When declaring custom process group, use it exclusively

--- ArchiSteamFarm/ASF.cs
+++ ArchiSteamFarm/ASF.cs
@@ -143,24 +143,20 @@

 			GlobalConfig = globalConfig;

-			StringBuilder networkGroupBuilder = new StringBuilder();
-
 			// The only purpose of using hashingAlgorithm below is to cut on a potential size of the resource name - paths can be really long, and we almost certainly have some upper limit on the resource name we can allocate
 			// At the same time it'd be the best if we avoided all special characters, such as '/' found e.g. in base64, as we can't be sure that it's not a prohibited character in regards to native OS implementation
 			// Because of that, MD5 is sufficient for our case, as it generates alphanumeric characters only, and is barely 128-bit long. We don't need any kind of complex cryptography or collision detection here, any hashing algorithm will do, and the shorter the better
+			string networkGroupText = "";
+
 			if (!string.IsNullOrEmpty(Program.NetworkGroup)) {
 				using MD5 hashingAlgorithm = MD5.Create();

-				networkGroupBuilder.Append("-" + BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(Program.NetworkGroup))).Replace("-", ""));
-			}
-
-			if (!string.IsNullOrEmpty(globalConfig.WebProxyText)) {
+				networkGroupText = "-" + BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(Program.NetworkGroup))).Replace("-", "");
+			} else if (!string.IsNullOrEmpty(globalConfig.WebProxyText)) {
 				using MD5 hashingAlgorithm = MD5.Create();

-				networkGroupBuilder.Append("-" + BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(globalConfig.WebProxyText))).Replace("-", ""));
-			}
-
-			string networkGroupText = networkGroupBuilder.ToString();
+				networkGroupText = "-" + BitConverter.ToString(hashingAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(globalConfig.WebProxyText))).Replace("-", "");
+			}

 			ConfirmationsSemaphore ??= OS.CreateCrossProcessSemaphore(nameof(ConfirmationsSemaphore) + networkGroupText);
 			GiftsSemaphore ??= OS.CreateCrossProcessSemaphore(nameof(GiftsSemaphore) + networkGroupText);


Remove obsolete commands

Remove obsolete commands

--- ArchiSteamFarm/Bot.cs
+++ ArchiSteamFarm/Bot.cs
@@ -546,12 +546,8 @@
 						return ResponseResume(steamID);
 					case "!RESTART":
 						return ResponseRestart(steamID);
-					case "!STARTALL":
-						return ResponseStartAll(steamID);
 					case "!STATUS":
 						return ResponseStatus(steamID);
-					case "!STATUSALL":
-						return ResponseStatusAll(steamID);
 					case "!STOP":
 						return ResponseStop(steamID);
 					case "!UPDATE":
@@ -2629,23 +2625,6 @@
 			return responses.Count > 0 ? string.Join("", responses) : null;
 		}

-		private static string ResponseStartAll(ulong steamID) {
-			if (steamID == 0) {
-				ASF.ArchiLogger.LogNullError(nameof(steamID));
-				return null;
-			}
-
-			if (!IsOwner(steamID)) {
-				return null;
-			}
-
-			foreach (Bot bot in Bots.Values.Where(bot => !bot.KeepRunning)) {
-				bot.ResponseStart(steamID);
-			}
-
-			return Environment.NewLine + Strings.Done;
-		}
-
 		private string ResponseStatus(ulong steamID) {
 			if (steamID == 0) {
 				ArchiLogger.LogNullError(nameof(steamID));
@@ -2713,22 +2692,6 @@

 			List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
 			return responses.Count > 0 ? string.Join("", responses) : null;
-		}
-
-		private static string ResponseStatusAll(ulong steamID) {
-			if (steamID == 0) {
-				ASF.ArchiLogger.LogNullError(nameof(steamID));
-				return null;
-			}
-
-			if (!IsOwner(steamID)) {
-				return null;
-			}
-
-			HashSet<Bot> botsRunning = new HashSet<Bot>(Bots.Where(bot => bot.Value.KeepRunning).OrderBy(bot => bot.Key).Select(bot => bot.Value));
-			IEnumerable<string> statuses = botsRunning.Select(bot => bot.ResponseStatus(steamID));
-
-			return string.Join("", statuses) + Environment.NewLine + string.Format(Strings.BotsStatusOverview, botsRunning.Count, Bots.Count, botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarm.Count), botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining)));
 		}

 		private string ResponseStop(ulong steamID) {


Enhance !statusall

Enhance !statusall

--- ArchiSteamFarm/Bot.cs
+++ ArchiSteamFarm/Bot.cs
@@ -852,18 +852,12 @@
 				return null;
 			}

