Fixed a bug that prevented modified methods from calling the original method if no IMethodCall implementations were found

--- Deflector/Deflector/MethodCallInterceptionEmitter.cs
+++ Deflector/Deflector/MethodCallInterceptionEmitter.cs
@@ -29,6 +29,7 @@
         private MethodReference _stackCtor;
         private MethodReference _markerAttributeCtor;
         private MethodReference _addMethodCalls;
+        private MethodReference _containsKey;

         private TypeReference _markerAttributeType;

@@ -37,6 +38,8 @@
             _pushMethod = module.ImportMethod<Stack<object>>("Push");
             _toArray = module.ImportMethod<Stack<object>>("ToArray");
             _getMethodCall = module.ImportMethod<IDictionary<MethodBase, IMethodCall>>("get_Item");
+            _containsKey = module.ImportMethod<IDictionary<MethodBase, IMethodCall>>("ContainsKey");
+
             _invokeMethod = module.ImportMethod<IMethodCall>("Invoke");
             _stackCtor = module.ImportConstructor<Stack<object>>(new Type[0]);
             _markerAttributeCtor = module.ImportConstructor<MethodCallsAlreadyInterceptedAttribute>(new Type[0]);
@@ -99,8 +102,6 @@
                     constructorCalls.Select(instruction => instruction.Operand as MethodReference).ToArray();

                 // Precalculate all method call interceptors
-                var addMethod = module.ImportMethod<IDictionary<MethodBase, IMethodCall>>("Add", typeof(MethodBase),
-                    typeof(IMethodCall));

                 var provider = method.AddLocal<IMethodCallProvider>();
                 var getProvider = module.ImportMethod("GetProvider", typeof(MethodCallProviderRegistry));
@@ -184,13 +185,20 @@
             var constructor = (MethodReference)oldInstruction.Operand;
             var module = hostMethod.Module;

+            // TODO: Call Dictionary<,>.ContainsKey to check if there is a replacement method call for the current method
             // Get the IMethodCall instance for the current constructor
+            il.Emit(OpCodes.Ldloc, _callMap);
+            il.PushMethod(constructor, module);
+            il.Emit(OpCodes.Callvirt, _containsKey);
+
+            var skipInterception = il.Create(OpCodes.Nop);
+            il.Emit(OpCodes.Brfalse, skipInterception);
+
             il.Emit(OpCodes.Ldloc, _callMap);
             il.PushMethod(constructor, module);
             il.Emit(OpCodes.Callvirt, _getMethodCall);
             il.Emit(OpCodes.Stloc, _currentMethodCall);

-            var skipInterception = il.Create(OpCodes.Nop);

             il.Emit(OpCodes.Ldloc, _currentMethodCall);

@@ -241,16 +249,21 @@

             // Grab the method call instance
             il.Emit(OpCodes.Ldloc, _callMap);
-
-
             il.PushMethod(targetMethod, module);
+            il.Emit(OpCodes.Callvirt, _containsKey);
+
+            var skipInterception = il.Create(OpCodes.Nop);
+            il.Emit(OpCodes.Brfalse, skipInterception);
+
+            il.Emit(OpCodes.Ldloc, _callMap);
+
+            il.PushMethod(targetMethod, module);

             il.Emit(OpCodes.Callvirt, _getMethodCall);

             il.Emit(OpCodes.Stloc, _currentMethodCall);
-
-            var skipInterception = il.Create(OpCodes.Nop);
+

             il.Emit(OpCodes.Ldloc, _currentMethodCall);
             il.Emit(OpCodes.Brfalse, skipInterception);


Added label changed for sync PoI's and added Model loaded event

--- framework/csCommonSense/Types/DataServer/Service.cs
+++ framework/csCommonSense/Types/DataServer/Service.cs
@@ -99,6 +99,8 @@

         public delegate void PingReceivedHandler(Service s, BaseContent b);

+        public delegate void ModelLoadedHandler(BaseContent baseContent, IModelPoiInstance model);
+
         public const string ServiceVariableName = "Service:";
         public const string StaticServiceVariableName = "StaticService:";
         //private static readonly object _lock = new object();
@@ -418,7 +420,6 @@
                 return false;
             }
         }
-
         private bool CreateBackupOfLiveService()
         {
             if (string.IsNullOrEmpty(FileName)) return false;
@@ -642,6 +643,8 @@

         public event PingReceivedHandler PingReceived;

+        public event ModelLoadedHandler OnModelLoaded;
+
         public void MakeLocal()
         {
             UnSubscribeServiceChannel();
@@ -680,8 +683,14 @@
             if (PingReceived != null) PingReceived(this, c);
         }

+
         // Debounce every second or when 100 pois are received
         private DebouncedProcessor<BaseContent> _baseContentDebounce = new DebouncedProcessor<BaseContent>(1000,100);
+        internal void RaiseModelLoaded(BaseContent baseContent, IModelPoiInstance model)
+        {
+            var handler = OnModelLoaded;
+            if (handler != null) handler(baseContent, model);
+        }
         private void serviceChannel_OnBuffer(TEventEntry aEvent, int aTick, int aBufferId, TByteBuffer aBuffer)
         {
             var cm = ContentMessage.ConvertByteArrayToMessage(aBuffer.Buffer);
@@ -771,11 +780,39 @@
                                 try
                                 {
                                     obj.IsInTransit = true;
+                                    // Clone label dictionary
+                                    var diffLabels = new Dictionary<string, string>();
+                                    if (obj.Labels != null)
+                                    {
+                                        foreach (KeyValuePair<string, string> label in obj.Labels)
+                                        {
+                                            diffLabels.Add(label.Key, label.Value);
+                                        }
+                                    }
                                     RuntimeTypeModel.Default.DeserializeWithLengthPrefix(ms, obj, cl.ContentType,
                                         PrefixStyle.Base128, 0);
-
                                     _baseContentDebounce.Add(obj);
                                     //obj.ForceUpdate(true, true);
+
+                                    // Notify label changed:
+                                    if (obj.Labels != null)
+                                    {
+                                        foreach (KeyValuePair<string, string> currentLabel in obj.Labels)
+                                        {
+                                            string oldLabelValue;
+                                            if (diffLabels.TryGetValue(currentLabel.Key, out oldLabelValue))
+                                            {
+                                               if (currentLabel.Value != oldLabelValue) // label changed
+                                               {
+                                                  TriggerLabelChangedBySync(obj, currentLabel.Key, oldLabelValue, currentLabel.Value);
+                                               }
+                                            }
+                                            else // new label
+                                            {
+                                                TriggerLabelChangedBySync(obj, currentLabel.Key, null, currentLabel.Value);
+                                            }
+                                        }
+                                    }
                                 }
                                 catch (Exception e)
                                 {
@@ -795,6 +832,16 @@
                     }
                     break;
             }
+        }
+
+        /// <summary>
+        /// Notify label changed when BaseContent is synchronised over IMB bus
+        /// </summary>
+        private void TriggerLabelChangedBySync(BaseContent pConent, string pLabelKey, string pOldValue, string pNewValue)
+        {
+            // dsPoiLayer runs in Guid thread and uses label changed
+            Execute.OnUIThread(() => pConent.TriggerLabelChanged(pLabelKey, pOldValue, pNewValue));
+
         }

         public void Close()


add code

add code

--- Seed.BarCodeLine/Form1.cs
+++ Seed.BarCodeLine/Form1.cs
@@ -56,7 +56,7 @@
                         TBatch.Text = p.Batch;
                     }
                 }
-                _product.ProductLine = _productLine;
+                _config.ProductLine = _productLine;
                 _config.BigCodeLen = Convert.ToInt32(_bigCodeLen);
                 _config.SmlCodeLen = Convert.ToInt32(_smlCodeLen);
                 _config.CodeType = _codeType;


Annual rollover rewrite

Annual rollover rewrite

--- Server/HetsApi/Startup.cs
+++ Server/HetsApi/Startup.cs
@@ -86,16 +86,14 @@
                 options.MultipartBodyLengthLimit = 1073741824; // 1 GB
             });

-            // enable Hangfire
             //enable Hangfire