-			StringBuilder result = new StringBuilder(Environment.NewLine);
-
-			byte runningBotsCount = 0;
-			foreach (Bot bot in Bots.OrderBy(bot => bot.Key).Select(bot => bot.Value)) {
-				result.Append(bot.ResponseStatus(steamID) + Environment.NewLine);
-				if (bot.KeepRunning) {
-					runningBotsCount++;
-				}
-			}
-
-			result.Append("There are " + runningBotsCount + "/" + Bots.Count + " bots running.");
-			return result.ToString();
+			HashSet<Bot> botsRunning = new HashSet<Bot>(Bots.Where(bot => bot.Value.KeepRunning).OrderBy(bot => bot.Key).Select(bot => bot.Value));
+			IEnumerable<string> statuses = botsRunning.Select(bot => bot.ResponseStatus(steamID));
+
+			return Environment.NewLine +
+				string.Join(Environment.NewLine, statuses) + Environment.NewLine +
+				"There are " + botsRunning.Count + "/" + Bots.Count + " bots running, with total of " + botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarm.Count) + " games (" + botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining)) + " cards) left to farm.";
 		}

 		private async Task<string> ResponseLoot(ulong steamID) {


文字化けのためエンコードの変更

文字化けのためエンコードの変更

--- ux/Component/Handle.cs
+++ ux/Component/Handle.cs
@@ -1,130 +1,130 @@
-/* ux - Micro Xylph / Software Synthesizer Core Library
+/* ux - Micro Xylph / Software Synthesizer Core Library
  * Copyright (C) 2013 Tomona Nanase. All rights reserved.
- */
-
-using System;
-
-namespace ux.Component
-{
-	/// <summary>
-	/// シンセサイザに対する命令をサポートします。
-	/// </summary>
-	public class Handle
-	{
-        #region Private Field
-        private readonly int targetPart;
-        private readonly HandleType type;
-        private readonly int data1;
-        private readonly float data2;
-        #endregion
-
-        #region Public Properties
-        /// <summary>
-		/// 対象となるパートを取得します。
-		/// </summary>
-        public int TargetPart { get { return this.targetPart; } }
-
-		/// <summary>
-		/// ハンドルのタイプを取得します。
-		/// </summary>
-        public HandleType Type { get { return this.type; } }
-
-        /// <summary>
-        /// ハンドルに対する整数パラメータを取得します。
-        /// </summary>
-        public int Data1 { get { return this.data1; } }
-
-        /// <summary>
-        /// ハンドルに対する実数パラメータを取得します。
-        /// </summary>
-        public float Data2 { get { return this.data2; } }
-		#endregion
-
-		#region Constructor
-		/// <summary>
-		/// パラメータを指定せずに新しい Handle クラスのインスタンスを初期化します。
-		/// </summary>
-        /// <param name="targetPart">ハンドルが適用されるパート。</param>
-		/// <param name="type">ハンドルの種類。</param>
-        public Handle(int targetPart, HandleType type)
-		{
-			this.targetPart = targetPart;
-			this.type = type;
-
-            this.data1 = 0;
-            this.data2 = 0.0f;
-		}
-
-        /// <summary>
-        /// パラメータを指定して新しい Handle クラスのインスタンスを初期化します。
-        /// </summary>
-        /// <param name="targetPart">ハンドルが適用されるパート。</param>
-        /// <param name="type">ハンドルの種類。</param>
-        /// <param name="data1">パラメータに対する整数パラメータ。</param>
-        public Handle(int targetPart, HandleType type, int data1)
-        {
-            this.targetPart = targetPart;
-            this.type = type;
-
-            this.data1 = data1;
-            this.data2 = 0.0f;
-        }
-
-        /// <summary>
-        /// パラメータを指定して新しい Handle クラスのインスタンスを初期化します。
-        /// </summary>
-        /// <param name="targetPart">ハンドルが適用されるパート。</param>
-        /// <param name="type">ハンドルの種類。</param>
-        /// <param name="data2">パラメータに対する実数パラメータ。</param>
-        public Handle(int targetPart, HandleType type, float data2)
-        {
-            this.targetPart = targetPart;
-            this.type = type;
-
-            this.data1 = 0;
-            this.data2 = data2;
-        }
-
-        /// <summary>
-        /// パラメータを指定して新しい Handle クラスのインスタンスを初期化します。
-        /// </summary>
-        /// <param name="targetPart">ハンドルが適用されるパート。</param>
-        /// <param name="type">ハンドルの種類。</param>
-        /// <param name="data1">パラメータに対する整数パラメータ。</param>
-        /// <param name="data2">パラメータに対する実数パラメータ。</param>
-        public Handle(int targetPart, HandleType type, int data1, float data2)
-        {
-            this.targetPart = targetPart;
-            this.type = type;
-
-            this.data1 = data1;
-            this.data2 = data2;
-        }
-
-        /// <summary>
-        /// ベースとなる Handle オブジェクトと新しいパートを指定して Handle クラスのインスタンスを初期化します。
-        /// </summary>
-        /// <param name="handle">ベースとなる Handle オブジェクト。</param>
-        /// <param name="newTargetPart">新しいパート。</param>
-        public Handle(Handle handle, int newTargetPart)
-        {
-            this.targetPart = newTargetPart;
-            this.type = handle.Type;
-
-            this.data1 = handle.data1;
-            this.data2 = handle.data2;
-        }
-		#endregion
-
-		#region Override Methods
-		/// <summary>
-		/// このクラスのインスタンスを表す文字列を取得します。
-		/// </summary>
-        /// <returns>このクラスのインスタンスを表す文字列。</returns>
-		public override string ToString()
-		{
-			return String.Format("{0} Part:{1}, Data1:{2}, Data2:{3:f2}", this.type, this.targetPart, this.data1, this.data2);
-		}
-		#endregion
-	}
-}
+ */
+
+using System;
+
+namespace ux.Component
+{
+    /// <summary>
+    /// シンセサイザに対する命令をサポートします。
+    /// </summary>
+    public class Handle
+    {
+        #region -- Private Fields --
+        private readonly int targetPart;
+        private readonly HandleType type;
+        private readonly int data1;
+        private readonly float data2;
+        #endregion
+
+        #region -- Public Properties --
+        /// <summary>
+        /// 対象となるパートを取得します。
+        /// </summary>
+        public int TargetPart { get { return this.targetPart; } }
+
+        /// <summary>
+        /// ハンドルのタイプを取得します。
+        /// </summary>
+        public HandleType Type { get { return this.type; } }
+
+        /// <summary>
+        /// ハンドルに対する整数パラメータを取得します。
+        /// </summary>
+        public int Data1 { get { return this.data1; } }
+
+        /// <summary>
+        /// ハンドルに対する実数パラメータを取得します。
+        /// </summary>
+        public float Data2 { get { return this.data2; } }
+        #endregion
+
+        #region -- Constructors --
+        /// <summary>
+        /// パラメータを指定せずに新しい Handle クラスのインスタンスを初期化します。
+        /// </summary>
+        /// <param name="targetPart">ハンドルが適用されるパート。</param>
+        /// <param name="type">ハンドルの種類。</param>
+        public Handle(int targetPart, HandleType type)
+        {
+            this.targetPart = targetPart;
+            this.type = type;
+
+            this.data1 = 0;
+            this.data2 = 0.0f;
+        }
+
+        /// <summary>
+        /// パラメータを指定して新しい Handle クラスのインスタンスを初期化します。
+        /// </summary>
+        /// <param name="targetPart">ハンドルが適用されるパート。</param>
+        /// <param name="type">ハンドルの種類。</param>
+        /// <param name="data1">パラメータに対する整数パラメータ。</param>
+        public Handle(int targetPart, HandleType type, int data1)
+        {
+            this.targetPart = targetPart;
+            this.type = type;
+
+            this.data1 = data1;
+            this.data2 = 0.0f;
+        }
+
+        /// <summary>
+        /// パラメータを指定して新しい Handle クラスのインスタンスを初期化します。
+        /// </summary>
+        /// <param name="targetPart">ハンドルが適用されるパート。</param>
+        /// <param name="type">ハンドルの種類。</param>
+        /// <param name="data2">パラメータに対する実数パラメータ。</param>
+        public Handle(int targetPart, HandleType type, float data2)
+        {
+            this.targetPart = targetPart;
+            this.type = type;
+
+            this.data1 = 0;
+            this.data2 = data2;
+        }
+
+        /// <summary>
+        /// パラメータを指定して新しい Handle クラスのインスタンスを初期化します。
+        /// </summary>
+        /// <param name="targetPart">ハンドルが適用されるパート。</param>
+        /// <param name="type">ハンドルの種類。</param>
+        /// <param name="data1">パラメータに対する整数パラメータ。</param>
+        /// <param name="data2">パラメータに対する実数パラメータ。</param>
+        public Handle(int targetPart, HandleType type, int data1, float data2)
+        {
+            this.targetPart = targetPart;
+            this.type = type;
+
+            this.data1 = data1;
+            this.data2 = data2;
+        }
+
+        /// <summary>
+        /// ベースとなる Handle オブジェクトと新しいパートを指定して Handle クラスのインスタンスを初期化します。
+        /// </summary>
+        /// <param name="handle">ベースとなる Handle オブジェクト。</param>
+        /// <param name="newTargetPart">新しいパート。</param>
+        public Handle(Handle handle, int newTargetPart)
+        {
+            this.targetPart = newTargetPart;
+            this.type = handle.Type;
+
+            this.data1 = handle.data1;
+            this.data2 = handle.data2;
+        }
+        #endregion
+
+        #region -- Public Methods --
+        /// <summary>
+        /// このクラスのインスタンスを表す文字列を取得します。
+        /// </summary>
+        /// <returns>このクラスのインスタンスを表す文字列。</returns>
+        public override string ToString()
+        {
+            return String.Format("{0} Part:{1}, Data1:{2}, Data2:{3:f2}", this.type, this.targetPart, this.data1, this.data2);
+        }
+        #endregion
+    }
+}


Add [NullAllowed] for some NSDictionary parameters in AVFoundation

--- src/avfoundation.cs
+++ src/avfoundation.cs
@@ -897,10 +897,10 @@
 		bool ExpectsMediaDataInRealTime { get; set;  }

 		[Static, Export ("assetWriterInputWithMediaType:outputSettings:")]
-		AVAssetWriterInput FromType (string mediaType, NSDictionary outputSettings);
+		AVAssetWriterInput FromType (string mediaType, [NullAllowed] NSDictionary outputSettings);

 		[Export ("initWithMediaType:outputSettings:")]
-		IntPtr Constructor (string mediaType, NSDictionary outputSettings);
+		IntPtr Constructor (string mediaType, [NullAllowed] NSDictionary outputSettings);

 		[Export ("requestMediaDataWhenReadyOnQueue:usingBlock:")]
 		void RequestMediaData (DispatchQueue queue, NSAction action);
@@ -930,10 +930,10 @@
 		//CVPixelBufferPoolRef pixelBufferPool { get;  }

 		[Static, Export ("assetWriterInputPixelBufferAdaptorWithAssetWriterInput:sourcePixelBufferAttributes:")]
-		AVAssetWriterInputPixelBufferAdaptor FromInput (AVAssetWriterInput input, NSDictionary sourcePixelBufferAttributes);
+		AVAssetWriterInputPixelBufferAdaptor FromInput (AVAssetWriterInput input, [NullAllowed] NSDictionary sourcePixelBufferAttributes);

 		[Export ("initWithAssetWriterInput:sourcePixelBufferAttributes:")]
-		IntPtr Constructor (AVAssetWriterInput input, NSDictionary sourcePixelBufferAttributes);
+		IntPtr Constructor (AVAssetWriterInput input, [NullAllowed] NSDictionary sourcePixelBufferAttributes);

 		[Export ("appendPixelBuffer:withPresentationTime:")]
 		bool AppendPixelBufferWithPresentationTime (CVPixelBuffer pixelBuffer, CMTime presentationTime);


Add .asf file extension to WMA support

Add .asf file extension to WMA support

--- ATL/AudioData/AudioDataIOFactory.cs
+++ ATL/AudioData/AudioDataIOFactory.cs
@@ -85,6 +85,7 @@

                 tempFmt = new Format("Windows Media Audio");
                 tempFmt.ID = ATL.AudioReaders.AudioReaderFactory.CID_WMA;
+                tempFmt.AddExtension(".asf");
                 tempFmt.AddExtension(".wma");
                 theFactory.addFormat(tempFmt);


a flag to propInst to prune methods matching file paths

--- AddOns/PropInst/PropInst/Program.cs
+++ AddOns/PropInst/PropInst/Program.cs
@@ -12,7 +12,6 @@
     internal class Driver
     {
         public HashSet<IToken> ProcsThatHaveBeenInstrumented = new HashSet<IToken>();
-

         //TODO: collect some stats about the instrumentation, mb some debugging output??

@@ -20,12 +19,18 @@
         {
             if (args.Length < 3)
             {
-                Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl");
+                Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl [options]");
+                Console.WriteLine("\t /pruneMethodsWithFilePathPrefix:<absolutePath> Prune implementations whose path has this prefix");
                 return;
             }

             if (args.Any(s => s == "/break"))
                 System.Diagnostics.Debugger.Launch();
+
+            var pruneFilePaths = new HashSet<string>();
+            args
+                .Where(s => s.StartsWith("/pruneMethodsWithFilePathPrefix:"))
+                .Iter(s => pruneFilePaths.Add(s.Substring("/pruneMethodsWithFilePathPrefix:".Length)));

             // initialize Boogie
             CommandLineOptions.Install(new CommandLineOptions());
@@ -60,10 +65,46 @@
             //augment the CorralExtraInit procedure (perform this after Matching/instrumentation)
             AugmentCorralExtraInit(boogieProgram);

+            //prune methods that match PruneFilePaths
+            PruneMethodsWithPaths(boogieProgram, pruneFilePaths);
+
             string outputFile = args[2];
             BoogieUtil.PrintProgram(boogieProgram, outputFile);

             Stats.printStats();
+        }
+
+        private static void PruneMethodsWithPaths(Program boogieProgram, HashSet<string> pruneFilePaths)
+        {
+            var pruneImplCandidates =
+                boogieProgram
+                .Implementations
+                .Where(x => IntersectsFilePath(x, pruneFilePaths));
+            Console.WriteLine($"Pruning methods {string.Join("\t", pruneImplCandidates.Select(x => x.Name))}");
+            boogieProgram.RemoveTopLevelDeclarations(x => x is Implementation && pruneImplCandidates.Contains(x));
+            Console.WriteLine($"Pruning complete...");
+        }
+
+        private static bool IntersectsFilePath(Implementation impl, HashSet<string> pruneFilePaths)
+        {
+            string sourceFile = null;
+            foreach (var blk in impl.Blocks)
+            {
+                foreach (var cmd in blk.Cmds.OfType<AssertCmd>())
+                {
+                    var file = QKeyValue.FindStringAttribute(cmd.Attributes, "sourcefile");
+                    if (file == null) continue;
+                    if (file.Equals("?")) continue;
+                    sourceFile = file;
+                    break;
+                }
+            }
+            return sourceFile != null && pruneFilePaths.Any(x => sourceFile.StartsWith(x));
+        }
+
+        private static string PossibleFilePath(Implementation x)
+        {
+            throw new NotImplementedException();
         }

         private static void AugmentCorralExtraInit(Program boogieProgram)


Amend variable name 'donchianChannel' on QCAlgorithmn.Indicator

Amend variable name on 'donchianChannel'  on QCAlgorithmn.Indicator

--- Algorithm/QCAlgorithm.Indicators.cs
+++ Algorithm/QCAlgorithm.Indicators.cs
@@ -451,9 +451,9 @@
         public DonchianChannel DCH(string symbol, int period, Resolution? resolution = null, Func<BaseData, TradeBar> selector = null)
         {
             var name = CreateIndicatorName(symbol, "DCH", resolution);
-            var dnchianChannel = new DonchianChannel(name, period);
-            RegisterIndicator(symbol, dnchianChannel, resolution, selector);
-            return dnchianChannel;
+            var donchianChannel = new DonchianChannel(name, period);
+            RegisterIndicator(symbol, donchianChannel, resolution, selector);
+            return donchianChannel;
         }

         /// <summary>


Refactored UnityBinaryReader.

Refactored UnityBinaryReader.

--- Assets/Scripts/UnityBinaryReader.cs
+++ Assets/Scripts/UnityBinaryReader.cs
@@ -8,13 +8,7 @@
 /// <remarks>Not thread safe.</remarks>
 public class UnityBinaryReader : IDisposable
 {
-	public Stream BaseStream
-	{
-		get
-		{
-			return reader.BaseStream;
-		}
-	}
+	public Stream BaseStream { get { return reader.BaseStream; } }

 	public UnityBinaryReader(Stream input)
 	{
@@ -64,13 +58,15 @@
 	{
 		var remainingByteCount = reader.BaseStream.Length - reader.BaseStream.Position;

+		Debug.Assert(remainingByteCount <= int.MaxValue);
+
 		return reader.ReadBytes((int)remainingByteCount);
 	}
 	public void ReadRestOfBytes(byte[] buffer, int startIndex)
 	{
 		var remainingByteCount = reader.BaseStream.Length - reader.BaseStream.Position;

-		Debug.Assert((startIndex >= 0) && ((startIndex + remainingByteCount) <= buffer.Length));
+		Debug.Assert((startIndex >= 0) && (remainingByteCount <= int.MaxValue) && ((startIndex + remainingByteCount) <= buffer.Length));

 		reader.Read(buffer, startIndex, (int)remainingByteCount);
 	}
@@ -153,6 +149,15 @@
 		unsafe
 		{
 			return *((float*)(&singleAsUInt));
+		}
+	}
+	public double ReadLEDouble()
+	{
+		var doubleAsUInt = ReadLEUInt64();
+
+		unsafe
+		{
+			return *((double*)(&doubleAsUInt));
 		}
 	}


Logo Show movPlayer & switch scene

Logo Show movPlayer & switch scene

--- Assets/Scenes/Logo/Scripts/logomov.cs
+++ Assets/Scenes/Logo/Scripts/logomov.cs
@@ -4,12 +4,13 @@
 public class logomov : MonoBehaviour {

 	public MovieTexture movTexture;
+
 	// Use this for initialization
 	void Start () {
 		movTexture = Resources.Load ("logo") as MovieTexture;
 		GetComponent<Renderer> ().material.mainTexture = movTexture;
-
-		movTexture.loop = true;
+
+		movTexture.loop = false;
 		if (!movTexture.isPlaying) {
 			movTexture.Play ();
 		}
@@ -17,6 +18,8 @@

 	// Update is called once per frame
 	void Update () {
-
+		if (!movTexture.isPlaying) {
+			Application.LoadLevel ("SelectMusic");
+		}
 	}
 }


Epilogue small fix

Epilogue small fix

--- Assets/Scripts/Audio/AudioEpilogue.cs
+++ Assets/Scripts/Audio/AudioEpilogue.cs
@@ -31,7 +31,7 @@

     void EpilogueStart()
     {
-        if (LevelManager.instance.Level >= LevelManager.instance.LevelCount - 2)
+        if (DialogueManager.ActiveInstance == DialogueManager.instance.defaultMap["Epilogue"])
         {
             epilogue.timeSamples = GetComponent<AudioRunning>().SampleOffset();
             epilogue.Play();


adding initial spawn

adding initial spawn

--- Assets/Scripts/Game/GameController.cs
+++ Assets/Scripts/Game/GameController.cs
@@ -46,6 +46,8 @@
     [SerializeField]
     private AnimationCurve _spawnCurve;
     [SerializeField]
+    private float _initialSpawn;
+    [SerializeField]
     private float _spawnInterval;
     [SerializeField]
     private int _minBacteria;
@@ -94,6 +96,18 @@
         _startScreen.gameObject.SetActive(true);
     }

+    private void SpawnInitial()
+    {
+        var enemies = new List<Bacteria>();
+        for(int i = 0; i < _initialSpawn; i++)
+        {
+            Vector2 pos;
+            if (_strategy.GetSpawnPosition(enemies.ToArray(), _player, out pos))
+            {
+                enemies.Add(Spawn.SpawnBacteria(pos));
+            }
+        }
+    }
     private void StartGame()
     {
         Lives = _startLives;
@@ -112,6 +126,7 @@
         {
             Destroy(enemy.gameObject);
         }
+        SpawnInitial();
         InvokeRepeating("CheckBacteria", 1.0f, 1.0f);

         Score = 0;


Make getCursorPosition work with perspective camera

--- Assets/Scripts/Helper/CameraHelper.cs
+++ Assets/Scripts/Helper/CameraHelper.cs
@@ -89,20 +89,31 @@
 	/// <returns></returns>
 	public static Vector3 getCursorPosition(float z)
 	{
-		camSize = Camera.main.orthographicSize;
+		if (Camera.main.orthographic)
+		{
+			camSize = Camera.main.orthographicSize;

-		Vector3 position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
-		//if (isPointOffscreen(position))
-		//	return lastCursorPosition;
+			Vector3 position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
+			//if (isPointOffscreen(position))
+			//	return lastCursorPosition;

-		position.x = Mathf.Clamp(position.x, Camera.main.transform.position.x - (camSize * 4f / 3f),
-			Camera.main.transform.position.x + (camSize * 4f / 3f));
-		position.y = Mathf.Clamp(position.y, Camera.main.transform.position.y - camSize,
-			Camera.main.transform.position.y + camSize);
-		position.z = z;
+			position.x = Mathf.Clamp(position.x, Camera.main.transform.position.x - (camSize * 4f / 3f),
+				Camera.main.transform.position.x + (camSize * 4f / 3f));
+			position.y = Mathf.Clamp(position.y, Camera.main.transform.position.y - camSize,
+				Camera.main.transform.position.y + camSize);
+			position.z = z;

-		lastCursorPosition = position;
-		return position;
+			lastCursorPosition = position;
+			return position;
+		}
+		else
+		{
+			Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
+			Plane xy = new Plane(Vector3.forward, new Vector3(0, 0, z));
+			float distance;
+			xy.Raycast(mouseRay, out distance);
+			return mouseRay.GetPoint(distance);
+		}
 	}

 	/// <summary>


hack to show buttons in proper place

hack to show buttons in proper place

--- Assets/lab/Editor/Window/LabWindow.cs
+++ Assets/lab/Editor/Window/LabWindow.cs
@@ -35,6 +35,21 @@
 			return;
 		}
         _statusBar.DrawStatusBar();
+        //a bit dirty hack of drawing buttons in param panel without making dependencies. Well, editor gui...
+        EditorGUILayout.BeginHorizontal();
+        if (_target != null && GUILayout.Button(new GUIContent((Texture2D)EditorGUIUtility.Load("Assets/lab/Icons/32x32/debug.png"), "run debug info"), "CommandLeft")) {
+            _treeDrawer.RunDebug();
+        }
+        if (_target != null && GUILayout.Button(new GUIContent((Texture2D)EditorGUIUtility.Load("Assets/lab/Icons/32x32/reset.png"), "reset debug info"), "CommandMid")) {
+            _treeDrawer.ResetDebug();
+        }
+        if (_target != null && GUILayout.Button(new GUIContent((Texture2D)EditorGUIUtility.Load("Assets/lab/Icons/32x32/center.png"), "center view on root"), "CommandRight")) {
+            var pos = -_statusBar.CurrentTree.Root.Position + (new Vector2(position.width - _currentViewWidth, position.height - EditorStyles.toolbar.fixedHeight) - NodeDrawer.gSize) / 2;
+            pos.x = Mathf.Floor(pos.x);
+            pos.y = Mathf.Floor(pos.y);
+            _treeDrawer.OffsetNodes(pos);
+        }
+        EditorGUILayout.EndHorizontal();
         ResizeSplitPanel();
         _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, GUILayout.Width(_currentViewWidth), GUILayout.Height(position.height));
         _paramPanel.DrawPanel();
@@ -46,18 +61,6 @@
             _treeDrawer.DrawTree();
         }
         EndWindows();
-		if(_target != null && GUI.Button(new Rect(position.width - _currentViewWidth - 55f, position.height - EditorStyles.toolbar.fixedHeight - 55f, 50f, 50f), "C")) {
-            var pos = -_statusBar.CurrentTree.Root.Position + (new Vector2(position.width - _currentViewWidth, position.height - EditorStyles.toolbar.fixedHeight) - NodeDrawer.gSize) / 2;
-            pos.x = Mathf.Floor(pos.x);
-            pos.y = Mathf.Floor(pos.y);
-			_treeDrawer.OffsetNodes(pos);
-		}
-		if (_target != null && GUI.Button(new Rect(position.width - _currentViewWidth - 110f, position.height - EditorStyles.toolbar.fixedHeight - 55f, 50f, 50f), "R")) {
-			_treeDrawer.ResetDebug();
-		}
-		if (_target != null && GUI.Button(new Rect(position.width - _currentViewWidth - 165f, position.height - EditorStyles.toolbar.fixedHeight - 55f, 50f, 50f), "D")) {
-			_treeDrawer.RunDebug();
-		}
         GUI.EndGroup();
         InputHandler();
     }


idx on filter async

idx on filter async

--- reactor/async/Async.cs
+++ reactor/async/Async.cs
@@ -268,6 +268,8 @@
                 {
                     list.Add(item);
                 }
+
+                idx += 1;
             }

             return list;


Make user readonly.

Make user readonly.

--- AerospikeClient/Cluster/Cluster.cs
+++ AerospikeClient/Cluster/Cluster.cs
@@ -40,7 +40,7 @@
 		protected internal readonly Dictionary<string, string> ipMap;

 		// User name in UTF-8 encoded bytes.
-		protected internal byte[] user;
+		protected internal readonly byte[] user;

 		// Password in hashed format in bytes.
 		protected internal byte[] password;


delete file

delete file


Reorder methods around load()

Reorder methods around load()

--- osu.Game/OsuGameBase.cs
+++ osu.Game/OsuGameBase.cs
@@ -160,47 +160,6 @@
             Name = @"osu!lazer";
         }

-        public override void SetHost(GameHost host)
-        {
-            base.SetHost(host);
-
-            // may be non-null for certain tests
-            Storage ??= host.Storage;
-
-            LocalConfig ??= UseDevelopmentServer
-                ? new DevelopmentOsuConfigManager(Storage)
-                : new OsuConfigManager(Storage);
-        }
-
-        /// <summary>
-        /// Use to programatically exit the game as if the user was triggering via alt-f4.
-        /// Will keep persisting until an exit occurs (exit may be blocked multiple times).
-        /// </summary>
-        public void GracefullyExit()
-        {
-            if (!OnExiting())
-                Exit();
-            else
-                Scheduler.AddDelayed(GracefullyExit, 2000);
-        }
-
-        public void Migrate(string path)
-        {
-            contextFactory.FlushConnections();
-            (Storage as OsuStorage)?.Migrate(Host.GetStorage(path));
-        }
-
-        protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
-
-        protected virtual BatteryInfo CreateBatteryInfo() => null;
-
-        protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer();
-
-        protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
-            dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
-
-        protected override Storage CreateStorage(GameHost host, Storage defaultStorage) => new OsuStorage(host, defaultStorage);
-
         [BackgroundDependencyLoader]
         private void load()
         {
@@ -390,6 +349,47 @@
             FrameStatistics.ValueChanged += e => fpsDisplayVisible.Value = e.NewValue != FrameStatisticsMode.None;
         }

+        protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
+            dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
+
+        public override void SetHost(GameHost host)
+        {
+            base.SetHost(host);
+
+            // may be non-null for certain tests
+            Storage ??= host.Storage;
+
+            LocalConfig ??= UseDevelopmentServer
+                ? new DevelopmentOsuConfigManager(Storage)
+                : new OsuConfigManager(Storage);
+        }
+
+        /// <summary>
+        /// Use to programatically exit the game as if the user was triggering via alt-f4.
+        /// Will keep persisting until an exit occurs (exit may be blocked multiple times).
+        /// </summary>
+        public void GracefullyExit()
+        {
+            if (!OnExiting())
+                Exit();
+            else
+                Scheduler.AddDelayed(GracefullyExit, 2000);
+        }
+
+        public void Migrate(string path)
+        {
+            contextFactory.FlushConnections();
+            (Storage as OsuStorage)?.Migrate(Host.GetStorage(path));
+        }
+
+        protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
+
+        protected virtual BatteryInfo CreateBatteryInfo() => null;
+
+        protected virtual Container CreateScalingContainer() => new DrawSizePreservingFillContainer();
+
+        protected override Storage CreateStorage(GameHost host, Storage defaultStorage) => new OsuStorage(host, defaultStorage);
+
         private void onRulesetChanged(ValueChangedEvent<RulesetInfo> r)
         {
             var dict = new Dictionary<ModType, IReadOnlyList<Mod>>();


Add tests for PascalCaseToSpacedString extensions

--- test/Entelect.Tests/Strings/StringExtensionsTests.cs
+++ test/Entelect.Tests/Strings/StringExtensionsTests.cs
@@ -12,6 +12,7 @@
             var doesContain = "asd".Contains("S",StringComparison.OrdinalIgnoreCase);
             Assert.True(doesContain);
         }
+
         [Test]
         public void ListContainsIgnoringCase()
         {
@@ -19,5 +20,23 @@
             var doesContain = list.Contains("ASD", StringComparison.OrdinalIgnoreCase);
             Assert.True(doesContain);
         }
+
+        [Test]
+        public void PascalCaseToSpacedString()
+        {
+            const string input = "SomePascalCasedString";
+            const string expectedOutput = "Some Pascal Cased String";
+            var actualOutput = input.PascalToSpacedString();
+            Assert.AreEqual(expectedOutput, actualOutput);
+        }
+
+        [Test]
+        public void PascalCaseToSpacedStringArray()
+        {
+            const string input = "SomePascalCasedString";
+            var expectedOutput = new []{"Some", "Pascal", "Cased","String"};
+            var actualOutput = input.PascalToSpacedStringArray();
+            Assert.That(expectedOutput, Is.EquivalentTo(actualOutput));
+        }
     }
 }


Increase test timeout.

Increase test timeout.

--- test/Rocket.Chat.Net.Tests/Bot/RocketChatBotFacts.cs
+++ test/Rocket.Chat.Net.Tests/Bot/RocketChatBotFacts.cs
@@ -287,7 +287,7 @@

             // Act
             _driverMock.MessageReceived += Raise.Event<MessageReceived>(rocketMessage);
-            Thread.Sleep(10);
+            Thread.Sleep(20);

             // Assert
             responseMock1.Received().Response(rocketMessage, bot);


added side properties to AARectangle

added side properties to AARectangle

--- Archimedes.Geometry/AARectangle.cs
+++ Archimedes.Geometry/AARectangle.cs
@@ -169,6 +169,40 @@
             }
         }

+        public double Left
+        {
+            get
+            {
+                return X;
+            }
+        }
+
+        public double Top
+        {
+            get
+            {
+                return Y;
+            }
+        }
+
+
+        public double Right
+        {
+            get
+            {
+                return X + Width;
+            }
+        }
+
+
+        public double Bottom
+        {
+            get
+            {
+                return Y + Height;
+            }
+        }
+
         #endregion

         #region Public Methods


Added a version number menu item

Added a version number menu item

--- Assets/NuGet/Editor/NugetWindow.cs
+++ Assets/NuGet/Editor/NugetWindow.cs
@@ -103,6 +103,14 @@
         protected static void ReloadNugetConfigFile()
         {
             NugetHelper.LoadNugetConfigFile();
+        }
+
+        /// <summary>
+        /// Displays the version number of NuGetForUnity.
+        /// </summary>
+        [MenuItem("NuGet/Version 0.0.2")]
+        protected static void DisplayVersion()
+        {
         }

         /// <summary>


Now player moves left and right on the map