-
             services.AddHangfire(configuration =>
                 configuration
-                //.UseSerilogLogProvider()
+                .UseSerilogLogProvider()
                 .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
                 .UseSimpleAssemblyNameTypeSerializer()
                 .UseRecommendedSerializerSettings()
-                .UsePostgreSqlStorage(connectionString)
+                .UsePostgreSqlStorage(connectionString)
             );

             services.AddHangfireServer(options =>
@@ -119,41 +117,33 @@
         /// </summary>
         /// <param name="app"></param>
         /// <param name="env"></param>
-        /// <param name="loggerFactory"></param>
-        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
         {
-            if (env.IsDevelopment())
-                app.UseDeveloperExceptionPage();
+            // web site error handler  (Testing: app.UseDeveloperExceptionPage();)
+            app.UseWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder =>
+            {
+                builder.UseExceptionHandler(Configuration.GetSection("Constants:ErrorUrl").Value);
+            });

-            //app.UseMiddleware<ExceptionMiddleware>();

-            //TryMigrateDatabase(app, logger);
+            // enable Hangfire
+            BackgroundJobServerOptions jsOptions = new BackgroundJobServerOptions
+            {
+                WorkerCount = 1
+            };

-            //var healthCheckOptions = new HealthCheckOptions
-            //{
-            //    ResponseWriter = async (c, r) =>
-            //    {
-            //        c.Response.ContentType = MediaTypeNames.Application.Json;
-            //        var result = JsonSerializer.Serialize(
-            //           new
-            //           {
-            //               checks = r.Entries.Select(e =>
-            //          new {
-            //              description = e.Key,
-            //              status = e.Value.Status.ToString(),
-            //              tags = e.Value.Tags,
-            //              responseTime = e.Value.Duration.TotalMilliseconds
-            //          }),
-            //               totalResponseTime = r.TotalDuration.TotalMilliseconds
-            //           });
-            //        await c.Response.WriteAsync(result);
-            //    }
-            //};
+            app.UseHangfireServer(jsOptions);
+
+            // disable the back to site link
+            DashboardOptions dashboardOptions = new DashboardOptions
+            {
+                AppPath = null,
+                Authorization = new[] { new HangfireAuthorizationFilter() }
+            };

             //app.UseHealthChecks("/healthz", healthCheckOptions);

             app.UseRouting();
-            app.UseCors();
             app.UseAuthentication();
             app.UseAuthorization();
             app.UseEndpoints(endpoints =>
@@ -162,9 +152,10 @@
             });

             app.UseSwagger();
+            string swaggerApi = Configuration.GetSection("Constants:SwaggerApiUrl").Value;
             app.UseSwaggerUI(options =>
             {
-                options.SwaggerEndpoint(Configuration.GetSection("Constants:SwaggerApiUrl").Value, "HETS REST API v1");
+                options.SwaggerEndpoint(swaggerApi, "HETS REST API v1");
                 options.DocExpansion(DocExpansion.None);
             });
         }


Woops

Woops

--- SteamMobile/LinkTitles.cs
+++ SteamMobile/LinkTitles.cs
@@ -63,7 +63,7 @@
                     string youtubeUrl = null;
                     try
                     {
-                        var apiQuery = string.Format("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&order=relevance&q=" + ytName + "%20%2B%20" + ytArtist + "&key=" + ApiKey);
+                        var apiQuery = string.Format("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&order=relevance&q={0}%20%2B%20{1}&key={2}", ytName, ytArtist, ApiKey);
                         var ytResponse = DownloadPage(apiQuery);

                         var ytToken = JObject.Parse(ytResponse);


Fix Action return values

Fix Action return values

--- DynThings.WebPortal/Controllers/DevicesController.cs
+++ DynThings.WebPortal/Controllers/DevicesController.cs
@@ -90,7 +90,10 @@
             if (ModelState.IsValid)
             {
                 UnitOfWork.repoDevices.Edit(device.ID, device.Title);
-                return RedirectToAction("Ok");
+            }
+            else
+            {
+                return Content("Error");
             }
             return View(device);
         }


Updated tests

Updated tests

--- EFDataAccess.Tests/Spec/DynamicSpecificationTests.cs
+++ EFDataAccess.Tests/Spec/DynamicSpecificationTests.cs
@@ -7,211 +7,92 @@
     [TestFixture]
     public class DynamicSpecificationTests
     {
-        [Test]
-        public void Specification_with_equal_to_operation_type_is_satisfied_when_candiate_property_is_equal_to_dynamic_value()
+        private TestClass _candidateObject;
+
+        [SetUp]
+        public void Setup()
         {
-            var candidateObject = new TestClass() {Salary = 5000};
-            var specification = new DynamicSpecification<TestClass>("Salary",OperationType.EqualTo, 5000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsTrue(satisfied);
+            _candidateObject = new TestClass() { Salary = 5000 };
         }

         [Test]
-        public void Specification_with_equal_to_operation_type_is_not_satisfied_when_candiate_property_is_not_equal_to_dynamic_value()
+        public void EqualTo_test()
         {
-            var candidateObject = new TestClass() { Salary = 5000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.EqualTo, 4000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsFalse(satisfied);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.EqualTo, 5000).IsSatisfiedBy(_candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.EqualTo, 4000).IsSatisfiedBy(_candidateObject), Is.False);
         }

         [Test]
-        public void Specification_with_not_equal_to_operation_type_is_satisfied_when_candiate_property_is_not_equal_to_dynamic_value()
+        public void NotEqualTo_test()
         {
-            var candidateObject = new TestClass() { Salary = 5000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.NotEqualTo, 4000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsTrue(satisfied);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.NotEqualTo, 4000).IsSatisfiedBy(_candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.NotEqualTo, 5000).IsSatisfiedBy(_candidateObject), Is.False);
         }

         [Test]
-        public void Specification_with_not_equal_to_operation_type_is_not_satisfied_when_candiate_property_is_equal_to_dynamic_value()
+        public void GreaterThan_test()
         {
-            var candidateObject = new TestClass() { Salary = 5000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.NotEqualTo, 5000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsFalse(satisfied);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThan, 4000).IsSatisfiedBy(_candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThan, 6000).IsSatisfiedBy(_candidateObject), Is.False);
         }

         [Test]
-        public void Specification_with_greater_then_operation_type_is_satisfied_when_candiate_property_is_greater_than_dynamic_value()
+        public void LessThan_test()
         {
-            var candidateObject = new TestClass() { Salary = 5000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThan, 4000);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.LessThan, 6000).IsSatisfiedBy(_candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.LessThan, 4000).IsSatisfiedBy(_candidateObject), Is.False);
+        }

-            var satisfied = specification.IsSatisfiedBy(candidateObject);

-            Assert.IsTrue(satisfied);
+        [Test]
+        public void GreaterThanEqualTo_test()
+        {
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThanEqualTo, 5000).IsSatisfiedBy(_candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThanEqualTo, 4000).IsSatisfiedBy(_candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThanEqualTo, 6000).IsSatisfiedBy(_candidateObject), Is.False);
         }

         [Test]