--- Assets/Scripts/PlayerController.cs
+++ Assets/Scripts/PlayerController.cs
@@ -4,13 +4,25 @@

 public class PlayerController : MonoBehaviour {

-	// Use this for initialization
-	void Start () {
-
-	}
-
-	// Update is called once per frame
-	void Update () {
-
+	public float speed = 10.0f;
+
+	void Update() {
+
+		// ======== move player position ========
+		if (Input.mousePosition.x < 2.0f) {
+			transform.position -= new Vector3 (speed * Time.deltaTime, 0, 0);
+		}
+
+		if (Input.mousePosition.x > Screen.width - 2.0f) {
+			transform.position += new Vector3 (speed * Time.deltaTime, 0, 0);
+		}
+
+		if (Input.mousePosition.y > Screen.height - 2.0f) {
+			transform.position += new Vector3 (0, 0, speed * Time.deltaTime);
+		}
+
+		if (Input.mousePosition.y < 2.0f) {
+			transform.position -= new Vector3 (0, 0, speed * Time.deltaTime);
+		}
 	}
 }


Draw a line indicating the strike direction to make things easier while we dont have a cue stick

--- Assets/Scripts/PlayerController.cs
+++ Assets/Scripts/PlayerController.cs
@@ -37,6 +37,7 @@
 				cameraRotation = mainCamera.transform.rotation;
 				cameraOffset = cueBall.transform.position - mainCamera.transform.position;
 			}
+			Debug.DrawLine(cueBall.transform.position, cueBall.transform.position+strikeDirection*4);
 		}
 	}


Fix player's z-order

Fix player's z-order

--- Assets/Scripts/PlayerController.cs
+++ Assets/Scripts/PlayerController.cs
@@ -89,6 +89,6 @@
         animationTime = clip.normalizedTime;
         transform.position = Vector2.Lerp(previousPosition, nextPosition, animationTime);

-        GetComponent<SpriteRenderer>().sortingOrder = (int) -transform.position.y;
+        GetComponent<SpriteRenderer>().sortingOrder = (int) -transform.position.y - 1;
     }
 }


Deletes tiles when in them

Deletes tiles when in them

--- Assets/Scripts/QQLevelGenerator.cs
+++ Assets/Scripts/QQLevelGenerator.cs
@@ -9,6 +9,7 @@
 	private Texture2D textureMap;
 	private int mapWidth, mapHeight;
 	private List<QQTile> tileInstances;
+    private int deleteCounter = 0;

 	public int MapHeight
 	{
@@ -47,7 +48,10 @@
                 tilesArray[(int)positionInGrid.x, (int)positionInGrid.y] = TileType.Empty;
                 if (inBlock)
                 {
-                    //destroy gameobject
+                    int index = ((int)positionInGrid.x * mapHeight) + (deleteCounter % mapHeight) + (int)positionInGrid.y;
+                    QQTile tileToDelete = tileInstances[index];
+                    if (tileToDelete != null)
+                        GameObject.Destroy(tileToDelete.gameObject);
                 }
                 break;
             case TileType.Death:
@@ -58,6 +62,11 @@
                 {
                     QQGameManager.Instance.CollectiblePickedUp();
                     tilesArray[(int)positionInGrid.x, (int)positionInGrid.y] = TileType.Empty;
+
+                    int index = ((int)positionInGrid.x * mapHeight) + (deleteCounter % mapHeight) + (int)positionInGrid.y;
+                    QQTile tileToDelete = tileInstances[index];
+                    if (tileToDelete != null)
+                        GameObject.Destroy(tileToDelete.gameObject);
                 }
                 break;
             case TileType.Spawn:
@@ -120,6 +129,7 @@
 			tiles[i] = tileInstances[i];

 		tileInstances.RemoveRange(removalStartIdx, mapHeight);
+        deleteCounter += mapHeight;

 		for (int i = 0; i < tiles.Length; i++)
 		{


Monster images on board in MoM and borders on placement images in d2e.

--- Assets/Scripts/Quest/TokenBoard.cs
+++ Assets/Scripts/Quest/TokenBoard.cs
@@ -74,8 +74,13 @@
             if (h.heroData != null) count++;
         }

+        if (game.gameType is MoMGameType)
+        {
+            Texture2D newTex = ContentData.FileToTexture(me.cMonster.image);
+            AddPlacedMonsterImg("", newTex, 1, 1, me.qEvent.location.x, me.qEvent.location.y);
+        }
         // Check for a placement list at this hero count
-        if (me.qMonster.placement[count].Length == 0)
+        else if (me.qMonster.placement[count].Length == 0)
         {
             // group placement
             AddAreaMonster(me.qMonster);
@@ -125,45 +130,84 @@
     }

     // Add a placement image
-    public void AddPlacedMonsterImg(string place, Texture2D newTex, int x, int y)
-    {
-        Game game = Game.Get();
-        Sprite tileSprite;
+    public void AddPlacedMonsterImg(string place, Texture2D newTex, int sizeX, int sizeY, float posX = 0, float posY = 0)
+    {
+        Game game = Game.Get();
+        Sprite iconSprite;
+        Sprite borderSprite;

         // Check that placement name exists
-        if (!game.quest.qd.components.ContainsKey(place))
+        if (!game.quest.qd.components.ContainsKey(place) && place.Length > 0)
         {
             ValkyrieDebug.Log("Error: Invalid moster place: " + place);
             Application.Quit();
         }

-        QuestData.MPlace mp = game.quest.qd.components[place] as QuestData.MPlace;
-
         // Create object
+        GameObject circleObject = new GameObject("MonsterSpawnBorder" + place);
         GameObject gameObject = new GameObject("MonsterSpawn" + place);
+        GameObject borderObject = new GameObject("MonsterSpawnBorder" + place);
         gameObject.tag = "dialog";
-
+        borderObject.tag = "dialog";
+        circleObject.tag = "dialog";
+        circleObject.transform.parent = game.tokenCanvas.transform;
         gameObject.transform.parent = game.tokenCanvas.transform;
+        borderObject.transform.parent = game.tokenCanvas.transform;

         // Create the image
         UnityEngine.UI.Image image = gameObject.AddComponent<UnityEngine.UI.Image>();
-        tileSprite = Sprite.Create(newTex, new Rect(0, 0, newTex.width, newTex.height), Vector2.zero, 1);
-        if (mp.master)
-        {
-            image.color = Color.red;
-        }
-        image.sprite = tileSprite;
-        image.rectTransform.sizeDelta = new Vector2(x, y);
-        // Move to get the top left square corner at 0,0
-        gameObject.transform.Translate(Vector3.right * (float)(x - 1) / 2f, Space.World);
-        gameObject.transform.Translate(Vector3.down * (float)(y - 1) / 2f, Space.World);
-
-        if (mp.rotate)
-        {
-            gameObject.transform.RotateAround(Vector3.zero, Vector3.forward, -90);
+        iconSprite = Sprite.Create(newTex, new Rect(0, 0, newTex.width, newTex.height), Vector2.zero, 1);
+        image.sprite = iconSprite;
+        image.rectTransform.sizeDelta = new Vector2(sizeX, sizeY);
+
+        if (place.Length > 0)
+        {
+            QuestData.MPlace mp = game.quest.qd.components[place] as QuestData.MPlace;
+            posX = mp.location.x;
+            posY = mp.location.y;
+
+            // Move to get the top left square corner at 0,0
+            gameObject.transform.Translate(Vector3.right * (float)(sizeX - 1) / 2f, Space.World);
+            gameObject.transform.Translate(Vector3.down * (float)(sizeY - 1) / 2f, Space.World);
+            borderObject.transform.Translate(Vector3.right * (float)(sizeX - 1) / 2f, Space.World);
+            borderObject.transform.Translate(Vector3.down * (float)(sizeY - 1) / 2f, Space.World);
+            circleObject.transform.Translate(Vector3.right * (float)(sizeX - 1) / 2f, Space.World);
+            circleObject.transform.Translate(Vector3.down * (float)(sizeY - 1) / 2f, Space.World);
+
+            image.rectTransform.sizeDelta = new Vector2(sizeX * 0.83f, sizeY * 0.83f);
+
+            borderObject.AddComponent<CanvasRenderer>();
+            borderObject.AddComponent<RectTransform>();
+
+            UnityEngine.UI.Image iconFrame = borderObject.AddComponent<UnityEngine.UI.Image>();
+            Texture2D frameTex = Resources.Load("sprites/borders/Frame_Monster_1x1") as Texture2D;
+            iconFrame.sprite = Sprite.Create(frameTex, new Rect(0, 0, frameTex.width, frameTex.height), Vector2.zero, 1);
+            iconFrame.rectTransform.sizeDelta = new Vector2(sizeX, sizeY);
+
+            circleObject.AddComponent<CanvasRenderer>();
+            circleObject.AddComponent<RectTransform>();
+
+            UnityEngine.UI.Image iconCicle = circleObject.AddComponent<UnityEngine.UI.Image>();
+            Texture2D circleTex = Resources.Load("sprites/target") as Texture2D;
+            iconCicle.sprite = Sprite.Create(circleTex, new Rect(0, 0, circleTex.width, circleTex.height), Vector2.zero, 1);
+            iconCicle.rectTransform.sizeDelta = new Vector2(sizeX * 1.08f, sizeY * 1.08f);
+
+            if (mp.master)
+            {
+                iconCicle.color = Color.red;
+            }
+
+            if (mp.rotate)
+            {
+                gameObject.transform.RotateAround(Vector3.zero, Vector3.forward, -90);
+                iconFrame.transform.RotateAround(Vector3.zero, Vector3.forward, -90);
+                iconCicle.transform.RotateAround(Vector3.zero, Vector3.forward, -90);
+            }
         }
         // Move to square
-        gameObject.transform.Translate(new Vector3(mp.location.x, mp.location.y, 0), Space.World);
+        gameObject.transform.Translate(new Vector3(posX, posY, 0), Space.World);
+        borderObject.transform.Translate(new Vector3(posX, posY, 0), Space.World);
+        circleObject.transform.Translate(new Vector3(posX, posY, 0), Space.World);
     }


Added health counter.

Added health counter.

--- Assets/Scripts/States/StateGame.cs
+++ Assets/Scripts/States/StateGame.cs
@@ -5,7 +5,8 @@
 public class StateGame : ExaState {
 	public StateGame(): base(GAME) {
 		//Initialize
-		m_Coin = 9;
+		m_Coin 		= 9;
+		m_Health	= 3;

 		//Create background
 		FSprite Background = new FSprite("rect") {
@@ -28,7 +29,6 @@
 		//Create components
 		m_Exa 		= new Exa();
 		m_Coins		= new FContainer();
-
 		AddChild(m_Coins);
 		AddChild(m_Exa);

@@ -40,14 +40,19 @@
 		m_CurrentCoinTime = m_SpawnCoinTime;

 		//Create interface
-		m_CoinCounter = new FLabel("font", "");
+		m_Coin--;
+		m_Health++;
+		m_CoinCounter 	= new FLabel("font", "");
+		m_HealthCounter = new FLabel("font", "");
+		AddChild(m_HealthCounter);
 		AddChild(m_CoinCounter);
+		decrementHealth();
 		incrementCoin();
 	}

 	public override void onUpdate(FTouch[] touches) {
 		//Update
-		m_Exa.update(Platforms);
+		m_Exa.update();
 		processCoins(m_Exa.getOffset());

 		//Check input
@@ -62,6 +67,16 @@
 		m_CoinCounter.text 	= m_Coin + " Coins";
 		m_CoinCounter.x 	= Futile.screen.width - 12 - (m_CoinCounter.textRect.width * 0.5f);
 		m_CoinCounter.y 	= Futile.screen.height - 12 - (m_CoinCounter.textRect.height * 0.5f);
+	}
+
+	public void decrementHealth() {
+		//Decrease
+		m_Health--;
+
+		//Refresh
+		m_HealthCounter.text 	= "Error: " + (3 - m_Health);
+		m_HealthCounter.x 		= 12 + (m_HealthCounter.textRect.width * 0.5f);
+		m_HealthCounter.y 		= 4 + (m_HealthCounter.textRect.height * 0.5f);
 	}

 	protected void processCoins(float offset) {
@@ -125,9 +140,10 @@
 	}

 	//Data
+	protected int 	m_Coin;
+	protected int 	m_Health;
 	protected float m_SpawnCoinTime;
 	protected float m_CurrentCoinTime;
-	protected int m_Coin;

 	//Components
 	protected Exa			m_Exa;
@@ -135,4 +151,5 @@

 	//Interface
 	protected FLabel m_CoinCounter;
+	protected FLabel m_HealthCounter;
 }


* Added min confidence for sending a NLC classify event.

--- Assets/Watson/Widgets/NlcWidget.cs
+++ Assets/Watson/Widgets/NlcWidget.cs
@@ -47,6 +47,8 @@
         private double m_MinWordConfidence = 0.4;
         [SerializeField, Tooltip("Recognized speech below this confidence is just ignored.")]
         private double m_IgnoreWordConfidence = 0.2;
+        [SerializeField, Tooltip("What is the minimum confidence for a classification event to be fired.")]
+        private double m_MinClassEventConfidence = 0.5;

         [Serializable]
         private class ClassEventMapping
@@ -119,7 +121,8 @@
                 if ( m_TopClassText != null )
                     m_TopClassText.text = result.top_class;

-                if ( !string.IsNullOrEmpty( result.top_class) )
+                if ( !string.IsNullOrEmpty( result.top_class)
+                        && result.topConfidence >= m_MinClassEventConfidence )
                 {
                     if ( m_ClassEventList.Count > 0 && m_ClassEventMap.Count == 0 )
                     {


fixed typo in comment

fixed typo in comment

--- BBR-ChargebackModel-CLI/Program.cs
+++ BBR-ChargebackModel-CLI/Program.cs
@@ -30,7 +30,7 @@
         {
             var opts = GetCLIOptions(args);

-            // If we need to re-migrate, rever the db to its original state
+            // If we need to re-migrate, revert the db to its original state
             if (opts.Revert)
             {
                 migrator.DbMigrator.MigrateToEmptyDb(opts.DbType, opts.ConnectionString);


Added failing test for #2912.

Added failing test for #2912.

--- tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs
+++ tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs
@@ -194,6 +194,29 @@
             Assert.Equal("baz", source.Foo);
             source.Foo = "quz";
             Assert.Equal("baz", target.Text);
+        }
+
+        [Fact]
+        public void OneWayToSource_Binding_Should_Not_StackOverflow_With_Null_Value()
+        {
+            var target = new TextBlock { Text = null };
+            var binding = new Binding
+            {
+                Path = "Foo",
+                Mode = BindingMode.OneWayToSource,
+            };
+
+            target.Bind(TextBox.TextProperty, binding);
+
+            var source = new Source { Foo = "foo" };
+            target.DataContext = source;
+
+            Assert.Null(source.Foo);
+
+            // When running tests under NCrunch, NCrunch replaces the standard StackOverflowException
+            // with its own, which will be caught by our code. Detect the stackoverflow anyway, by
+            // making sure the target property was only set once.
+            Assert.Equal(1, source.FooSetCount);
         }

         [Fact]
@@ -630,9 +653,12 @@
                 set
                 {
                     _foo = value;
+                    ++FooSetCount;
                     RaisePropertyChanged();
                 }
             }
+
+            public int FooSetCount { get; private set; }

             public event PropertyChangedEventHandler PropertyChanged;


Fixed a typo in documentation

Fixed a typo in documentation

--- Ceen.Httpd/BufferedStreamReader.cs
+++ Ceen.Httpd/BufferedStreamReader.cs
@@ -10,7 +10,7 @@
 	/// Helper class that reads a stream,
 	/// but also provides a buffer to allow peek/read-ahead
 	/// It contains a special method to read data until the first
-	/// CR LF CR LF entry (end o HTTP header), and leaves the rest of
+	/// CR LF CR LF entry (end of HTTP header), and leaves the rest of
 	/// the stream untouched.
 	/// </summary>
 	public class BufferedStreamReader : Stream


Fix file paths in debug info

Fix file paths in debug info

--- StoryCompiler/ModCompiler.cs
+++ StoryCompiler/ModCompiler.cs
@@ -163,10 +163,22 @@
                 {
                     using (var reader = new BinaryReader(scriptStream))
                     {
+                        string path;
+                        if (file.Value is PackagedFileInfo)
+                        {
+                            var pkgd = file.Value as PackagedFileInfo;
+                            path = (pkgd.PackageStream as FileStream).Name + ":/" + pkgd.Name;
+                        }
+                        else
+                        {
+                            var fs = file.Value as FilesystemFileInfo;
+                            path = fs.FilesystemPath;
+                        }
+
                         var script = new GoalScript
                         {
                             Name = Path.GetFileNameWithoutExtension(file.Value.Name),
-                            Path = file.Key,
+                            Path = path,
                             ScriptBody = reader.ReadBytes((int)scriptStream.Length)
                         };
                         GoalScripts.Add(script);


Fixed issue when connecting with pscp to transfer files where password request was not being recognized (it appears the format has changed from prior versions of pscp).

--- SuperPutty/Scp/PscpClient.cs
+++ SuperPutty/Scp/PscpClient.cs
@@ -330,7 +330,7 @@
                         {
                             bool keepReading = true;
                             bool completed = false;
-                            if (strOut == PUTTY_INTERACTIVE_AUTH || strOut.Contains("'s password:"))
+                            if (strOut == PUTTY_INTERACTIVE_AUTH || strOut.Contains("assword:"))
                             {
                                 result.StatusCode = ResultStatusCode.RetryAuthentication;
                                 Log.Debug("Username/Password invalid or not sent");
@@ -406,7 +406,7 @@
                         }
                         else
                         {
-                            result.SetErrorFormat("Unknown error.  exitCode={0}, out={1}, err={2}", proc.ExitCode, output, err);
+                            result.SetErrorFormat("Unknown error.  exitCode={0}, out='{1}', err='{2}'", proc.ExitCode, String.Join("|", output), String.Join("|", err));
                         }
                     }
                 }


Use direct Socket instead of TcpClient

Use direct Socket instead of TcpClient

--- Syndll2/NetworkConnection.cs
+++ Syndll2/NetworkConnection.cs
@@ -13,13 +13,13 @@
     internal class NetworkConnection : IConnection
     {
         private readonly IPEndPoint _endPoint;
-        private readonly TcpClient _tcpClient;
+        private readonly Socket _socket;
         private NetworkStream _stream;
         private bool _disposed;

         public bool Connected
         {
-            get { return _tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected; }
+            get { return _socket != null && _socket.Connected; }
         }

         public Stream Stream
@@ -30,7 +30,7 @@
         private NetworkConnection(IPEndPoint endPoint)
         {
             _endPoint = endPoint;
-            _tcpClient = new TcpClient
+            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
                 {
                     // todo: see if these timeout values need adjusting
                     ReceiveTimeout = 5000,
@@ -63,15 +63,15 @@
             // Enter the gate.  This will block until it is safe to connect.
             GateKeeper.Enter(endPoint, timeout);

-            var client = connection._tcpClient;
+            var socket = connection._socket;
             try
             {
                 // Now we can try to connect, using the specified timeout.
-                var result = client.BeginConnect(endPoint.Address, endPoint.Port, null, null);
+                var result = socket.BeginConnect(endPoint, socket.EndConnect, null);
                 result.AsyncWaitHandle.WaitOne(timeout, true);
-                if (!client.Connected)
+                if (!socket.Connected)
                 {
-                    client.Close();
+                    socket.Close();
                     throw new TimeoutException("Timeout occurred while trying to connect to the terminal.");
                 }
             }
@@ -82,7 +82,7 @@
             }

             // Get the stream for the connection
-            connection._stream = client.GetStream();
+            connection._stream = new NetworkStream(socket, true);

             Util.Log("Connected!");

@@ -116,16 +116,19 @@
             await GateKeeper.EnterAsync(endPoint, timeout);

             // Now we can try to connect, using the specified timeout.
-            var client = connection._tcpClient;
-            await Task.WhenAny(client.ConnectAsync(endPoint.Address, endPoint.Port), Task.Delay(timeout));
-            if (!client.Connected)
-            {
-                client.Close();
+            var socket = connection._socket;
+
+            var connectTask = Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, endPoint, null);
+
+            await Task.WhenAny(connectTask, Task.Delay(timeout));
+            if (!socket.Connected)
+            {
+                socket.Close();
                 throw new TimeoutException("Timeout occurred while trying to connect to the terminal.");
             }

             // Get the stream for the connection
-            connection._stream = client.GetStream();
+            connection._stream = new NetworkStream(socket, true);

             Util.Log("Connected!");

@@ -175,8 +178,7 @@
                 return;
             }

-            _stream.Close();
-            _tcpClient.Close();
+            _socket.Disconnect(false);
             GateKeeper.Exit(_endPoint);

             Util.Log("Disconnected.");
@@ -195,7 +197,8 @@
             if (disposing)
             {
                 Disconnect();
-                _stream.Dispose();
+                if (_stream != null)
+                    _stream.Dispose();
             }

             _disposed = true;


improved ConfigurationElementBase.cs

improved ConfigurationElementBase.cs

--- Common/ConfigurationElementBase.cs
+++ Common/ConfigurationElementBase.cs
@@ -29,6 +29,7 @@
         public ConfigurationElementBase(bool nameRequired)
         {
             m_NameRequired = nameRequired;
+            Options = new NameValueCollection();
         }

         /// <summary>
@@ -71,11 +72,6 @@
         /// </returns>
         protected override bool OnDeserializeUnrecognizedAttribute(string name, string value)
         {
-            if (Options == null)
-            {
-                Options = new NameValueCollection();
-            }
-
             Options.Add(name, value);
             return true;
         }


Fix two mispelling

Fix two mispelling

--- SystemReportTool/TestExec.cs
+++ SystemReportTool/TestExec.cs
@@ -70,9 +70,9 @@
             Request.ProgressBar.ProgressBarValue++;
             TestNetwork.TracertTest("www.3dxchat.com", 30);
             Request.ProgressBar.ProgressBarValue++;
-            TestNetwork.PortTest("198.105.215.52", 8124, "USdirect");
+            TestNetwork.PortTest("198.105.215.52", 8124, "US Direct");
             Request.ProgressBar.ProgressBarValue++;
-            TestNetwork.PortTest("54.72.64.172", 8124, "EUproxy");
+            TestNetwork.PortTest("54.72.64.172", 8124, "EU Proxy");
             Request.ProgressBar.ProgressBarValue++;
             this.ResultTestFull.Add(TestNetwork.GetResult());
         }


Ajouter la fonction blocs

Ajouter la fonction blocs

--- TP3Etu/TP3/FormPrincipale.cs
+++ TP3Etu/TP3/FormPrincipale.cs
@@ -89,15 +89,116 @@
     #endregion

     #region Code à développer
-		void CreeNouveauBlocActif()
+		TypeBloc CreeNouveauBlocActif()
 		{
 			Random rnd = new Random(420);
 			int random = 0;
 			random = rnd.Next(2, 8);
-
+
+			// Carré
 			if (random == 2)
 			{
-
+				// Positions Y
+				blocActifY[0] = 0;
+				blocActifY[1] = 0;
+				blocActifY[2] = 1;
+				blocActifY[3] = 1;
+				//Positions X
+				blocActifX[0] = 1;
+				blocActifX[1] = 2;
+				blocActifX[2] = 1;
+				blocActifX[3] = 2;
+				return TypeBloc.Carré;
+			}
+			// Ligne
+			else if (random == 3)
+			{
+				// Positions Y
+				blocActifY[0] = 0;
+				blocActifY[1] = 0;
+				blocActifY[2] = 1;
+				blocActifY[3] = 1;
+				//Positions X
+				blocActifX[0] = 1;
+				blocActifX[1] = 2;
+				blocActifX[2] = 1;
+				blocActifX[3] = 2;
+				return TypeBloc.Ligne;
+			}
+			// T
+			else if (random == 4)
+			{
+				// Positions Y
+				blocActifY[0] = 0;
+				blocActifY[1] = 0;
+				blocActifY[2] = 1;
+				blocActifY[3] = 1;
+				//Positions X
+				blocActifX[0] = 1;
+				blocActifX[1] = 2;
+				blocActifX[2] = 1;
+				blocActifX[3] = 2;
+				return TypeBloc.T;
+			}
+			// L
+			else if (random == 5)
+			{
+				// Positions Y
+				blocActifY[0] = 0;
+				blocActifY[1] = 1;
+				blocActifY[2] = 1;
+				blocActifY[3] = 1;
+				//Positions X
+				blocActifX[0] = 1;
+				blocActifX[1] = 2;
+				blocActifX[2] = 1;
+				blocActifX[3] = 2;
+				return TypeBloc.L;
+			}
+			// J
+			else if (random == 6)
+			{
+				// Positions Y
+				blocActifY[0] = 0;
+				blocActifY[1] = 0;
+				blocActifY[2] = 1;
+				blocActifY[3] = 1;
+				//Positions X
+				blocActifX[0] = 1;
+				blocActifX[1] = 2;
+				blocActifX[2] = 1;
+				blocActifX[3] = 2;
+				return TypeBloc.J;
+			}
+			// S
+			else if (random == 7)
+			{
+				// Positions Y
+				blocActifY[0] = 0;
+				blocActifY[1] = 0;
+				blocActifY[2] = 1;
+				blocActifY[3] = 1;
+				//Positions X
+				blocActifX[0] = 1;
+				blocActifX[1] = 2;
+				blocActifX[2] = 1;
+				blocActifX[3] = 2;
+				return TypeBloc.S;
+			}
+			// Z
+			else if (random == 8)
+			{
+				// Positions Y
+				blocActifY[0] = 0;
+				blocActifY[1] = 0;
+				blocActifY[2] = 1;
+				blocActifY[3] = 1;
+				//Positions X
+				blocActifX[0] = 1;
+				blocActifX[1] = 2;
+				blocActifX[2] = 1;
+				blocActifX[3] = 2;
+				return TypeBloc.Z;
 			}
 		}


Fix quelse sustsudf

Fix quelse sustsudf

--- TP3Etu/TP3/FormPrincipale.cs
+++ TP3Etu/TP3/FormPrincipale.cs
@@ -6,16 +6,13 @@
 {
 	public partial class FormPrincipale : Form
 	{
-        #region Propriétés /  variables partagées par toutes les méthodes.
-        //Position du bloc de rotation
-        static int colonneCourante = 0;
-        static int ligneCourante = 0;
-        //Position relative du bloc actif selon le bloc de rotation
-        static int[] blocActifX = new int[4] { 0, 0, 0, 0 };
-        static int[] blocActifY = new int[4] { 0, 0, 0, 0 };
-        //Nombre de colonnes dans le jeu
-        int nbColonnesJeu = 10;
-		#region Propriétés /  variables partagées par toutes les méthodes.
+    #region Propriétés /  variables partagées par toutes les méthodes.
+    //Position du bloc de rotation
+    static int colonneCourante = 0;
+    static int ligneCourante = 0;
+    //Position relative du bloc actif selon le bloc de rotation
+    static int[] blocActifX = new int[4] { 0, 0, 0, 0 };
+    static int[] blocActifY = new int[4] { 0, 0, 0, 0 };
 		//Nombre de colonnes dans le jeu
 		static int nbColonnesJeu = 10;
 		//Nombre de lignes dans le jeu


Add exception handler in multicast delegate

--- CSharpRecipe/Recipe.ClassAndGeneric/MulticastDelegate.cs
+++ CSharpRecipe/Recipe.ClassAndGeneric/MulticastDelegate.cs
@@ -1,11 +1,17 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
+using System.Runtime.Serialization;
+using System.Security.Permissions;
 using System.Text;
 using System.Threading.Tasks;

 namespace Recipe.ClassAndGeneric
 {
+    /// <summary>
+    /// Test method group
+    /// </summary>
     public class TestInvokeIntReturn
     {
         public static int Method1()
@@ -22,8 +28,7 @@

         public static int Method3()
         {
-            Console.WriteLine("Invoked Method3\n");
-            return 3;
+            throw new Exception("This is a test exception");
         }
     }

@@ -39,10 +44,27 @@

             Console.WriteLine("Fire delegates in reverse");
             Delegate[] delegateList = allInstances.GetInvocationList();
+
+            List<Exception> invocationExceptions = new List<Exception>();
+
             foreach (Func<int> instance in delegateList.EveryOther())
             {
-               int retVal= instance();
-                Console.WriteLine($"Delegate returns {retVal}\n");
+                try
+                {
+                    int retVal = instance();
+                    Console.WriteLine($"Delegate returns {retVal}\n");
+                }
+                catch (Exception ex)
+                {
+                    Console.WriteLine(ex.ToString());
+                    invocationExceptions.Add(ex);
+                }
+
+            }
+
+            if (invocationExceptions.Count>0)
+            {
+                throw new MulticastInvocationException(invocationExceptions);
             }
         }

@@ -65,4 +87,48 @@
             }
         }
     }
+
+    /// <summary>
+    /// Exception handler class
+    /// </summary>
+    [Serializable]
+    public class MulticastInvocationException : Exception
+    {
+        private List<Exception> _invocationExceptions;
+
+        public MulticastInvocationException() : base()
+        {
+
+        }
+
+        public MulticastInvocationException(IEnumerable<Exception> invocationExceptions)
+        {
+            this._invocationExceptions = new List<Exception>(invocationExceptions);
+        }
+
+        public MulticastInvocationException(string message):base(message)
+        {
+
+        }
+
+        public MulticastInvocationException(string message, Exception innerException) : base(message, innerException)
+        {
+
+        }
+
+        protected MulticastInvocationException(SerializationInfo info, StreamingContext context) : base(info, context)
+        {
+            _invocationExceptions = (List<Exception>) info.GetValue("InvocationExceptions", typeof(List<Exception>));
+        }
+
+        [SecurityPermission(SecurityAction.Demand,SerializationFormatter = true)]
+        public override void GetObjectData(SerializationInfo info, StreamingContext context)
+        {
+            info.AddValue("InvocationExceptions", this.InvocationExceptions);
+            base.GetObjectData(info, context);
+        }
+
+        public ReadOnlyCollection<Exception> InvocationExceptions
+            => new ReadOnlyCollection<Exception>(_invocationExceptions);
+    }
 }


Fix InBetweenInspector

Fix InBetweenInspector

--- Assets/MixedRealityToolkit.SDK/Inspectors/Utilities/Solvers/InBetweenInspector.cs
+++ Assets/MixedRealityToolkit.SDK/Inspectors/Utilities/Solvers/InBetweenInspector.cs
@@ -11,7 +11,6 @@
     public class InBetweenEditor : UnityEditor.Editor
     {
         private SerializedProperty trackedObjectProperty;
-        private SerializedProperty secondTrackedHandJointProperty;
         private SerializedProperty transformTargetProperty;
         private InBetween solverInBetween;

@@ -20,7 +19,6 @@
         private void OnEnable()
         {
             trackedObjectProperty = serializedObject.FindProperty("trackedObjectForSecondTransform");
-            secondTrackedHandJointProperty = serializedObject.FindProperty("secondTrackedHandJoint");
             transformTargetProperty = serializedObject.FindProperty("secondTransformOverride");

             solverInBetween = target as InBetween;
@@ -38,11 +36,6 @@
                 EditorGUI.BeginChangeCheck();
                 EditorGUILayout.PropertyField(trackedObjectProperty);
                 trackedObjectChanged = EditorGUI.EndChangeCheck();
-
-                if (trackedObjectProperty.intValue == (int)TrackedObjectType.HandJoint)
-                {
-                    EditorGUILayout.PropertyField(secondTrackedHandJointProperty);
-                }
             }

             EditorGUILayout.PropertyField(transformTargetProperty);


Fallback to guncomp on the entity (#10659)

--- Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs
+++ Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs
@@ -154,19 +154,18 @@

     public GunComponent? GetGun(EntityUid entity)
     {
-        if (!EntityManager.TryGetComponent(entity, out SharedHandsComponent? hands) ||
-            hands.ActiveHandEntity is not { } held)
-        {
-            return null;
-        }
-
-        if (!EntityManager.TryGetComponent(held, out GunComponent? gun))
-            return null;
-
         if (!_combatMode.IsInCombatMode(entity))
             return null;

-        return gun;
+        if (EntityManager.TryGetComponent(entity, out SharedHandsComponent? hands) &&
+            hands.ActiveHandEntity is { } held &&
+            TryComp(held, out GunComponent? gun))
+        {
+            return gun;
+        }
+
+        // Last resort is check if the entity itself is a gun.
+        return !TryComp(entity, out gun) ? null : gun;
     }

     private void StopShooting(GunComponent gun)


update spu block size recommendations

update spu block size recommendations

--- CompatBot/Utils/ResultFormatters/LogParserResultFormatter.WeirdSettingsSection.cs
+++ CompatBot/Utils/ResultFormatters/LogParserResultFormatter.WeirdSettingsSection.cs
@@ -138,11 +138,8 @@
                 notes.Add("⚠ `HLE lwmutex` is enabled, might affect compatibility");
             if (items["spu_block_size"] is string spuBlockSize)
             {
-                if ((string.IsNullOrEmpty(serial) || !KnownMegaSpuBlockSizeIds.Contains(serial))
-                    && spuBlockSize != "Safe")
-                {
-                    notes.Add($"⚠ Please use `Safe` mode for `SPU Block Size`. `{spuBlockSize}` is currently unstable.");
-                }
+                if (spuBlockSize == "Giga")
+                    notes.Add($"⚠ Please change `SPU Block Size`, `{spuBlockSize}` is currently unstable.");
             }

             if (items["lib_loader"] is string libLoader
@@ -255,13 +252,14 @@
         {
             if (serial == "BLUS30481" || serial == "BLES00826" || serial == "BLJM60223")
             {
-                if (items["spu_decoder"] is string spuDecoder
+/*                if (items["spu_decoder"] is string spuDecoder
                     && spuDecoder.Contains("LLVM")
                     && items["spu_block_size"] is string spuBlockSize
                     && spuBlockSize != "Mega")
                 {
                     notes.Add("⚠ This game needs `SPU Block Size` set to `Mega` when using `SPU Decoder` `Recompiler (LLVM)`");
                 }
+*/

                 if (items["frame_limit"] is string frameLimit
                     && frameLimit != "30")


Fixed issue with incorrect displaying time for current week

--- TimeTracker/MainViewModel.cs
+++ TimeTracker/MainViewModel.cs
@@ -337,9 +337,14 @@
 			var currentDate = DateTime.Now.Date;
 			var firstDayOfWeek = Thread.CurrentThread.CurrentUICulture.DateTimeFormat.FirstDayOfWeek;

-			var daysBefore = Math.Abs(currentDate.DayOfWeek - firstDayOfWeek);
-
-			var firstDayOfCurrentWeek = currentDate.Subtract(TimeSpan.FromDays(daysBefore));
+			while (currentDate.DayOfWeek != firstDayOfWeek)
+			{
+				currentDate = currentDate.Subtract(TimeSpan.FromDays(1));
+			}
+
+			//var daysBefore = Math.Abs(currentDate.DayOfWeek - firstDayOfWeek);
+
+			var firstDayOfCurrentWeek = currentDate;
 			//var daysAfter = DayOfWeek.Sunday - currentDate.DayOfWeek;

 			//var firstDay = currentDate.Subtract(TimeSpan.FromDays(daysBefore));


added mechanism to prepare before ToString is called.

--- src/cs/Construct.cs
+++ src/cs/Construct.cs
@@ -91,7 +91,10 @@
       return deps;
     }

+    public virtual void prepare() {}
+
     public String ToString(String prefix) {
+      this.prepare();
       return this.getAnnotationsAsString(prefix)
           + prefix + this.type + " " + this.name
           + this.getSuperAsString()


Added overloaded Enqueue(Action action)

Added overloaded Enqueue(Action action)

This little convenience make the simplest usage a one liner:
`UnityMainThreadDispatcher.Instance().Enqueue(() => Debug.Log ("This is executed from the main thread"));`

I've implemented this in my own project and it seems to be working just fine. I'm no Unity expert, so if there are any risks to this I may not be able to tell.

--- UnityMainThreadDispatcher.cs
+++ UnityMainThreadDispatcher.cs
@@ -46,6 +46,20 @@
 			});
 		}
 	}
+
+        /// <summary>
+        /// Locks the queue and adds the Action to the queue
+	/// </summary>
+	/// <param name="action">function that will be executed from the main thread.</param>
+	public void Enqueue(Action action)
+	{
+		Enqueue(ActionWrapper(action));
+	}
+	IEnumerator ActionWrapper(Action a)
+	{
+		a();
+		yield return null;
+	}

 	private static UnityMainThreadDispatcher _instance = null;


Add open setting button

Add open setting button

--- ViewModels/ShellViewModel.cs
+++ ViewModels/ShellViewModel.cs
@@ -37,7 +37,7 @@
             EventAggregator = eventAggregator;
             Reciever = messageRevicer;
             Engine = engine;
-            DisplayName = "Tirkx Downloader";
+            DisplayName = "Tirkx Downloader 0.1 beta";
             queueEngineMessage = "Engine isn't working";

             Items.Add(queueViewModel);
@@ -68,6 +68,11 @@
             }
         }

+        public void OpenSetting()
+        {
+            WindowManager.ShowDialog(new SettingShellViewModel());
+        }
+
         protected override void OnDeactivate(bool close)
         {
             if (close)


Misc cleanup

Misc cleanup

--- VirusTotal.NET/VirusTotal.cs
+++ VirusTotal.NET/VirusTotal.cs
@@ -108,6 +108,9 @@
             }
         }

+        /// <summary>
+        /// The user-agent to use when doing queries
+        /// </summary>
         public string UserAgent { get { return _client.DefaultRequestHeaders.UserAgent.ToString(); } set { _client.DefaultRequestHeaders.Add("User-Agent", value); } }

         /// <summary>
@@ -328,7 +331,7 @@
             }

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("resource", string.Join(",", hashes));

             //https://www.virustotal.com/vtapi/v2/file/rescan
@@ -349,7 +352,7 @@
             ValidateResource(resource);

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("resource", resource);

             //https://www.virustotal.com/vtapi/v2/file/rescan
@@ -429,7 +432,7 @@
             }

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("resource", string.Join(",", hashes));

             //https://www.virustotal.com/vtapi/v2/file/report
@@ -449,7 +452,7 @@
             ValidateResource(resource);

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("resource", resource);

             //https://www.virustotal.com/vtapi/v2/file/report
@@ -495,7 +498,7 @@
                 throw new ResourceLimitException("Too many URLs. There is a maximum of 25 URLs at the same time.");

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("url", string.Join(Environment.NewLine, urls));

             //https://www.virustotal.com/vtapi/v2/url/scan
@@ -514,7 +517,7 @@
                 throw new ArgumentNullException(nameof(url), "You have to supply an URL.");

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("url", url.ToString());

             //https://www.virustotal.com/vtapi/v2/url/scan
@@ -560,7 +563,7 @@
                 throw new ResourceLimitException("Too many URLs. There is a maximum of 4 urls at the time.");

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("resource", string.Join(Environment.NewLine, urls));

             //Optional
@@ -583,7 +586,7 @@
                 throw new ArgumentNullException(nameof(url), "You have to supply an URL.");

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("resource", url.ToString());

             //Optional
@@ -674,7 +677,7 @@
                 throw new ArgumentException("You have to supply a domain.", nameof(domain));

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("domain", domain);

             //Hack because VT thought it was a good idea to have this API call as GET
@@ -717,7 +720,7 @@
                 throw new ArgumentException("Comment must not be null or whitespace", nameof(comment));

             //Required
-            Dictionary<string, string> values = new Dictionary<string, string>();
+            IDictionary<string, string> values = new Dictionary<string, string>();
             values.Add("resource", resource);
             values.Add("comment", comment);

@@ -725,7 +728,7 @@
             return GetResult<ScanResult>("comments/put", HttpMethod.Post, CreateContent(values));
         }

-        private FormUrlEncodedContent CreateContent(Dictionary<string, string> values)
+        private FormUrlEncodedContent CreateContent(IDictionary<string, string> values)
         {
             return new FormUrlEncodedContent(_defaultValues.Concat(values));
         }


Beispiele zu Dateigrösse verbessert

Beispiele zu Dateigrösse verbessert

--- HumanizrDemo/HumanizrDemo/HumanizrExamples.cs
+++ HumanizrDemo/HumanizrDemo/HumanizrExamples.cs
@@ -97,11 +97,19 @@
         }

         [TestMethod]