-        public void Specification_with_greater_then_operation_type_is_not_satisfied_when_candiate_property_is_less_than_dynamic_value()
+        public void LessThanEqualTo_test()
         {
-            var candidateObject = new TestClass() { Salary = 4000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThan, 5000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsFalse(satisfied);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.LessThanEqualTo, 6000).IsSatisfiedBy(_candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.LessThanEqualTo, 5000).IsSatisfiedBy(_candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Salary", OperationType.LessThanEqualTo, 3000).IsSatisfiedBy(_candidateObject), Is.False);
         }

         [Test]
-        public void Specification_with_greater_then_equal_to_operation_type_is_satisfied_when_candiate_property_is_greater_than_or_equal_to_dynamic_value()
+        public void Contains_test()
         {
-            var candidateObject = new TestClass() { Salary = 4000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThanEqualTo, 4000);
+            var candidateObject = new TestClass() { Department = "Sales & Marketing" };

-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsTrue(satisfied);
+            Assert.That(new DynamicSpecification<TestClass>("Department", OperationType.Contains, "Market").IsSatisfiedBy(candidateObject),Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Department", OperationType.Contains, "HR").IsSatisfiedBy(candidateObject), Is.False);
         }

         [Test]
-        public void Specification_with_greater_then_equal_to_operation_type_is_not_satisfied_when_candiate_property_is_less_than_dynamic_value()
+        public void StartWith_test()
         {
-            var candidateObject = new TestClass() { Salary = 4000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.GreaterThanEqualTo, 5000);
+            var candidateObject = new TestClass() { Department = "Sales & Marketing" };

-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsFalse(satisfied);
+            Assert.That(new DynamicSpecification<TestClass>("Department", OperationType.StartsWith, "Sales").IsSatisfiedBy(candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Department", OperationType.StartsWith, "HR").IsSatisfiedBy(candidateObject), Is.False);
         }

         [Test]
-        public void Specification_with_less_than_operation_type_is_satisfied_when_candiate_property_is_less_than_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Salary = 4000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.LessThan, 5000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsTrue(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_less_than_operation_type_is_not_satisfied_when_candiate_property_is_greater_than_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Salary = 6000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.LessThan, 5000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsFalse(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_less_than_equal_to_operation_type_is_satisfied_when_candiate_property_is_less_than_or_equal_to_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Salary = 4000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.LessThanEqualTo, 4000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsTrue(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_less_than_equal_to_operation_type_is_not_satisfied_when_candiate_property_is_greater_than_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Salary = 6000 };
-            var specification = new DynamicSpecification<TestClass>("Salary", OperationType.LessThanEqualTo, 5000);
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsFalse(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_contains_operation_type_is_satisfied_when_candiate_property_has_dynamic_value()
+        public void EndsWith_test()
         {
             var candidateObject = new TestClass() { Department = "Sales & Marketing" };
-            var specification = new DynamicSpecification<TestClass>("Department", OperationType.Contains, "Market");

-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsTrue(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_contains_operation_type_is_not_satisfied_when_candiate_property_does_not_has_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Department = "Sales & Marketing" };
-            var specification = new DynamicSpecification<TestClass>("Department", OperationType.Contains, "HR");
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.False(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_start_with_operation_type_is_satisfied_when_candiate_property_begins_with_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Department = "Sales & Marketing" };
-            var specification = new DynamicSpecification<TestClass>("Department", OperationType.StartsWith, "Sales");
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsTrue(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_start_with_operation_type_is_not_satisfied_when_candiate_property_does_not_begin_with_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Department = "Sales & Marketing" };
-            var specification = new DynamicSpecification<TestClass>("Department", OperationType.Contains, "HR");
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.False(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_ends_with_operation_type_is_satisfied_when_candiate_property_end_with_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Department = "Sales & Marketing" };
-            var specification = new DynamicSpecification<TestClass>("Department", OperationType.EndsWith, "Marketing");
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.IsTrue(satisfied);
-        }
-
-        [Test]
-        public void Specification_with_ends_with_operation_type_is_not_satisfied_when_candiate_property_does_not_end_with_dynamic_value()
-        {
-            var candidateObject = new TestClass() { Department = "Sales & Marketing" };
-            var specification = new DynamicSpecification<TestClass>("Department", OperationType.EndsWith, "HR");
-
-            var satisfied = specification.IsSatisfiedBy(candidateObject);
-
-            Assert.False(satisfied);
+            Assert.That(new DynamicSpecification<TestClass>("Department", OperationType.EndsWith, "Marketing").IsSatisfiedBy(candidateObject), Is.True);
+            Assert.That(new DynamicSpecification<TestClass>("Department", OperationType.EndsWith, "HR").IsSatisfiedBy(candidateObject), Is.False);
         }

         [Test]
         public void Throws_exception_when_dynamic_property_is_not_found_in_field_and_properties_of_candidate_object()
         {
-            var candidateObject = new TestClass();
-            var specification = new DynamicSpecification<TestClass>("Name", OperationType.EndsWith, "Smith");
+            var specification = new DynamicSpecification<TestClass>("Age", OperationType.GreaterThan, 30);

-            TestDelegate matchingOfSpecification = ()=> specification.IsSatisfiedBy(candidateObject);
+            TestDelegate matchingOfSpecification = ()=> specification.IsSatisfiedBy(_candidateObject);

             Assert.That(matchingOfSpecification,Throws.TypeOf<ArgumentException>());


Add AllianceName to CorporationSheet model

--- EveLib.EveXml/Models/Corporation/CorporationSheet.cs
+++ EveLib.EveXml/Models/Corporation/CorporationSheet.cs
@@ -93,6 +93,12 @@
         public long AllianceId { get; set; }

         /// <summary>
+        ///     Gets or sets the alliance name.
+        /// </summary>
+        [XmlElement("allianceName")]
+        public string AllianceName { get; set; }
+
+        /// <summary>
         ///     Gets or sets the faction identifier.
         /// </summary>
         /// <value>The faction identifier.</value>


Fix scaled slider thumb tracking.  When CCControlSlider was scaled the thumb tracking was not updating with the correct values from touch position.

See issue https://github.com/mono/CocosSharp/issues/267

--- Extensions/GUI/CCControlExtension/CCControlSlider.cs
+++ Extensions/GUI/CCControlExtension/CCControlSlider.cs
@@ -170,25 +170,25 @@

 		protected float ValueForLocation(CCPoint location)
 		{
-            var world = BackgroundSprite.BoundingBoxTransformedToWorld;
-            float percent = (location.X - world.MinX) / BackgroundSprite.ContentSize.Width;
+            float percent = location.X / BackgroundSprite.ContentSize.Width;
 			return Math.Max(Math.Min(minimumValue + percent * (MaximumValue - MinimumValue), MaximumAllowedValue), MinimumAllowedValue);
 		}

 		protected virtual CCPoint LocationFromTouch(CCTouch touch)
 		{
 			CCPoint touchLocation = touch.Location; // Get the touch position
-
-            var world = BackgroundSprite.BoundingBoxTransformedToWorld;
+            touchLocation = BackgroundSprite.WorldToParentspace(touchLocation);
+
+            var size = BackgroundSprite.ContentSize;

             if (touchLocation.X < 0)
 			{
 				touchLocation.X = 0;
 			}
-            else if (touchLocation.X > world.MaxX)
-			{
-                touchLocation.X = world.MaxX;
-			}
+            else if (touchLocation.X > size.Width)
+            {
+                touchLocation.X = size.Width;
+            }
 			return touchLocation;
 		}

@@ -222,7 +222,7 @@
         {
             if (Selected)
             {
-                Value = ValueForLocation(ThumbSprite.PositionWorldspace);
+                Value = ValueForLocation(ThumbSprite.Position);
             }
             ThumbSprite.Color = CCColor3B.White;
             Selected = false;


修改提示信息

修改提示信息

--- GameFramework/ObjectPool/ObjectPoolManager.Object.cs
+++ GameFramework/ObjectPool/ObjectPoolManager.Object.cs
@@ -178,7 +178,7 @@
                 m_SpawnCount--;
                 if (m_SpawnCount < 0)
                 {
-                    throw new GameFrameworkException("Spawn count is less than 0.");
+                    throw new GameFrameworkException(Utility.Text.Format("Object '{0}' spawn count is less than 0.", Name));
                 }
             }


Changes generated by f17cb62f0d3dbcb29542097cec45422d3e5dd570

--- GoCardless/Services/BillingRequestTemplateService.cs
+++ GoCardless/Services/BillingRequestTemplateService.cs
@@ -121,6 +121,27 @@
             {};

             return _goCardlessClient.ExecuteAsync<BillingRequestTemplateResponse>("POST", "/billing_request_templates", urlParams, request, id => GetAsync(id, null, customiseRequestMessage), "billing_request_templates", customiseRequestMessage);
+        }
+
+        ///
+        /// Updates a Billing Request Template, which will affect all future
+        /// Billing Requests created by this template.
+        ///
+        /// <param name="identity">Unique identifier, beginning with "BRQ".</param>
+        /// <param name="request">An optional `BillingRequestTemplateUpdateRequest` representing the body for this update request.</param>
+        /// <param name="customiseRequestMessage">An optional `RequestSettings` allowing you to configure the request</param>
+        /// <returns>A single billing request template resource</returns>
+        public Task<BillingRequestTemplateResponse> UpdateAsync(string identity, BillingRequestTemplateUpdateRequest request = null, RequestSettings customiseRequestMessage = null)
+        {
+            request = request ?? new BillingRequestTemplateUpdateRequest();
+            if (identity == null) throw new ArgumentException(nameof(identity));
+
+            var urlParams = new List<KeyValuePair<string, object>>
+            {
+                new KeyValuePair<string, object>("identity", identity),
+            };
+
+            return _goCardlessClient.ExecuteAsync<BillingRequestTemplateResponse>("PUT", "/billing_requests/:identity", urlParams, request, null, "billing_request_templates", customiseRequestMessage);
         }
     }

@@ -327,6 +348,148 @@
         public string IdempotencyKey { get; set; }
     }

+
+    ///
+    /// Updates a Billing Request Template, which will affect all future Billing
+    /// Requests created by this template.
+    ///
+    public class BillingRequestTemplateUpdateRequest
+    {
+
+        ///
+        /// [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217#Active_codes)
+        /// currency code. Currently only "GBP" is supported as we only have one
+        /// scheme that is per_payment_authorised.
+        ///
+        [JsonProperty("mandate_request_currency")]
+        public string MandateRequestCurrency { get; set; }
+
+        ///
+        /// Key-value store of custom data that will be applied to the mandate
+        /// created when this request is fulfilled. Up to 3 keys are permitted,
+        /// with key names up to 50 characters and values up to 500 characters.
+        ///
+        [JsonProperty("mandate_request_metadata")]
+        public IDictionary<String, String> MandateRequestMetadata { get; set; }
+
+        ///
+        /// A Direct Debit scheme. Currently "ach", "autogiro", "bacs", "becs",
+        /// "becs_nz", "betalingsservice", "pad" and "sepa_core" are supported.
+        ///
+        [JsonProperty("mandate_request_scheme")]
+        public string MandateRequestScheme { get; set; }
+
+        ///
+        /// Verification preference for the mandate. One of:
+        ///

+        ///
`minimum`: only verify if absolutely required, such as when
+        /// part of scheme rules

+        ///
`recommended`: in addition to minimum, use the GoCardless risk
+        /// engine to decide an appropriate level of verification

+        ///
`when_available`: if verification mechanisms are available,
+        /// use them

+        ///
`always`: as `when_available`, but fail to create the Billing
+        /// Request if a mechanism isn't available

+        ///

+        ///
+        /// If not provided, the `recommended` level is chosen.
+        ///
+        [JsonProperty("mandate_request_verify")]
+        public BillingRequestTemplateMandateRequestVerify? MandateRequestVerify { get; set; }
+
+        ///
+        /// Verification preference for the mandate. One of:
+        ///

+        ///
`minimum`: only verify if absolutely required, such as when
+        /// part of scheme rules

+        ///
`recommended`: in addition to minimum, use the GoCardless risk
+        /// engine to decide an appropriate level of verification

+        ///
`when_available`: if verification mechanisms are available,
+        /// use them

+        ///
`always`: as `when_available`, but fail to create the Billing
+        /// Request if a mechanism isn't available

+        ///

+        ///
+        /// If not provided, the `recommended` level is chosen.
+        ///
+        [JsonConverter(typeof(StringEnumConverter))]
+        public enum BillingRequestTemplateMandateRequestVerify
+        {
+
+            /// `mandate_request_verify` with a value of "minimum"
+            [EnumMember(Value = "minimum")]
+            Minimum,
+            /// `mandate_request_verify` with a value of "recommended"
+            [EnumMember(Value = "recommended")]
+            Recommended,
+            /// `mandate_request_verify` with a value of "when_available"
+            [EnumMember(Value = "when_available")]
+            WhenAvailable,
+            /// `mandate_request_verify` with a value of "always"
+            [EnumMember(Value = "always")]
+            Always,
+        }
+
+        ///
+        /// Key-value store of custom data. Up to 3 keys are permitted, with key
+        /// names up to 50 characters and values up to 500 characters.
+        ///
+        [JsonProperty("metadata")]
+        public IDictionary<String, String> Metadata { get; set; }
+
+        ///
+        /// Name for the template. Provides a friendly human name for the
+        /// template, as it is shown in the dashboard. Must not exceed 255
+        /// characters.
+        ///
+        [JsonProperty("name")]
+        public string Name { get; set; }
+
+        ///
+        /// Amount in minor unit (e.g. pence in GBP, cents in EUR).
+        ///
+        [JsonProperty("payment_request_amount")]
+        public int? PaymentRequestAmount { get; set; }
+
+        ///
+        /// [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217#Active_codes)
+        /// currency code. Currently only "GBP" is supported as we only have one
+        /// scheme that is per_payment_authorised.
+        ///
+        [JsonProperty("payment_request_currency")]
+        public string PaymentRequestCurrency { get; set; }
+
+        ///
+        /// A human-readable description of the payment. This will be displayed
+        /// to the payer when authorising the billing request.
+        ///
+        ///
+        [JsonProperty("payment_request_description")]
+        public string PaymentRequestDescription { get; set; }
+
+        ///
+        /// Key-value store of custom data that will be applied to the payment
+        /// created when this request is fulfilled. Up to 3 keys are permitted,
+        /// with key names up to 50 characters and values up to 500 characters.
+        ///
+        [JsonProperty("payment_request_metadata")]
+        public IDictionary<String, String> PaymentRequestMetadata { get; set; }
+
+        ///
+        /// A Direct Debit scheme. Currently "ach", "autogiro", "bacs", "becs",
+        /// "becs_nz", "betalingsservice", "pad" and "sepa_core" are supported.
+        ///
+        [JsonProperty("payment_request_scheme")]
+        public string PaymentRequestScheme { get; set; }
+
+        ///
+        /// URL that the payer can be redirected to after completing the request
+        /// flow.
+        ///
+        [JsonProperty("redirect_uri")]
+        public string RedirectUri { get; set; }
+    }
+
     ///
     /// An API response for a request returning a single billing request template.
     ///


fixes crash when disconnecting from an unready network

--- Handle.WPF/Handle.WPF/ViewModels/IrcMainViewModel.cs
+++ Handle.WPF/Handle.WPF/ViewModels/IrcMainViewModel.cs
@@ -28,6 +28,7 @@
   using Caliburn.Micro;
   using System.Collections.Generic;
   using System.Windows.Input;
+  using System;

   /// <summary>
   /// Represents a ViewModel for IrcMainViews
@@ -55,7 +56,14 @@
         }
       }
       this.Networks.Remove(sender as IrcNetworkViewModel);
-      (sender as IrcNetworkViewModel).Client.Disconnect();
+      try
+      {
+        (sender as IrcNetworkViewModel).Client.Disconnect();
+      }
+      catch (Exception ex)
+      {
+        Console.WriteLine(ex.ToString());
+      }
       // TODO Wait with the close
     }
   }


added section name, section order, property order to /api/createnewasset/{id}

--- HardwhereApi/Controllers/CreateNewAssetController.cs
+++ HardwhereApi/Controllers/CreateNewAssetController.cs
@@ -26,13 +26,15 @@

             var valueTypes = db.ValueTypes.Select(Mapper.Map<ValueTypeDto>).ToDictionary(i => i.Id, j => j);

+            var sections = db.Sections.Select(Mapper.Map<SectionDto>).ToDictionary(i => i.Id, j => j);
+
             var dictionary = new Dictionary<string, object>();
             dictionary["Id"] = 0;
             dictionary["AssetTypeId"] = id;

             foreach (var prop in assetType.TypeProperties)
             {
-                dictionary[prop.PropertyName] = GetPropertyObject(prop, valueTypes);
+                dictionary[prop.PropertyName] = GetPropertyObject(prop, valueTypes, sections);
             }

             return Ok(new DynamicAssetDto(dictionary));
@@ -41,14 +43,19 @@
         private SuperDynamic GetPropertyObject(
             TypeProperty typeProperty,
             Dictionary<int, ValueTypeDto> valueTypes,
+            Dictionary<int, SectionDto> sections,
             object currentAssetPropertyValue = null)
         {
             var currentValueType = valueTypes[typeProperty.ValueTypeId];
+            var currentSection = sections[typeProperty.SectionId];
             var dictionary = new Dictionary<string, object>();
             dictionary["Value"] = currentAssetPropertyValue;
             dictionary["Type"] = currentValueType.Name;
             dictionary["Regex"] = currentValueType.Regex;
             dictionary["ErrorMessage"] = currentValueType.ErrorMessage;
+            dictionary["PropertyOrder"] = typeProperty.Order;
+            dictionary["SectionName"] = currentSection.Name;
+            dictionary["SectionOrder"] = currentSection.Order;

             return new SuperDynamic(dictionary);
         }


Fix:(temp) add logging around PPIfRestFCed

--- plugins/OsuMemoryEventSource/RawMemoryDataProcessor.cs
+++ plugins/OsuMemoryEventSource/RawMemoryDataProcessor.cs
@@ -4,6 +4,7 @@
 using CollectionManager.Enums;
 using OppaiSharp;
 using OsuMemoryDataProvider;
+using StreamCompanionTypes.DataTypes;
 using Beatmap = StreamCompanionTypes.DataTypes.Beatmap;
 using Mods = OppaiSharp.Mods;

@@ -46,43 +47,65 @@
             catch (FileNotFoundException) { }
         }