-        public void Dateigroesse_Wird_Benutzerfreundlich_angezeigt()
+        public void Dateigroesse_Laesst_sich_einfach_umrechnen()
         {
             var filesize = (10).Megabytes();

             Assert.AreEqual(10240, filesize.Kilobytes);
         }
+
+        [TestMethod]
+        public void Dateigroesse_Wird_Benutzerfreundlich_angezeigt()
+        {
+            var filesize = (100300000).Bytes();
+
+            Assert.AreEqual(95.65, filesize.Megabytes, 0.01);
+        }
     }
 }


Adicionada TAG ContrucaoCivil (sem o S) pois o ISSNet utiliza o nome da tag errada mesmo

--- src/ACBr.Net.NFSe/Providers/ISSNet/ProviderISSNet.cs
+++ src/ACBr.Net.NFSe/Providers/ISSNet/ProviderISSNet.cs
@@ -200,6 +200,18 @@
             return servico;
         }

+        protected override XElement WriteConstrucaoCivilRps(NotaServico nota)
+        {
+            if (nota.ConstrucaoCivil.CodigoObra.IsEmpty()) return null;
+
+            var construcao = new XElement("ContrucaoCivil");
+
+            construcao.AddChild(AdicionarTag(TipoCampo.Str, "", "CodigoObra", 1, 15, Ocorrencia.NaoObrigatoria, nota.ConstrucaoCivil.CodigoObra));
+            construcao.AddChild(AdicionarTag(TipoCampo.Str, "", "Art", 1, 15, Ocorrencia.Obrigatoria, nota.ConstrucaoCivil.ArtObra));
+
+            return construcao;
+        }
+
         #endregion RPS

         #region Services