+        private bool PPIfRestFCedExceptionLogged = false;
         public double PPIfRestFCed()
         {
             if (_preprocessedBeatmap == null)
                 return double.NaN;
-            Accuracy accCalc;
+            try
+            {
+                Accuracy accCalc;

-            PPv2 ppCalculator;
-            if (Play.Time <= 0)
-            {
-                accCalc = new Accuracy(100d, _preprocessedBeatmap.Objects.Count, 0);
-                ppCalculator = new PPv2(new PPv2Parameters(_preprocessedBeatmap, accCalc.Count100,
-                    accCalc.Count50, accCalc.CountMiss, -1, accCalc.Count300, _currentMods));
+                PPv2 ppCalculator;
+                if (Play.Time <= 0)
+                {
+                    accCalc = new Accuracy(100d, _preprocessedBeatmap.Objects.Count, 0);
+                    ppCalculator = new PPv2(new PPv2Parameters(_preprocessedBeatmap, accCalc.Count100,
+                        accCalc.Count50, accCalc.CountMiss, -1, accCalc.Count300, _currentMods));
+                    return ppCalculator.Total;
+                }
+
+                _preprocessedBeatmap.ResetCut();
+
+                //Calculate how much objects we can get starting from current Time
+                _preprocessedBeatmap.Cut(Play.Time, 100000000);
+                var c300Left = _preprocessedBeatmap.GetMaxComboSafe(true);
+                var comboLeft = _preprocessedBeatmap.GetMaxComboSafe();
+
+                var newMaxCombo = Math.Max(Play.MaxCombo, comboLeft + Play.Combo);
+                var newC300Count = Play.C300 + c300Left;
+
+                _preprocessedBeatmap.ResetCut();
+                if (newC300Count < 0)
+                    newC300Count = 0;
+
+                accCalc = new Accuracy(newC300Count, Play.C100, Play.C50, Play.CMiss);
+                _accIfRestFced = accCalc.Value() * 100;
+
+                ppCalculator = new PPv2(new PPv2Parameters(_preprocessedBeatmap, Play.C100,
+                    Play.C50, Play.CMiss, newMaxCombo, newC300Count, _currentMods));
                 return ppCalculator.Total;
             }
+            catch (ArgumentException e)
+            {
+                if (!PPIfRestFCedExceptionLogged)
+                {
+                    PPIfRestFCedExceptionLogged = true;
+                    e.Data.Add("playData", PlayDataToString(Play));
+                    e.Data.Add("mapID", _currentBeatmap?.MapId);
+                    e.Data.Add("mapHash", _currentBeatmap?.Md5);
+                    OsuMemoryEventSourceBase.Logger?.Log(e, LogLevel.Error);
+                }
+            }

-            _preprocessedBeatmap.ResetCut();
-
-            //Calculate how much objects we can get starting from current Time
-            _preprocessedBeatmap.Cut(Play.Time, 100000000);
-            var c300Left = _preprocessedBeatmap.GetMaxComboSafe(true);
-            var comboLeft = _preprocessedBeatmap.GetMaxComboSafe();
-
-            var newMaxCombo = Math.Max(Play.MaxCombo, comboLeft + Play.Combo);
-            var newC300Count = Play.C300 + c300Left;
-
-            _preprocessedBeatmap.ResetCut();
-            if (newC300Count < 0)
-                newC300Count = 0;
-
-            accCalc = new Accuracy(newC300Count, Play.C100, Play.C50, Play.CMiss);
-            _accIfRestFced = accCalc.Value() * 100;
-
-            ppCalculator = new PPv2(new PPv2Parameters(_preprocessedBeatmap, Play.C100,
-                    Play.C50, Play.CMiss, newMaxCombo, newC300Count, _currentMods));
-            return ppCalculator.Total;
+            return Double.NaN;
         }
-
+        private string PlayDataToString(PlayContainer p)
+        {
+            return $"{p.C300}/{p.C100}/{p.C50}/{p.CMiss}|"+
+                   $"acc:{p.Acc},combo: {p.Combo},maxCombo {p.MaxCombo}|" +
+                   $"time: {p.Time}";
+        }
         public double AimPPIfBeatmapWouldEndNow { get; private set; } = double.NaN;
         public double SpeedPPIfBeatmapWouldEndNow { get; private set; } = double.NaN;
         public double AccPPIfBeatmapWouldEndNow { get; private set; } = double.NaN;


logic fix

logic fix

--- JabberBCIT/JabberBCIT/Controllers/ForumController.cs
+++ JabberBCIT/JabberBCIT/Controllers/ForumController.cs
@@ -81,7 +81,7 @@
                 {
                     // the userid associated with this comment is the
                     // user of the parent comment's id
-                    UserID = db.Users.Find(db.Comments.Find(comment.ParentCommentID)).Id,
+                    UserID = db.Comments.Find(comment.ParentCommentID).User.Id,
                     ObjectID = comment.CommentID,
                     Type = "Comment",
                 });


AsyncRWLock: tests updated

AsyncRWLock: tests updated

--- Tests/AsyncRWLockTests.cs
+++ Tests/AsyncRWLockTests.cs
@@ -17,10 +17,19 @@

 		private static void AssertCounters(AsyncRWLock rwLock, int currentReadCount, int waitingReadCount, bool writerIsActive, int waitingWriteCount)
 		{
-			Assert.AreEqual(currentReadCount,rwLock.CurrentReadCount);
-			Assert.AreEqual(waitingReadCount,rwLock.WaitingReadCount);
-			Assert.AreEqual(writerIsActive,rwLock.WriterIsActive);
-			Assert.AreEqual(waitingWriteCount,rwLock.WaitingWriteCount);
+			var currentReadCountActual=rwLock.CurrentReadCount;
+			var waitingReadCountActual=rwLock.WaitingReadCount;
+			var writerIsActiveActual=rwLock.WriterIsActive;
+			var waitingWriteCountActual=rwLock.WaitingWriteCount;
+
+			if(currentReadCountActual!=currentReadCount)
+				throw new Exception(string.Format("Expected CurrentReadCount is {0}, but actual is {1} ",currentReadCount,currentReadCountActual));
+			if(waitingReadCountActual!=waitingReadCount)
+				throw new Exception(string.Format("Expected WaitingReadCount is {0}, but actual is {1} ",waitingReadCount,waitingReadCountActual));
+			if(writerIsActiveActual!=writerIsActive)
+				throw new Exception(string.Format("Expected WriterIsActive is {0}, but actual is {1} ",writerIsActive,writerIsActiveActual));
+			if(waitingWriteCountActual!=waitingWriteCount)
+				throw new Exception(string.Format("Expected WaitingWriteCount is {0}, but actual is {1} ",waitingWriteCount,waitingWriteCountActual));
 		}

 		[Test]


IStyle.cs    icon verwendet    fontsize verwendet     stable