update

update

--- Infrastructure/DrvSimu/DrvSimuControl.Load.cs
+++ Infrastructure/DrvSimu/DrvSimuControl.Load.cs
@@ -13,7 +13,7 @@
         private void ScientificCanvas_Load(object sender, EventArgs e)
         {
             var camera = new Camera(new vec3(4, 1.6f, 3), new vec3(0, 0, 0), new vec3(0, 1, 0),
-                 CameraType.Ortho, this.Width, this.Height);
+                 CameraType.Perspecitive, this.Width, this.Height);
             var cameraManipulater = new SatelliteManipulater();
             cameraManipulater.Bind(camera, this);
             this.cameraManipulater = cameraManipulater;


refactor

refactor

--- Jasily.Core.Linq/Linq/EnumerableExtensions.cs
+++ Jasily.Core.Linq/Linq/EnumerableExtensions.cs
@@ -106,13 +106,20 @@

         #region giveup

+        /// <summary>
+        /// Skip() will skip left of items, but Giveup() will skip right of items.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="source"></param>
+        /// <param name="giveup"></param>
+        /// <returns></returns>
         public static IEnumerable<T> Giveup<T>(this IEnumerable<T> source, int giveup)
         {
-            var collection = source as ICollection<T>;
-            if (collection != null)
-            {
-                if (collection.Count <= giveup) yield break;
-                foreach (var item in collection.Take(collection.Count - giveup))
+            var total = (source as ICollection<T>)?.Count ?? (source as ICollection)?.Count ?? -1;
+            if (total != -1)
+            {
+                if (total <= giveup) yield break;
+                foreach (var item in source.Take(total - giveup))
                 {
                     yield return item;
                 }


bugfix PullRequestQueryParamsの不備 #83

bugfix PullRequestQueryParamsの不備 #83

--- src/Backlog4net/Api/Option/PullRequestQueryParams.cs
+++ src/Backlog4net/Api/Option/PullRequestQueryParams.cs
@@ -4,7 +4,7 @@

 namespace Backlog4net.Api.Option
 {
-    public class PullRequestQueryParams : QueryParams
+    public class PullRequestQueryParams : GetParams
     {
         public IList<PullRequestStatusType> StatusType { set => AddNewArrayParams("statusId[]", value, x => x.ToString("D")); }

@@ -13,5 +13,9 @@
         public IList<long> IssueIds { set => AddNewArrayParams("issueId[]", value); }

         public IList<long> CreatedUserIds { set => AddNewArrayParams("createdUserId[]", value); }
+
+        public long Offset { set => AddNewParamValue(value); }
+
+        public int Count { set => AddNewParamValue(value); }
     }
 }


More fixes.

More fixes.

--- src/BigBook/ExtensionMethods/ReflectionExtensions.cs
+++ src/BigBook/ExtensionMethods/ReflectionExtensions.cs
@@ -1031,7 +1031,7 @@
         /// <returns>
         /// <c>true</c> if [is JIT optimizer disabled] [the specified attribute]; otherwise, <c>false</c>.
         /// </returns>
-        private static bool IsJitOptimized(this DebuggableAttribute attribute) => !(bool)attribute.Property("IsJITOptimizerDisabled");
+        private static bool IsJitOptimized(this DebuggableAttribute attribute) => !(bool)(attribute.Property("IsJITOptimizerDisabled") ?? true);

         /// <summary>
         /// Determines whether [is JIT tracking enabled].
@@ -1040,6 +1040,6 @@
         /// <returns>
         /// <c>true</c> if [is JIT tracking enabled] [the specified attribute]; otherwise, <c>false</c>.
         /// </returns>
-        private static bool IsJitTrackingEnabled(this DebuggableAttribute attribute) => (bool)attribute.Property("IsJITTrackingEnabled");
+        private static bool IsJitTrackingEnabled(this DebuggableAttribute attribute) => (bool)(attribute.Property("IsJITTrackingEnabled") ?? false);
     }
 }


Exclude failing test temporarily on Linux

--- src/BloomTests/Collection/CollectionSettingsTests.cs
+++ src/BloomTests/Collection/CollectionSettingsTests.cs
@@ -128,7 +128,7 @@
 		[TestCase("", "2")] // default
 		[TestCase("Decimal", "2")]
 		[TestCase("Devanagari", "२")]
-		[TestCase("Khmer", "២")]
+		[TestCase("Khmer", "២", ExcludePlatform = "Linux", Reason = "Fails until BL-4796 provides a better implementation")]
 		[TestCase("Cjk-Decimal", "二")]
 		public void CharactersForDigitsForPageNumbers_Tests(string numberStyleName, string digitForNumber2)
 		{


Make GetUniqueName() virtual so it's possible to inject a customized version when extending the compiler

--- src/Boo.Lang.Compiler/Services/UniqueNameProvider.cs
+++ src/Boo.Lang.Compiler/Services/UniqueNameProvider.cs
@@ -25,31 +25,31 @@
 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endregion
-
-
-namespace Boo.Lang.Compiler.Services
-{
-	public class UniqueNameProvider
-	{
-		private int _localIndex;
-
-		///Generates a name that will be unique within the CompilerContext.
-		///<param name="components">Zero or more string(s) that will compose the generated name.</param>
-		///<returns>Returns the generated unique name.</returns>
-		public string GetUniqueName(params string[] components)
-		{
-			var suffix = string.Concat("$", (++_localIndex).ToString());
-			if (components == null || components.Length == 0)
-				return suffix;
-
-			var sb = new System.Text.StringBuilder();
-			foreach (var component in components)
-			{
-				sb.Append("$");
-				sb.Append(component);
-			}
-			sb.Append(suffix);
-			return sb.ToString();
-		}
-	}
-}
+
+
+namespace Boo.Lang.Compiler.Services
+{
+	public class UniqueNameProvider
+	{
+		private int _localIndex;
+
+		///Generates a name that will be unique within the CompilerContext.
+		///<param name="components">Zero or more string(s) that will compose the generated name.</param>
+		///<returns>Returns the generated unique name.</returns>
+		public virtual string GetUniqueName(params string[] components)
+		{
+			var suffix = string.Concat("$", (++_localIndex).ToString());
+			if (components == null || components.Length == 0)
+				return suffix;
+
+			var sb = new System.Text.StringBuilder();
+			foreach (var component in components)
+			{
+				sb.Append("$");
+				sb.Append(component);
+			}
+			sb.Append(suffix);
+			return sb.ToString();
+		}
+	}
+}


Set property action of cs client now can set nullable props

--- src/CSharpClient/Bit.CSharpClient.All/View/Screen.cs
+++ src/CSharpClient/Bit.CSharpClient.All/View/Screen.cs
@@ -199,6 +199,8 @@

         static object ConvertUsingDotNetTypeConverter(Type destinationType, object input)
         {
+            destinationType = Nullable.GetUnderlyingType(destinationType) ?? destinationType;
+
             if (destinationType.IsEnum)
             {
                 return Enum.Parse(destinationType, (string)input);


Code formatting moved static initializers in an order that did not evaluate, this commit needs backporting to 5.x and master

(cherry picked from commit b2dbf7b7e00b177ba64ec26b4c91ac354eb3c23c)

--- src/CodeGeneration/ApiGenerator/CodeConfiguration.cs
+++ src/CodeGeneration/ApiGenerator/CodeConfiguration.cs
@@ -9,6 +9,15 @@
 	public static class CodeConfiguration
 	{
 		private static string _root = null;
+
+		// @formatter:off — disable formatter after this line
+		public static string EsNetFolder { get; } = $@"{Root}..\..\..\src\Elasticsearch.Net\";
+		public static string LastDownloadedVersionFile { get; } = Path.Combine(Root, "last_downloaded_version.txt");
+
+		public static string NestFolder { get; } = $@"{Root}..\..\..\src\Nest\";
+		public static string RestSpecificationFolder { get; } = $@"{Root}RestSpecification\";
+		public static string ViewFolder { get; } = $@"{Root}Views\";
+		// @formatter:on — enable formatter after this line

 		public static readonly Assembly Assembly = typeof(ApiGenerator).Assembly;

@@ -50,13 +59,6 @@
 			.ToDictionary(k => k.Key, v => v.Value);

-		public static string EsNetFolder { get; } = $@"{Root}..\..\..\src\Elasticsearch.Net\";
-		public static string LastDownloadedVersionFile { get; } = Path.Combine(Root, "last_downloaded_version.txt");
-
-		public static string NestFolder { get; } = $@"{Root}..\..\..\src\Nest\";
-		public static string RestSpecificationFolder { get; } = $@"{Root}RestSpecification\";
-		public static string ViewFolder { get; } = $@"{Root}Views\";
-
 		private static string Root
 		{
 			get


Reduce release/64 limit for EndToEndTests.Constraints (backport #61480)

--- src/Compilers/CSharp/Test/Emit/Emit/EndToEndTests.cs
+++ src/Compilers/CSharp/Test/Emit/Emit/EndToEndTests.cs
@@ -281,7 +281,7 @@
                 (ExecutionArchitecture.x86, ExecutionConfiguration.Debug) => 420,
                 (ExecutionArchitecture.x86, ExecutionConfiguration.Release) => 1100,
                 (ExecutionArchitecture.x64, ExecutionConfiguration.Debug) => 180,
-                (ExecutionArchitecture.x64, ExecutionConfiguration.Release) => 480,
+                (ExecutionArchitecture.x64, ExecutionConfiguration.Release) => 400,
                 _ => throw new Exception($"Unexpected configuration {ExecutionConditionUtil.Architecture} {ExecutionConditionUtil.Configuration}")
             };


Fixed implementation of IDisposable. Throw ObjectDisposedException if trying to use object after it has been disposed

--- src/EasyZMq/EasyZMq/Sockets/EasyZMqReceiverSocket.cs
+++ src/EasyZMq/EasyZMq/Sockets/EasyZMqReceiverSocket.cs
@@ -38,6 +38,8 @@

         public void Start()
         {
+            if (_disposedValue) throw new ObjectDisposedException("EasyZMqReceiverSocket");
+
             _configuration.AddressBinder.ConnectOrBindAddress(_socket);

             _poller.PollTillCancelledNonBlocking();
@@ -126,6 +128,12 @@
             }
         }

+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
         private bool _disposedValue;
         protected virtual void Dispose(bool disposing)
         {
@@ -146,11 +154,6 @@

                 _disposedValue = true;
             }
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
         }

         private void DisposeMonitor()


Delete unused WaitHelper.WhenAll

Delete unused WaitHelper.WhenAll

--- src/EditorFeatures/TestUtilities/Async/WaitHelper.cs
+++ src/EditorFeatures/TestUtilities/Async/WaitHelper.cs
@@ -33,28 +33,6 @@
             {
                 throw new InvalidOperationException("PumingWait is likely in a deadlock");
             }
-        }
-
-        public static async Task<bool> WhenAll(this IEnumerable<Task> tasks, TimeSpan timeout)
-        {
-            var delay = Task.Delay(timeout);
-            var list = tasks.Where(x => !x.IsCompleted).ToList();
-
-            list.Add(delay);
-            do
-            {
-                await Task.WhenAny(list).ConfigureAwait(true);
-                list.RemoveAll(x => x.IsCompleted);
-                if (list.Count == 0)
-                {
-                    return true;
-                }
-
-                if (delay.IsCompleted)
-                {
-                    return false;
-                }
-            } while (true);
         }

         public static void WaitForDispatchedOperationsToComplete(DispatcherPriority priority)


Fix IsReadOnly accessors (#138)

Fix IsReadOnly accessors (#138)

--- src/ErrorProne.NET.StructAnalyzers/TypeExtensions.cs
+++ src/ErrorProne.NET.StructAnalyzers/TypeExtensions.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Concurrent;
 using System.Linq;
+using System.Linq.Expressions;
 using System.Reflection;
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.CSharp;
@@ -10,8 +11,7 @@
 {
     public static class TypeExtensions
     {
-        private static readonly object[] EmptyObjectsArray = new object[0];
-        private static readonly ConcurrentDictionary<Type, bool> ReadOnlyMap = new ConcurrentDictionary<Type, bool>();
+        private static readonly ConcurrentDictionary<Type, Func<ITypeSymbol, bool>> IsReadOnlyAccessors = new ConcurrentDictionary<Type, Func<ITypeSymbol, bool>>();

         /// <summary>
         /// Returns true if a given type is a struct and the struct is readonly.
@@ -29,24 +29,53 @@
                 return true;
             }

+            if (TryGetPropertyAccessor(IsReadOnlyAccessors, "IsReadOnly", type.GetType(), out var accessor))
+            {
+                return accessor(type);
+            }
+
             if (type is INamedTypeSymbol nt && nt.DeclaringSyntaxReferences.Length != 0)
             {
                 return nt.IsReadOnlyStruct();
             }

-            // Unfortunately, there is no way to get the information about the readonliness of the type.
-            // This is not a named type, so we'll try to get IsReadOnly property via reflection.
-            // Dirty, but can't see other options:(
-            return ReadOnlyMap.GetOrAdd(type.GetType(), t =>
+            return false;
+        }
+
+        private static bool TryGetPropertyAccessor<T, TResult>(ConcurrentDictionary<Type, Func<T, TResult>> cache, string propertyName, Type type, out Func<T, TResult> accessor)
+        {
+            if (cache.TryGetValue(type, out accessor))
             {
-                var property = t.GetRuntimeProperties().FirstOrDefault(p => p.Name == "IsReadOnly");
-                if (property?.GetMethod == null)
+                return accessor != null;
+            }
+
+            return TryGetPropertyAccessorSlow(cache, propertyName, type, out accessor);
+        }
+
+        private static bool TryGetPropertyAccessorSlow<T, TResult>(ConcurrentDictionary<Type, Func<T, TResult>> cache, string propertyName, Type type, out Func<T, TResult> accessor)
+        {
+            accessor = cache.GetOrAdd(
+                type,
+                _ =>
                 {
-                    return false;
-                }
+                    var getMethod = type.GetRuntimeProperties().FirstOrDefault(property => property.Name == propertyName)?.GetMethod;
+                    if (getMethod is null)
+                    {
+                        return null;
+                    }

-                return (bool) property.GetMethod.Invoke(type, EmptyObjectsArray);
-            });
+                    var obj = Expression.Parameter(typeof(T), "obj");
+                    var instance = !getMethod.IsStatic ? Expression.Convert(obj, getMethod.DeclaringType) : null;
+                    var expr = Expression.Lambda<Func<T, TResult>>(
+                        Expression.Convert(
+                            Expression.Call(instance, getMethod),
+                            typeof(TResult)),
+                        obj);
+
+                    return expr.Compile();
+                });
+
+            return accessor != null;
         }

         /// <summary>


Document OriginAttractionForce API

Document OriginAttractionForce API

--- Boing/Forces/OriginAttractionForce.cs
+++ Boing/Forces/OriginAttractionForce.cs
@@ -19,12 +19,24 @@
 namespace Boing
 {
     /// <summary>
-    /// An attraction towards the system's origin.
+    /// A force that attracts all non-pinned point masses towards the origin of the coordinate system.
     /// </summary>
     public sealed class OriginAttractionForce : IForce
     {
+        /// <summary>
+        /// Gets and sets the magnitude of the force.
+        /// </summary>
+        /// <remarks>
+        /// Positive values cause attraction to the origin, while negative values
+        /// cause repulsion from it. Larger values cause larger forces, and a zero
+        /// value effectively disables this force.
+        /// </remarks>
         public float Stiffness { get; set; }

+        /// <summary>
+        /// Initialises a new instance of <see cref="OriginAttractionForce"/>.
+        /// </summary>
+        /// <param name="stiffness"></param>
         public OriginAttractionForce(float stiffness = 40)
         {
             Stiffness = stiffness;


remove unimplemented listener

remove unimplemented listener

--- BrailleIO_ShowOff/ShowOff.Designer.cs
+++ BrailleIO_ShowOff/ShowOff.Designer.cs
@@ -549,7 +549,7 @@
             this.pictureBoxTouch.Size = new System.Drawing.Size(721, 363);
             this.pictureBoxTouch.TabIndex = 49;
             this.pictureBoxTouch.TabStop = false;
-            this.pictureBoxTouch.Click += new System.EventHandler(this.pictureBoxTouch_Click);
+            //this.pictureBoxTouch.Click += new System.EventHandler(this.pictureBoxTouch_Click);
             //this.pictureBoxTouch.MouseCaptureChanged += new System.EventHandler(pictureBoxTouch_MouseCaptureChanged);
             this.pictureBoxTouch.MouseDown += new System.Windows.Forms.MouseEventHandler(pictureBoxTouch_MouseDown);
             this.pictureBoxTouch.MouseEnter += new System.EventHandler(pictureBoxTouch_MouseEnter);


Fix construction to some extent on rotated grids (#5024)

* Fix things to some extent on rotated grids

* Use Box2Rotated overload of IEntityLookup in GetEntitiesInTile

--- Content.Shared/Maps/TurfHelpers.cs
+++ Content.Shared/Maps/TurfHelpers.cs
@@ -152,7 +152,10 @@
         {
             lookupSystem ??= IoCManager.Resolve<IEntityLookup>();

-            return lookupSystem.GetEntitiesIntersecting(turf.MapIndex, GetWorldTileBox(turf), flags);
+            if (!GetWorldTileBox(turf, out var worldBox))
+                return Enumerable.Empty<IEntity>();
+
+            return lookupSystem.GetEntitiesIntersecting(turf.MapIndex, worldBox, flags);
         }

         /// <summary>
@@ -183,7 +186,8 @@
         {
             var physics = EntitySystem.Get<SharedPhysicsSystem>();

-            var worldBox = GetWorldTileBox(turf);
+            if (!GetWorldTileBox(turf, out var worldBox))
+                return false;

             var query = physics.GetCollidingEntities(turf.MapIndex, in worldBox);

@@ -209,20 +213,25 @@
         /// <summary>
         /// Creates a box the size of a tile, at the same position in the world as the tile.
         /// </summary>
-        private static Box2 GetWorldTileBox(TileRef turf)
+        private static bool GetWorldTileBox(TileRef turf, out Box2Rotated res)
         {
             var map = IoCManager.Resolve<IMapManager>();
-
-            // This is scaled to 90 % so it doesn't encompass walls on other tiles.
-            var tileBox = Box2.UnitCentered.Scale(0.9f);

             if (map.TryGetGrid(turf.GridIndex, out var tileGrid))
             {
+                // This is scaled to 90 % so it doesn't encompass walls on other tiles.
+                var tileBox = Box2.UnitCentered.Scale(0.9f);
                 tileBox = tileBox.Scale(tileGrid.TileSize);
-                return tileBox.Translated(tileGrid.GridTileToWorldPos(turf.GridIndices));
+                var worldPos = tileGrid.GridTileToWorldPos(turf.GridIndices);
+                tileBox = tileBox.Translated(worldPos);
+                // Now tileBox needs to be rotated to match grid rotation
+                res = new Box2Rotated(tileBox, tileGrid.WorldRotation, worldPos);
+                return true;
             }

-            return tileBox;
+            // Have to "return something"
+            res = Box2Rotated.UnitCentered;
+            return false;
         }
     }
 }