--- BBT/IStyle.cs
+++ BBT/IStyle.cs
@@ -4,6 +4,7 @@
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Windows.Media.Imaging;

 namespace BBT
 {
@@ -18,8 +19,11 @@
         Tuple<Color, bool> getColor();
         void setColor(Tuple<Color, bool> color);

-        void setICon(System.Drawing.Bitmap icon);
-        System.Drawing.Bitmap getIcon();
+        void setICon(BitmapImage icon);
+        BitmapImage getIcon();
+
+        void setFontsize(int fontSize);
+        double getFontsize();

         void isActivated(bool active);


Made the max size get changed after the text widget is done getting its size

--- MatterControlLib/PartPreviewWindow/MainViewWidget.cs
+++ MatterControlLib/PartPreviewWindow/MainViewWidget.cs
@@ -832,7 +832,8 @@

 			UpadetMaxWidth();

-			textWidget.TextChanged += (s, e) => UpadetMaxWidth();
+			// delay this for an update so that the layout of the text widget has happened and its size has been updated.
+			textWidget.TextChanged += (s, e) => UiThread.RunOnIdle(UpadetMaxWidth);

 			void UpadetMaxWidth()
 			{
@@ -851,7 +852,7 @@
 				}

 				partTab.MaximumSize = new Vector2(width, partTab.MaximumSize.Y);
-				partTab.Parent.Width = partTab.Width - 1;
+				partTab.Width = partTab.Width - 1;
 			}

 			partTab.HAnchor = HAnchor.Stretch;


Tag exceptions that most likely cause crashes

--- Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs
+++ Mindscape.Raygun4Net.Xamarin.Android/RaygunClient.cs
@@ -307,7 +307,7 @@
     {
       if (e.ExceptionObject is Exception)
       {
-        _client.Send(e.ExceptionObject as Exception);
+        _client.Send((e.ExceptionObject as Exception), new List<string>(){ "UnhandledException" });
       }
     }

@@ -315,7 +315,7 @@
     {
       if (e.Exception != null)
       {
-        _client.Send(e.Exception);
+        _client.Send(e.Exception, new List<string>() { "UnhandledException" });
       }
     }


Remove debug logs

Remove debug logs

--- OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs
+++ OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs
@@ -182,11 +182,11 @@
                 for (int i = 0; i < DisplayConfig.GetNumDisplayInputs(); i++)
                 {
                     OSVR.ClientKit.DisplayDimensions surfaceDisplayDimensions = DisplayConfig.GetDisplayDimensions((byte)i);
+
                     TotalDisplayWidth += (uint)surfaceDisplayDimensions.Width; //add up the width of each eye
                     TotalDisplayHeight = (uint)surfaceDisplayDimensions.Height; //store the height -- this shouldn't change
                 }
-                Debug.Log("Total Display Width is " + TotalDisplayWidth);
-                Debug.Log("Total Display Height is " + TotalDisplayHeight);
+
                 Screen.SetResolution((int)TotalDisplayWidth, (int)TotalDisplayHeight, false);
             }


Doch noch beim Löschen das Item aus der Liste entfernen

--- OctoAwesome/OctoAwesome.Client/Screens/LoadScreen.cs
+++ OctoAwesome/OctoAwesome.Client/Screens/LoadScreen.cs
@@ -96,6 +96,8 @@
                     return;

                 ResourceManager.Instance.DeleteUniverse(levelList.SelectedItem.Id);
+                levelList.Items.Remove(levelList.SelectedItem);
+                levelList.SelectedItem = null;
                 levelList.InvalidateDimensions();
                 SettingsManager.Set("LastUniverse", "");
             };


update

update

--- OpenGLviaCSharp/fuluDd00_LayeredEngraving/Program.cs
+++ OpenGLviaCSharp/fuluDd00_LayeredEngraving/Program.cs
@@ -16,7 +16,7 @@
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.Run(new FormEngraving());
-            Application.Run(new FormVolumeRendering());
+            //Application.Run(new FormVolumeRendering());
         }
     }
 }


slight progress-parser-improvement

slight progress-parser-improvement

--- OpenQuoridorFramework/OQF.Utils/ParseProgressText.cs
+++ OpenQuoridorFramework/OQF.Utils/ParseProgressText.cs
@@ -10,7 +10,8 @@
 			var result = new List<string>();

 			var lines = fileText.Split('\n')
-								.Select(element => element.Trim());
+								.Select(element => element.Trim())
+								.Where(line => !line.StartsWith("#"));

 			var currentLineNumber = 0;


Clean up

Clean up

--- src/ncore-test1/Startup.cs
+++ src/ncore-test1/Startup.cs
@@ -12,8 +12,6 @@
 {
     public class Startup
     {
-        // This method gets called by the runtime. Use this method to add services to the container.
-        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
         public void ConfigureServices(IServiceCollection services)
         {
         }


Fix bugs in the sending of compressed updates in the new way it processes updates.

--- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3758,36 +3758,17 @@
                     }
                     else if (!canUseImproved)
                     {
+                        ISceneChildEntity cEntity = (ISceneChildEntity)entity;
                         compressedUpdates.Add (update);
                         //We are sending a compressed, which the client will save, add it to the cache
-                        module.AddCachedObject (AgentId, entity.LocalId, ((ISceneChildEntity)entity).CRC);
+                        module.AddCachedObject (AgentId, entity.LocalId, cEntity.CRC);
                         CompressedFlags Flags = CompressedFlags.None;
                         if (updateFlags == PrimUpdateFlags.FullUpdate || updateFlags == PrimUpdateFlags.FindBest)
                         {
                             //Add the defaults
                             updateFlags = PrimUpdateFlags.None;
-
-                            //Must send these as well
-                            if (((ISceneChildEntity)entity).Text != "")
-                                updateFlags |= PrimUpdateFlags.Text;
-                            if (((ISceneChildEntity)entity).AngularVelocity != Vector3.Zero)
-                                updateFlags |= PrimUpdateFlags.AngularVelocity;
-                            if (((ISceneChildEntity)entity).TextureAnimation != null && ((SceneObjectPart)entity).TextureAnimation.Length != 0)
-                                updateFlags |= PrimUpdateFlags.TextureAnim;
-                            if (((ISceneChildEntity)entity).Sound != UUID.Zero)
-                                updateFlags |= PrimUpdateFlags.Sound;
-                            if (((ISceneChildEntity)entity).ParticleSystem != null && ((SceneObjectPart)entity).ParticleSystem.Length != 0)
-                                updateFlags |= PrimUpdateFlags.Particles;
-                            if (((ISceneChildEntity)entity).MediaUrl != "" && ((SceneObjectPart)entity).MediaUrl != null)
-                                updateFlags |= PrimUpdateFlags.MediaURL;
-                            if (((ISceneChildEntity)entity).ParentEntity.RootChild.IsAttachment)
-                                updateFlags |= PrimUpdateFlags.AttachmentPoint;
-
-                            //Make sure that we send this! Otherwise, the client will only see one prim
-                            if (((ISceneChildEntity)entity).ParentEntity != null)
-                                if (((ISceneChildEntity)entity).ParentEntity.ChildrenEntities ().Count != 1)
-                                    updateFlags |= PrimUpdateFlags.ParentID;
                         }
+
                         updateFlags |= PrimUpdateFlags.ClickAction;
                         updateFlags |= PrimUpdateFlags.ExtraData;
                         updateFlags |= PrimUpdateFlags.Shape;
@@ -3798,7 +3779,28 @@
                         updateFlags |= PrimUpdateFlags.Position;
                         updateFlags |= PrimUpdateFlags.AngularVelocity;

-                        if (updateFlags.HasFlag (PrimUpdateFlags.Text) && ((ISceneChildEntity)entity).ParentEntity.RootChild.Text == "")
+                        //Must send these as well
+                        if (cEntity.Text != "")
+                            updateFlags |= PrimUpdateFlags.Text;
+                        if (cEntity.AngularVelocity != Vector3.Zero)
+                            updateFlags |= PrimUpdateFlags.AngularVelocity;
+                        if (cEntity.TextureAnimation != null && cEntity.TextureAnimation.Length != 0)
+                            updateFlags |= PrimUpdateFlags.TextureAnim;
+                        if (cEntity.Sound != UUID.Zero)
+                            updateFlags |= PrimUpdateFlags.Sound;
+                        if (cEntity.ParticleSystem != null && cEntity.ParticleSystem.Length != 0)
+                            updateFlags |= PrimUpdateFlags.Particles;
+                        if (cEntity.MediaUrl != "" && cEntity.MediaUrl != null)
+                            updateFlags |= PrimUpdateFlags.MediaURL;
+                        if (cEntity.ParentEntity.RootChild.IsAttachment)
+                            updateFlags |= PrimUpdateFlags.AttachmentPoint;
+
+                        //Make sure that we send this! Otherwise, the client will only see one prim
+                        if (cEntity.ParentEntity != null)
+                            if (cEntity.ParentEntity.ChildrenEntities ().Count != 1)
+                                updateFlags |= PrimUpdateFlags.ParentID;
+
+                        if (updateFlags.HasFlag (PrimUpdateFlags.Text) && cEntity.Text == "")
                             updateFlags &= ~PrimUpdateFlags.Text; //Remove the text flag if we don't have text!

                         if (updateFlags.HasFlag (PrimUpdateFlags.AngularVelocity))
@@ -3815,7 +3817,7 @@
                             Flags |= CompressedFlags.HasText;
                         if (updateFlags.HasFlag (PrimUpdateFlags.TextureAnim))
                             Flags |= CompressedFlags.TextureAnimation;
-                        if (updateFlags.HasFlag (PrimUpdateFlags.NameValue) || ((ISceneChildEntity)entity).IsAttachment)
+                        if (updateFlags.HasFlag (PrimUpdateFlags.NameValue) || cEntity.IsAttachment)
                             Flags |= CompressedFlags.HasNameValues;

                         compressedUpdates.Add (update);


Improved the redirect validation of the Auth Server

Improved the redirect validation of the Auth Server to cater mutiple
tenants

--- PlatformProject.AuthServer/App_Start/Startup.Auth.cs
+++ PlatformProject.AuthServer/App_Start/Startup.Auth.cs
@@ -83,13 +83,8 @@
             }
             else if (context.ClientId == Clients.ImplicitGrantClient.Id)
             {
-                foreach (var redirectUrl in Clients.ImplicitGrantClient.RedirectUrls)
-                {
-                    if (context.Validated(redirectUrl))
-                    {
-                        break;
-                    }
-                }
+                // Note: This validation can be extended to validate the actual redirect url of the client
+                context.Validated();
             }
             return Task.FromResult(0);
         }


Fixed an ability exception when leveling to high levels

--- PlayerModels/StatCalculations/ClassStatCalculator.cs
+++ PlayerModels/StatCalculations/ClassStatCalculator.cs
@@ -60,7 +60,7 @@
             {
                 if (ccm.className == className)
                 {
-                    if (ccm.lvl % 2 == 1)
+                    if (ccm.lvl % 2 == 1 && abilities.Count < ((ccm.lvl - 1) / 2))
                     {
                         return cm.name + " has learned " + abilities[(ccm.lvl - 1) / 2].name + ".  " + abilities[(ccm.lvl - 1) / 2].description;
                     }


Fixed issues when pasting a copied layer multiple times

--- Project-Aurora/Settings/Control_LayerManager.xaml.cs
+++ Project-Aurora/Settings/Control_LayerManager.xaml.cs
@@ -260,7 +260,7 @@
                     Global.Clipboard = (this.lstLayers.SelectedItem as Layer)?.Clone();
                 else if (e.Key == Key.V && Global.Clipboard is Layer)
                 {
-                    Layer lyr = (Layer)Global.Clipboard;
+                    Layer lyr = (Layer)((Layer)Global.Clipboard)?.Clone();

                     if (FocusedProfile.AvailableLayers.Contains(lyr.Handler.Type))
                     {


minor: correct method name in comment

minor: correct method name in comment

--- OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1355,7 +1355,7 @@
         private bool WaitForUpdateAgent(IClientAPI client)
         {
             // Before the source region executes UpdateAgent
-            // (which triggers Scene.IncomingChildAgentDataUpdate(AgentData cAgentData) here in the destination,
+            // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination,
             // m_originRegionID is UUID.Zero; after, it's non-Zero.  The CompleteMovement sequence initiated from the
             // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero
             int count = 50;


Locking the priority queue to see if it gets pass that exception.

--- OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
@@ -77,7 +77,8 @@
                 J2KImage imgrequest;

                 // Do a linear search for this texture download
-                m_priorityQueue.Find(delegate(J2KImage img) { return img.m_requestedUUID == newRequest.RequestedAssetID; }, out imgrequest);
+                lock (m_priorityQueue)
+                    m_priorityQueue.Find(delegate(J2KImage img) { return img.m_requestedUUID == newRequest.RequestedAssetID; }, out imgrequest);

                 if (imgrequest != null)
                 {
@@ -85,7 +86,11 @@
                     {
                         //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID);

-                        try { m_priorityQueue.Delete(imgrequest.m_priorityQueueHandle); }
+                        try
+                        {
+                            lock (m_priorityQueue)
+                                m_priorityQueue.Delete(imgrequest.m_priorityQueueHandle);
+                        }
                         catch (Exception) { }
                     }
                     else
@@ -108,8 +113,17 @@

                             //Update the requested priority
                             imgrequest.m_requestedPriority = newRequest.Priority;
-                            try { m_priorityQueue.Replace(imgrequest.m_priorityQueueHandle, imgrequest); }
-                            catch (Exception) { imgrequest.m_priorityQueueHandle = null; m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest); }
+                            try
+                            {
+                                lock (m_priorityQueue)
+                                    m_priorityQueue.Replace(imgrequest.m_priorityQueueHandle, imgrequest);
+                            }
+                            catch (Exception)
+                            {
+                                imgrequest.m_priorityQueueHandle = null;
+                                lock (m_priorityQueue)
+                                    m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest);
+                            }

                             //Run an update
                             imgrequest.RunUpdate();
@@ -152,7 +166,8 @@
                         imgrequest.m_requestedPriority = newRequest.Priority;

                         //Add this download to the priority queue
-                        m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest);
+                        lock (m_priorityQueue)
+                            m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest);

                         //Run an update
                         imgrequest.RunUpdate();
@@ -212,7 +227,9 @@
             {
                 while (m_priorityQueue.Count > 0)
                 {
-                    J2KImage imagereq = m_priorityQueue.FindMax();
+                    J2KImage imagereq = null;
+                    lock (m_priorityQueue)
+                        imagereq = m_priorityQueue.FindMax();

                     if (imagereq.m_decoded == true)
                     {
@@ -230,7 +247,11 @@
                         if (imagereq.SendPackets(m_client, maxpack))
                         {
                             // Send complete. Destroy any knowledge of this transfer
-                            try { m_priorityQueue.Delete(imagereq.m_priorityQueueHandle); }
+                            try
+                            {
+                                lock (m_priorityQueue)
+                                    m_priorityQueue.Delete(imagereq.m_priorityQueueHandle);
+                            }
                             catch (Exception) { }
                         }
                     }


BulletSim: increase default value of AvatarStopZeroThreshold as this reduces the occurance of stopped avatar drifting in the viewer. Not sure why but this is a short term fix while investigation continues.

--- OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
+++ OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
@@ -633,7 +633,7 @@
 	    new ParameterDefn<float>("AvatarAddForcePushFactor", "BSCharacter.AddForce is multiplied by this and mass to be like other physics engines",
             0.315f ),
 	    new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
-            0.1f,
+            0.4f,
             (s) => { return (float)AvatarStopZeroThreshold; },
             (s,v) => { AvatarStopZeroThreshold = v; AvatarStopZeroThresholdSquared = v * v; } ),
 	    new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",


* Tweaking master uuid exception to make it clearer what just went wrong (user server timeout) * Increasing GetUserProfile requests only to 6 seconds from 3 * Not completely sure what effect this will have, though probably not much * At some point one will have to accept that if the grid servers are taking many many seconds to respond, running using that grid will not be viable. * Perhaps there should be a big warning up front if grid request times are slower than n seconds.

--- OpenSim/Region/Communications/OGS1/OGS1UserServices.cs
+++ OpenSim/Region/Communications/OGS1/OGS1UserServices.cs
@@ -106,7 +106,7 @@
             }
             else
             {
-                m_log.Warn("[INTERGRID]: Got invalid queryID from userServer");
+                m_log.Warn("[OGS1 USER SERVICES]: Got invalid queryID from userServer");
             }
             return pickerlist;
         }
@@ -188,13 +188,18 @@
             }
             catch (WebException e)
             {
-                m_log.Warn("Error when trying to fetch Avatar Picker Response: " +
+                m_log.Warn("[OGS1 USER SERVICES]: Error when trying to fetch Avatar Picker Response: " +
                            e.Message);
                 // Return Empty picker list (no results)
             }
             return pickerlist;
         }

+        /// <summary>
+        /// Get a user profile from the user server
+        /// </summary>
+        /// <param name="avatarID"></param>
+        /// <returns>null if the request fails</returns>
         public UserProfileData GetUserProfile(string name)
         {
             try
@@ -204,19 +209,26 @@
                 IList parameters = new ArrayList();
                 parameters.Add(param);
                 XmlRpcRequest req = new XmlRpcRequest("get_user_by_name", parameters);
-                XmlRpcResponse resp = req.Send(m_parent.NetworkServersInfo.UserURL, 3000);
+                XmlRpcResponse resp = req.Send(m_parent.NetworkServersInfo.UserURL, 6000);
                 Hashtable respData = (Hashtable) resp.Value;

                 return ConvertXMLRPCDataToUserProfile(respData);
             }
             catch (WebException e)
             {
-                m_log.Warn("Error when trying to fetch profile data by name from remote user server: " +
-                           e.Message);
-            }
+                m_log.ErrorFormat(
+                    "[OGS1 USER SERVICES]: Error when trying to fetch profile data by name from remote user server: {0}",
+                    e);
+            }
+
             return null;
         }

+        /// <summary>
+        /// Get a user profile from the user server
+        /// </summary>
+        /// <param name="avatarID"></param>
+        /// <returns>null if the request fails</returns>
         public UserProfileData GetUserProfile(LLUUID avatarID)
         {
             try
@@ -226,16 +238,18 @@
                 IList parameters = new ArrayList();
                 parameters.Add(param);
                 XmlRpcRequest req = new XmlRpcRequest("get_user_by_uuid", parameters);
-                XmlRpcResponse resp = req.Send(m_parent.NetworkServersInfo.UserURL, 3000);
+                XmlRpcResponse resp = req.Send(m_parent.NetworkServersInfo.UserURL, 6000);
                 Hashtable respData = (Hashtable) resp.Value;

                 return ConvertXMLRPCDataToUserProfile(respData);
             }
             catch (Exception e)
             {
-                Console.WriteLine("Error when trying to fetch profile data by uuid from remote user server: " +
-                                  e.Message);
-            }
+                m_log.ErrorFormat(
+                    "[OGS1 USER SERVICES]: Error when trying to fetch profile data by uuid from remote user server: {0}",
+                    e);
+            }
+
             return null;
         }

@@ -244,24 +258,40 @@
             // TODO: implement
         }

+        /// <summary>
+        /// Retrieve the user information for the given master uuid.
+        /// </summary>
+        /// <param name="uuid"></param>
+        /// <returns></returns>
         public UserProfileData SetupMasterUser(string firstName, string lastName)
         {
             return SetupMasterUser(firstName, lastName, String.Empty);
         }

+        /// <summary>
+        /// Retrieve the user information for the given master uuid.
+        /// </summary>
+        /// <param name="uuid"></param>
+        /// <returns></returns>
         public UserProfileData SetupMasterUser(string firstName, string lastName, string password)
         {
             UserProfileData profile = GetUserProfile(firstName, lastName);
             return profile;
         }

+        /// <summary>
+        /// Retrieve the user information for the given master uuid.
+        /// </summary>
+        /// <param name="uuid"></param>
+        /// <returns></returns>
         public UserProfileData SetupMasterUser(LLUUID uuid)
         {
             UserProfileData data = GetUserProfile(uuid);

             if (data == null)
             {
-                throw new Exception("[OGS1 USER SERVICES]: Unknown master user " + uuid);
+                throw new Exception(
+                    "Could not retrieve profile for master user " + uuid + ".  User server did not respond to the request.");
             }

             return data;
@@ -497,7 +527,7 @@
             }
             catch (WebException e)
             {
-                m_log.Warn("Error when trying to fetch Avatar's friends list: " +
+                m_log.Warn("[OGS1 USER SERVICES]: Error when trying to fetch Avatar's friends list: " +
                            e.Message);
                 // Return Empty list (no friends)
             }


SharpFileSystem.SharpZipLib: fixed GetEntries resulting in passing the related tests

--- SharpFileSystem.SharpZipLib/SharpZipLibFileSystem.cs
+++ SharpFileSystem.SharpZipLib/SharpZipLibFileSystem.cs
@@ -35,12 +35,13 @@

         protected FileSystemPath ToPath(ZipEntry entry)
         {
-            return FileSystemPath.Parse(entry.Name);
+            return FileSystemPath.Parse(FileSystemPath.DirectorySeparator + entry.Name);
         }

         protected string ToEntryPath(FileSystemPath path)
         {
-            return path.ToString();
+            // Remove heading '/' from path.
+            return path.Path.TrimStart(FileSystemPath.DirectorySeparator);
         }

         protected ZipEntry ToEntry(FileSystemPath path)
@@ -55,7 +56,15 @@

         public ICollection<FileSystemPath> GetEntities(FileSystemPath path)
         {
-            return GetZipEntries().Select(e => ToPath(e)).Where(p => p.ParentPath == path).ToList();
+            return GetZipEntries()
+                .Select(ToPath)
+                .Where(entryPath => path.IsParentOf(entryPath))
+                .Select(entryPath => entryPath.ParentPath == path
+                    ? entryPath
+                    : path.AppendDirectory(entryPath.RemoveParent(path).GetDirectorySegments()[0])
+                    )
+                .Distinct()
+                .ToList();
         }

         public bool Exists(FileSystemPath path)


Readds mac banning and viewer banning. This got lost sometime a long time ago.

--- OpenSim/Server/Handlers/Login/LLLoginHandlers.cs
+++ OpenSim/Server/Handlers/Login/LLLoginHandlers.cs
@@ -80,6 +80,25 @@
                         clientVersion = requestData["version"].ToString();
                     // We should do something interesting with the client version...

+                    //MAC BANNING START
+                    string mac = (string)requestData["mac"];
+                    Aurora.Framework.IGenericData GD = Aurora.DataManager.DataManager.GetDefaultGenericPlugin();
+                    if (GD.Query("macAddress",mac,"macban","*")[0] == mac)
+                    {
+                        m_log.InfoFormat("Mac is in the list");
+                        return new XmlRpcResponse();
+                    }
+                    //MAC BANNING END
+
+                    //Viewer Ban Start
+
+                    if (GD.Query("Client", clientVersion, "BannedViewers", "*")[0] == clientVersion)
+                    {
+                        return new XmlRpcResponse();
+                    }
+
+                    //Viewer ban end
+
                     m_log.InfoFormat("[LOGIN]: XMLRPC Login Requested for {0} {1}, starting in {2}, using {3}", first, last, startLocation, clientVersion);

                     LoginResponse reply = null;


One more buglet related to the issue at hand.

--- OpenSim/Services/HypergridService/GatekeeperService.cs
+++ OpenSim/Services/HypergridService/GatekeeperService.cs
@@ -73,7 +73,7 @@
                     throw new Exception(String.Format("No section GatekeeperService in config file"));

                 string accountService = serverConfig.GetString("UserAccountService", String.Empty);
-                string homeUsersService = serverConfig.GetString("HomeUsersSecurityService", string.Empty);
+                string homeUsersService = serverConfig.GetString("UserAgentService", string.Empty);
                 string gridService = serverConfig.GetString("GridService", String.Empty);
                 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
                 string simulationService = serverConfig.GetString("SimulationService", String.Empty);