Fix the save of attachments in Avatar Archive

--- Aurora/Modules/Archivers/AppearanceArchiver.cs
+++ Aurora/Modules/Archivers/AppearanceArchiver.cs
@@ -1,372 +1,373 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Reflection;
-using System.Text;
-using OpenSim.Framework;
-using OpenSim.Framework.Serialization.External;
-using OpenSim.Region.Framework.Scenes;
-using OpenSim.Region.Framework.Interfaces;
-using OpenSim.Services.Interfaces;
-using OpenMetaverse;
-using OpenMetaverse.StructuredData;
-using log4net;
-using Aurora.Framework;
-
-namespace Aurora.Modules
-{
-    /// <summary>
-    /// This module loads/saves the avatar's appearance from/down into an "Avatar Archive", also known as an AA.
-    /// </summary>
-    public class AuroraAvatarAppearanceArchiver : ISharedRegionModule, IAvatarAppearanceArchiver
-	{
-		private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-		private Scene m_scene;
-        private IInventoryService InventoryService;
-        private IAssetService AssetService;
-        private IUserAccountService UserAccountService;
-        private IAvatarService AvatarService;
-
-        public void Initialise(Nini.Config.IConfigSource source)
-        {
-		}
-
-        public void AddRegion(Scene scene)
-        {
-            if (m_scene == null)
-                m_scene = scene;
-
-            MainConsole.Instance.Commands.AddCommand("region", false, "save avatar archive", "save avatar archive <First> <Last> <Filename> <FolderNameToSaveInto>", "Saves appearance to an avatar archive archive (Note: put \"\" around the FolderName if you need more than one word)", HandleSaveAvatarArchive);
-            MainConsole.Instance.Commands.AddCommand("region", false, "load avatar archive", "load avatar archive <First> <Last> <Filename>", "Loads appearance from an avatar archive archive", HandleLoadAvatarArchive);
-        }
-
-        public void RemoveRegion(Scene scene)
-        {
-
-        }
-
-        public void RegionLoaded(Scene scene)
-        {
-            InventoryService = m_scene.InventoryService;
-            AssetService = m_scene.AssetService;
-            UserAccountService = m_scene.UserAccountService;
-            AvatarService = m_scene.AvatarService;
-        }
-
-        public Type ReplaceableInterface
-        {
-            get { return null; }
-        }
-
-        public void PostInitialise() { }
-
-		public void Close()
-		{
-		}
-
-		public string Name
-        {
-			get { return "AuroraAvatarArchiver"; }
-		}
-
-		public bool IsSharedModule
-        {
-			get { return true; }
-		}
-
-		protected void HandleLoadAvatarArchive(string module, string[] cmdparams)
-		{
-			if (cmdparams.Length != 6) {
-                m_log.Info("[AvatarArchive] Not enough parameters!");
-				return;
-			}
-			LoadAvatarArchive(cmdparams[5], cmdparams[3] + " " + cmdparams[4]);
-		}
-
-        public void LoadAvatarArchive(string FileName, string Name)
-        {
-            UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, Name);
-            m_log.Info("[AvatarArchive] Loading archive from " + FileName);
-            if (account == null)
-            {
-                m_log.Error("[AvatarArchive] User not found!");
-                return;
-            }
-
-            StreamReader reader = new StreamReader(FileName);
-            string file = reader.ReadToEnd();
-            reader.Close();
-            reader.Dispose();
-
-            IScenePresence SP;
-            m_scene.TryGetScenePresence(account.PrincipalID, out SP);
-            if (SP == null)
-                return; //Bad people!
-
-            SP.ControllingClient.SendAlertMessage("Appearance loading in progress...");
-
-            string FolderNameToLoadInto = "";
-
-            OSDMap map = ((OSDMap)OSDParser.DeserializeLLSDXml(file));
-
-            OSDMap assetsMap = ((OSDMap)map["Assets"]);
-            OSDMap itemsMap = ((OSDMap)map["Items"]);
-            OSDMap bodyMap = ((OSDMap)map["Body"]);
-
-            AvatarAppearance appearance = ConvertXMLToAvatarAppearance(bodyMap, out FolderNameToLoadInto);
-
-            appearance.Owner = account.PrincipalID;
-
-            List<InventoryItemBase> items = new List<InventoryItemBase>();
-
-            InventoryFolderBase AppearanceFolder = InventoryService.GetFolderForType(account.PrincipalID, AssetType.Clothing);
-
-            InventoryFolderBase folderForAppearance
-                = new InventoryFolderBase(
-                    UUID.Random(), FolderNameToLoadInto, account.PrincipalID,
-                    -1, AppearanceFolder.ID, 1);
-
-            InventoryService.AddFolder(folderForAppearance);
-
-            folderForAppearance = InventoryService.GetFolder(folderForAppearance);
-
-            try
-            {
-                LoadAssets(assetsMap);
-                LoadItems(itemsMap, account.PrincipalID, folderForAppearance, out items);
-            }
-            catch (Exception ex)
-            {
-                m_log.Warn("[AvatarArchiver]: Error loading assets and items, " + ex.ToString());
-            }
-
-            //Now update the client about the new items
-            SP.ControllingClient.SendBulkUpdateInventory(folderForAppearance);
-            foreach (InventoryItemBase itemCopy in items)
-            {
-                if (itemCopy == null)
-                {
-                    SP.ControllingClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
-                    continue;
-                }
-                if (!SP.IsChildAgent)
-                {
-                    SP.ControllingClient.SendBulkUpdateInventory(itemCopy);
-                }
-            }
-            m_log.Info("[AvatarArchive] Loaded archive from " + FileName);
-        }
-
-        private InventoryItemBase GiveInventoryItem(UUID senderId, UUID recipient, InventoryItemBase item, InventoryFolderBase parentFolder)
-        {
-            InventoryItemBase itemCopy = new InventoryItemBase();
-            itemCopy.Owner = recipient;
-            itemCopy.CreatorId = item.CreatorId;
-            itemCopy.ID = UUID.Random();
-            itemCopy.AssetID = item.AssetID;
-            itemCopy.Description = item.Description;
-            itemCopy.Name = item.Name;
-            itemCopy.AssetType = item.AssetType;
-            itemCopy.InvType = item.InvType;
-            itemCopy.Folder = UUID.Zero;
-
-            //Give full permissions for them
-            itemCopy.NextPermissions = (uint)PermissionMask.All;
-            itemCopy.GroupPermissions = (uint)PermissionMask.All;
-            itemCopy.EveryOnePermissions = (uint)PermissionMask.All;
-            itemCopy.CurrentPermissions = (uint)PermissionMask.All;
-
-            if (parentFolder == null)
-            {
-                InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
-
-                if (folder != null)
-                    itemCopy.Folder = folder.ID;
-                else
-                {
-                    InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
-
-                    if (root != null)
-                        itemCopy.Folder = root.ID;
-                    else
-                        return null; // No destination
-                }
-            }
-            else
-                itemCopy.Folder = parentFolder.ID; //We already have a folder to put it in
-
-            itemCopy.GroupID = UUID.Zero;
-            itemCopy.GroupOwned = false;
-            itemCopy.Flags = item.Flags;
-            itemCopy.SalePrice = item.SalePrice;
-            itemCopy.SaleType = item.SaleType;
-
-            InventoryService.AddItem(itemCopy);
-            return itemCopy;
-        }
-
-        private AvatarAppearance ConvertXMLToAvatarAppearance(OSDMap map, out string FolderNameToPlaceAppearanceIn)
-        {
-            AvatarAppearance appearance = new AvatarAppearance();
-            appearance.Unpack(map);
-            FolderNameToPlaceAppearanceIn = map["FolderName"].AsString();
-            return appearance;
-        }
-
-        protected void HandleSaveAvatarArchive(string module, string[] cmdparams)
-        {
-            if (cmdparams.Length != 7)
-            {
-                m_log.Info("[AvatarArchive] Not enough parameters!");
-            }
-            UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, cmdparams[3] + " " + cmdparams[4]);
-            if (account == null)
-            {
-                m_log.Error("[AvatarArchive] User not found!");
-                return;
-            }
-
-            IScenePresence SP;
-            m_scene.TryGetScenePresence(account.PrincipalID, out SP);
-            if (SP == null)
-                return; //Bad people!
-            SP.ControllingClient.SendAlertMessage("Appearance saving in progress...");
-
-            AvatarAppearance appearance = AvatarService.GetAppearance(SP.UUID);
-            if (appearance == null)
-            {
-                IAvatarAppearanceModule appearancemod = SP.RequestModuleInterface<IAvatarAppearanceModule> ();
-                appearance = appearancemod.Appearance;
-            }
-            StreamWriter writer = new StreamWriter(cmdparams[5], false);
-            OSDMap map = new OSDMap();
-            OSDMap body = new OSDMap();
-            OSDMap assets = new OSDMap();
-            OSDMap items = new OSDMap();
-            body = appearance.Pack();
-            body.Add("FolderName", OSD.FromString(cmdparams[6]));
-
-            foreach (AvatarWearable wear in appearance.Wearables)
-            {
-                for (int i = 0; i < wear.Count; i++)
-                {
-                    WearableItem w = wear[i];
-                    if (w.AssetID != UUID.Zero)
-                    {
-                        SaveAsset(w.AssetID, assets);
-                        SaveItem(w.ItemID, items);
-                    }
-                }
-            }
-            List<AvatarAttachment> attachments = appearance.GetAttachments();
-            foreach (AvatarAttachment a in attachments)
-            {
-                SaveAsset(a.AssetID, assets);
-                SaveItem(a.ItemID, items);
-            }
-            map.Add("Body", body);
-            map.Add("Assets", assets);
-            map.Add("Items", items);
-            //Write the map
-            writer.Write(OSDParser.SerializeLLSDXmlString(map));
-            writer.Close();
-            writer.Dispose();
-            m_log.Info("[AvatarArchive] Saved archive to " + cmdparams[5]);
-        }
-
-        private void SaveAsset(UUID AssetID, OSDMap assetMap)
-        {
-            AssetBase asset = AssetService.Get(AssetID.ToString());
-            if (asset != null)
-            {
-                OSDMap assetData = new OSDMap();
-                m_log.Info("[AvatarArchive]: Saving asset " + asset.ID);
-                CreateMetaDataMap(asset.Metadata, assetData);
-                assetData.Add("AssetData", OSD.FromBinary(asset.Data));
-                assetMap.Add(asset.ID, assetData);
-            }
-            else
-            {
-                m_log.Warn("[AvatarArchive]: Could not find asset to save: " + AssetID.ToString());
-                return;
-            }
-        }
-
-        private void CreateMetaDataMap(AssetMetadata data, OSDMap map)
-        {
-            map["ContentType"] = OSD.FromString(data.ContentType);
-            map["CreationDate"] = OSD.FromDate(data.CreationDate);
-            map["CreatorID"] = OSD.FromString(data.CreatorID);
-            map["Description"] = OSD.FromString(data.Description);
-            map["ID"] = OSD.FromString(data.ID);
-            map["Name"] = OSD.FromString(data.Name);
-            map["Type"] = OSD.FromInteger(data.Type);
-        }
-
-        private AssetBase LoadAssetBase(OSDMap map)
-        {
-            AssetBase asset = new AssetBase();
-            asset.Data = map["AssetData"].AsBinary();
-
-            AssetMetadata md = new AssetMetadata();
-            md.ContentType = map["ContentType"].AsString();
-            md.CreationDate = map["CreationDate"].AsDate();
-            md.CreatorID = map["CreatorID"].AsString();
-            md.Description = map["Description"].AsString();
-            md.ID = map["ID"].AsString();
-            md.Name = map["Name"].AsString();
-            md.Type = (sbyte)map["Type"].AsInteger();
-
-            asset.Metadata = md;
-            asset.ID = md.ID;
-            asset.FullID = UUID.Parse(md.ID);
-            asset.Name = md.Name;
-            asset.Type = md.Type;
-
-            return asset;
-        }
-
-        private void SaveItem(UUID ItemID, OSDMap itemMap)
-        {
-            InventoryItemBase saveItem = InventoryService.GetItem(new InventoryItemBase(ItemID));
-            if (saveItem == null)
-            {
-                m_log.Warn("[AvatarArchive]: Could not find item to save: " + ItemID.ToString());
-                return;
-            }
-            m_log.Info("[AvatarArchive]: Saving item " + ItemID.ToString());
-            string serialization = UserInventoryItemSerializer.Serialize(saveItem);
-            itemMap[ItemID.ToString()] = OSD.FromString(serialization);
-        }
-
-        private void LoadAssets(OSDMap assets)
-        {
-            foreach (KeyValuePair<string, OSD> kvp in assets)
-            {
-                UUID AssetID = UUID.Parse(kvp.Key);
-                OSDMap assetMap = (OSDMap)kvp.Value;
-                AssetBase asset = AssetService.Get(AssetID.ToString());
-                m_log.Info("[AvatarArchive]: Loading asset " + AssetID.ToString());
-                if (asset == null) //Don't overwrite
-                {
-                    asset = LoadAssetBase(assetMap);
-                    AssetService.Store(asset);
-                }
-            }
-        }
-
-        private void LoadItems(OSDMap items, UUID OwnerID, InventoryFolderBase folderForAppearance, out List<InventoryItemBase> litems)
-        {
-            litems = new List<InventoryItemBase>();
-            foreach (KeyValuePair<string, OSD> kvp in items)
-            {
-                string serialization = kvp.Value.AsString();
-                InventoryItemBase item = OpenSim.Framework.Serialization.External.UserInventoryItemSerializer.Deserialize(serialization);
-                m_log.Info("[AvatarArchive]: Loading item " + item.ID.ToString());
-                item = GiveInventoryItem(item.CreatorIdAsUuid, OwnerID, item, folderForAppearance);
-                litems.Add(item);
-            }
-        }
-	}
-}
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using OpenSim.Framework;
+using OpenSim.Framework.Serialization.External;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Services.Interfaces;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using log4net;
+using Aurora.Framework;
+
+namespace Aurora.Modules
+{
+    /// <summary>
+    /// This module loads/saves the avatar's appearance from/down into an "Avatar Archive", also known as an AA.
+    /// </summary>
+    public class AuroraAvatarAppearanceArchiver : ISharedRegionModule, IAvatarAppearanceArchiver
+	{
+		private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+		private Scene m_scene;
+        private IInventoryService InventoryService;
+        private IAssetService AssetService;
+        private IUserAccountService UserAccountService;
+        private IAvatarService AvatarService;
+
+        public void Initialise(Nini.Config.IConfigSource source)
+        {
+		}
+
+        public void AddRegion(Scene scene)
+        {
+            if (m_scene == null)
+                m_scene = scene;
+
+            MainConsole.Instance.Commands.AddCommand("region", false, "save avatar archive", "save avatar archive <First> <Last> <Filename> <FolderNameToSaveInto>", "Saves appearance to an avatar archive archive (Note: put \"\" around the FolderName if you need more than one word. Put all attachments in BodyParts folder before to save the archive)", HandleSaveAvatarArchive);
+            MainConsole.Instance.Commands.AddCommand("region", false, "load avatar archive", "load avatar archive <First> <Last> <Filename>", "Loads appearance from an avatar archive archive", HandleLoadAvatarArchive);
+        }
+
+        public void RemoveRegion(Scene scene)
+        {
+
+        }
+
+        public void RegionLoaded(Scene scene)
+        {
+            InventoryService = m_scene.InventoryService;
+            AssetService = m_scene.AssetService;
+            UserAccountService = m_scene.UserAccountService;
+            AvatarService = m_scene.AvatarService;
+        }
+
+        public Type ReplaceableInterface
+        {
+            get { return null; }
+        }
+
+        public void PostInitialise() { }
+
+		public void Close()
+		{
+		}
+
+		public string Name
+        {
+			get { return "AuroraAvatarArchiver"; }
+		}
+
+		public bool IsSharedModule
+        {
+			get { return true; }
+		}
+
+		protected void HandleLoadAvatarArchive(string module, string[] cmdparams)
+		{
+			if (cmdparams.Length != 6) {
+                m_log.Info("[AvatarArchive] Not enough parameters!");
+				return;
+			}
+			LoadAvatarArchive(cmdparams[5], cmdparams[3] + " " + cmdparams[4]);
+		}
+
+        public void LoadAvatarArchive(string FileName, string Name)
+        {
+            UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, Name);
+            m_log.Info("[AvatarArchive] Loading archive from " + FileName);
+            if (account == null)
+            {
+                m_log.Error("[AvatarArchive] User not found!");
+                return;
+            }
+
+            StreamReader reader = new StreamReader(FileName);
+            string file = reader.ReadToEnd();
+            reader.Close();
+            reader.Dispose();
+
+            IScenePresence SP;
+            m_scene.TryGetScenePresence(account.PrincipalID, out SP);
+            if (SP == null)
+                return; //Bad people!
+
+            SP.ControllingClient.SendAlertMessage("Appearance loading in progress...");
+
+            string FolderNameToLoadInto = "";
+
+            OSDMap map = ((OSDMap)OSDParser.DeserializeLLSDXml(file));
+
+            OSDMap assetsMap = ((OSDMap)map["Assets"]);
+            OSDMap itemsMap = ((OSDMap)map["Items"]);
+            OSDMap bodyMap = ((OSDMap)map["Body"]);
+
+            AvatarAppearance appearance = ConvertXMLToAvatarAppearance(bodyMap, out FolderNameToLoadInto);
+
+            appearance.Owner = account.PrincipalID;
+
+            List<InventoryItemBase> items = new List<InventoryItemBase>();
+
+            InventoryFolderBase AppearanceFolder = InventoryService.GetFolderForType(account.PrincipalID, AssetType.Clothing);
+
+            InventoryFolderBase folderForAppearance
+                = new InventoryFolderBase(
+                    UUID.Random(), FolderNameToLoadInto, account.PrincipalID,
+                    -1, AppearanceFolder.ID, 1);
+
+            InventoryService.AddFolder(folderForAppearance);
+
+            folderForAppearance = InventoryService.GetFolder(folderForAppearance);
+
+            try
+            {
+                LoadAssets(assetsMap);
+                LoadItems(itemsMap, account.PrincipalID, folderForAppearance, out items);
+            }
+            catch (Exception ex)
+            {
+                m_log.Warn("[AvatarArchiver]: Error loading assets and items, " + ex.ToString());
+            }
+
+            //Now update the client about the new items
+            SP.ControllingClient.SendBulkUpdateInventory(folderForAppearance);
+            foreach (InventoryItemBase itemCopy in items)
+            {
+                if (itemCopy == null)
+                {
+                    SP.ControllingClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
+                    continue;
+                }
+                if (!SP.IsChildAgent)
+                {
+                    SP.ControllingClient.SendBulkUpdateInventory(itemCopy);
+                }
+            }
+            m_log.Info("[AvatarArchive] Loaded archive from " + FileName);
+        }
+
+        private InventoryItemBase GiveInventoryItem(UUID senderId, UUID recipient, InventoryItemBase item, InventoryFolderBase parentFolder)
+        {
+            InventoryItemBase itemCopy = new InventoryItemBase();
+            itemCopy.Owner = recipient;
+            itemCopy.CreatorId = item.CreatorId;
+            itemCopy.ID = UUID.Random();
+            itemCopy.AssetID = item.AssetID;
+            itemCopy.Description = item.Description;
+            itemCopy.Name = item.Name;
+            itemCopy.AssetType = item.AssetType;
+            itemCopy.InvType = item.InvType;
+            itemCopy.Folder = UUID.Zero;
+
+            //Give full permissions for them
+            itemCopy.NextPermissions = (uint)PermissionMask.All;
+            itemCopy.GroupPermissions = (uint)PermissionMask.All;
+            itemCopy.EveryOnePermissions = (uint)PermissionMask.All;
+            itemCopy.CurrentPermissions = (uint)PermissionMask.All;
+
+            if (parentFolder == null)
+            {
+                InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
+
+                if (folder != null)
+                    itemCopy.Folder = folder.ID;
+                else
+                {
+                    InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
+
+                    if (root != null)
+                        itemCopy.Folder = root.ID;
+                    else
+                        return null; // No destination
+                }
+            }
+            else
+                itemCopy.Folder = parentFolder.ID; //We already have a folder to put it in
+
+            itemCopy.GroupID = UUID.Zero;
+            itemCopy.GroupOwned = false;
+            itemCopy.Flags = item.Flags;
+            itemCopy.SalePrice = item.SalePrice;
+            itemCopy.SaleType = item.SaleType;
+
+            InventoryService.AddItem(itemCopy);
+            return itemCopy;
+        }
+
+        private AvatarAppearance ConvertXMLToAvatarAppearance(OSDMap map, out string FolderNameToPlaceAppearanceIn)
+        {
+            AvatarAppearance appearance = new AvatarAppearance();
+            appearance.Unpack(map);
+            FolderNameToPlaceAppearanceIn = map["FolderName"].AsString();
+            return appearance;
+        }
+
+        protected void HandleSaveAvatarArchive(string module, string[] cmdparams)
+        {
+            if (cmdparams.Length != 7)
+            {
+                m_log.Info("[AvatarArchive] Not enough parameters!");
+            }
+            UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, cmdparams[3] + " " + cmdparams[4]);
+            if (account == null)
+            {
+                m_log.Error("[AvatarArchive] User not found!");
+                return;
+            }
+
+            IScenePresence SP;
+            m_scene.TryGetScenePresence(account.PrincipalID, out SP);
+            if (SP == null)
+                return; //Bad people!
+            SP.ControllingClient.SendAlertMessage("Appearance saving in progress...");
+
+            AvatarAppearance appearance = AvatarService.GetAppearance(SP.UUID);
+            if (appearance == null)
+            {
+                IAvatarAppearanceModule appearancemod = SP.RequestModuleInterface<IAvatarAppearanceModule> ();
+                appearance = appearancemod.Appearance;
+            }
+            StreamWriter writer = new StreamWriter(cmdparams[5], false);
+            OSDMap map = new OSDMap();
+            OSDMap body = new OSDMap();
+            OSDMap assets = new OSDMap();
+            OSDMap items = new OSDMap();
+            body = appearance.Pack();
+            body.Add("FolderName", OSD.FromString(cmdparams[6]));
+
+            foreach (AvatarWearable wear in appearance.Wearables)
+            {
+                for (int i = 0; i < wear.Count; i++)
+                {
+                    WearableItem w = wear[i];
+                    if (w.AssetID != UUID.Zero)
+                    {
+                        SaveItem(w.ItemID, items, assets);
+                    }
+                }
+            }
+            List<AvatarAttachment> attachments = appearance.GetAttachments();
+            foreach (AvatarAttachment a in attachments)
+            {
+            	if (a.AssetID != UUID.Zero)
+            	{
+                SaveItem(a.ItemID, items, assets);
+                }
+            }
+            map.Add("Body", body);
+            map.Add("Assets", assets);
+            map.Add("Items", items);
+            //Write the map
+            writer.Write(OSDParser.SerializeLLSDXmlString(map));
+            writer.Close();
+            writer.Dispose();
+            m_log.Info("[AvatarArchive] Saved archive to " + cmdparams[5]);
+        }
+
+        private void SaveAsset(UUID AssetID, OSDMap assetMap)
+        {
+            AssetBase asset = AssetService.Get(AssetID.ToString());
+            if (asset != null)
+            {
+                OSDMap assetData = new OSDMap();
+                m_log.Info("[AvatarArchive]: Saving asset " + asset.ID);
+                CreateMetaDataMap(asset.Metadata, assetData);
+                assetData.Add("AssetData", OSD.FromBinary(asset.Data));
+                assetMap.Add(asset.ID, assetData);
+            }
+            else
+            {
+                m_log.Warn("[AvatarArchive]: Could not find asset to save: " + AssetID.ToString());
+                return;
+            }
+        }
+
+        private void CreateMetaDataMap(AssetMetadata data, OSDMap map)
+        {
+            map["ContentType"] = OSD.FromString(data.ContentType);
+            map["CreationDate"] = OSD.FromDate(data.CreationDate);
+            map["CreatorID"] = OSD.FromString(data.CreatorID);
+            map["Description"] = OSD.FromString(data.Description);
+            map["ID"] = OSD.FromString(data.ID);
+            map["Name"] = OSD.FromString(data.Name);
+            map["Type"] = OSD.FromInteger(data.Type);
+        }
+
+        private AssetBase LoadAssetBase(OSDMap map)
+        {
+            AssetBase asset = new AssetBase();
+            asset.Data = map["AssetData"].AsBinary();
+
+            AssetMetadata md = new AssetMetadata();
+            md.ContentType = map["ContentType"].AsString();
+            md.CreationDate = map["CreationDate"].AsDate();
+            md.CreatorID = map["CreatorID"].AsString();
+            md.Description = map["Description"].AsString();
+            md.ID = map["ID"].AsString();
+            md.Name = map["Name"].AsString();
+            md.Type = (sbyte)map["Type"].AsInteger();
+
+            asset.Metadata = md;
+            asset.ID = md.ID;
+            asset.FullID = UUID.Parse(md.ID);
+            asset.Name = md.Name;
+            asset.Type = md.Type;
+
+            return asset;
+        }
+
+        private void SaveItem(UUID ItemID, OSDMap itemMap, OSDMap assets)
+        {
+            InventoryItemBase saveItem = InventoryService.GetItem(new InventoryItemBase(ItemID));
+            if (saveItem == null)
+            {
+                m_log.Warn("[AvatarArchive]: Could not find item to save: " + ItemID.ToString());
+                return;
+            }
+            m_log.Info("[AvatarArchive]: Saving item " + ItemID.ToString());
+            string serialization = UserInventoryItemSerializer.Serialize(saveItem);
+            itemMap[ItemID.ToString()] = OSD.FromString(serialization);
+        }
+
+        private void LoadAssets(OSDMap assets)
+        {
+            foreach (KeyValuePair<string, OSD> kvp in assets)
+            {
+                UUID AssetID = UUID.Parse(kvp.Key);
+                OSDMap assetMap = (OSDMap)kvp.Value;
+                AssetBase asset = AssetService.Get(AssetID.ToString());
+                m_log.Info("[AvatarArchive]: Loading asset " + AssetID.ToString());
+                if (asset == null) //Don't overwrite
+                {
+                    asset = LoadAssetBase(assetMap);
+                    AssetService.Store(asset);
+                }
+            }
+        }
+
+        private void LoadItems(OSDMap items, UUID OwnerID, InventoryFolderBase folderForAppearance, out List<InventoryItemBase> litems)
+        {
+            litems = new List<InventoryItemBase>();
+            foreach (KeyValuePair<string, OSD> kvp in items)
+            {
+                string serialization = kvp.Value.AsString();
+                InventoryItemBase item = OpenSim.Framework.Serialization.External.UserInventoryItemSerializer.Deserialize(serialization);
+                m_log.Info("[AvatarArchive]: Loading item " + item.ID.ToString());
+                item = GiveInventoryItem(item.CreatorIdAsUuid, OwnerID, item, folderForAppearance);
+                litems.Add(item);
+            }
+        }
+	}
+}


Avoid NRE on PermissionTagHelper

Avoid NRE on PermissionTagHelper

--- BTCPayServer/TagHelpers/PermissionTagHelper.cs
+++ BTCPayServer/TagHelpers/PermissionTagHelper.cs
@@ -1,3 +1,4 @@
+#nullable enable
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
@@ -26,22 +27,20 @@
     public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
     {
         if (string.IsNullOrEmpty(Permission))
-        {
             return;
-        }
+        if (_httpContextAccessor.HttpContext is null)
+            return;

         var key = $"{Permission}_{PermissionResource}";
-        if (!_httpContextAccessor.HttpContext.Items.TryGetValue(key, out var cachedResult))
+        if (!_httpContextAccessor.HttpContext.Items.TryGetValue(key, out var o) ||
+            o is not AuthorizationResult res)
         {
-            var result = await _authorizationService.AuthorizeAsync(_httpContextAccessor.HttpContext.User,
+            res = await _authorizationService.AuthorizeAsync(_httpContextAccessor.HttpContext.User,
                 PermissionResource,
                 Permission);
-
-            cachedResult = result;
-            _httpContextAccessor.HttpContext.Items.Add(key, result);
-
+            _httpContextAccessor.HttpContext.Items.Add(key, res);
         }
-        if (!((AuthorizationResult)cachedResult).Succeeded)
+        if (!res.Succeeded)
         {
             output.SuppressOutput();
         }


Revert "Fix flakiness in RequestsCanBeAbortedMidRead (#4881)" (#5708)

This was never supposed be be merged into release/2.2 or master since both those branches include aspnet/KestrelHttpServer#2844.

This reverts commit 019ba081d38b5410aa0c7808275c0fd78d8f32fc.

--- src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs
+++ src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs
@@ -709,12 +709,7 @@
                 }
             }

-            var thrownEx = await Assert.ThrowsAnyAsync<Exception>(async () => await readTcs.Task).DefaultTimeout();
-
-            // https://github.com/aspnet/AspNetCore-Internal/issues/1521
-            // In more recent versions of Kestrel, we expect this to always be a TaskCanceledException,
-            // but without the changes in https://github.com/aspnet/KestrelHttpServer/pull/2844, this is flaky.
-            Assert.True(thrownEx is TaskCanceledException || thrownEx is IOException, $"{thrownEx} is neither a TaskCanceledException nor IOException.");
+            await Assert.ThrowsAsync<TaskCanceledException>(async () => await readTcs.Task);

             // The cancellation token for only the last request should be triggered.
             var abortedRequestId = await registrationTcs.Task.DefaultTimeout();


fixed exception handling

fixed exception handling

--- src/ServiceStack/WebHost.Endpoints/EndpointHostConfig.cs
+++ src/ServiceStack/WebHost.Endpoints/EndpointHostConfig.cs
@@ -246,19 +246,18 @@
 						if (instance.MetadataRedirectPath != null) { break; }
 					}
 				}
-
-				if (!SkipPathValidation && instance.MetadataRedirectPath == null)
-				{
-					throw new ConfigurationErrorsException(
-						"Unable to infer ServiceStack's <httpHandler.Path/> from the Web.Config\n"
-						+ "Check with http://www.servicestack.net/ServiceStack.Hello/ to ensure you have configured ServiceStack properly.\n"
-						+ "Otherwise you can explicitly set your httpHandler.Path by setting: EndpointHostConfig.ServiceStackPath");
-				}
 			}
 			catch (Exception exc)
 			{
-				log.Error("Bad Path", exc);
-				throw;
+				log.Error("Bad Config", exc);
+			}
+
+			if (!SkipPathValidation && instance.MetadataRedirectPath == null)
+			{
+				throw new ConfigurationErrorsException(
+					"Unable to infer ServiceStack's <httpHandler.Path/> from the Web.Config\n"
+					+ "Check with http://www.servicestack.net/ServiceStack.Hello/ to ensure you have configured ServiceStack properly.\n"
+					+ "Otherwise you can explicitly set your httpHandler.Path by setting: EndpointHostConfig.ServiceStackPath");
 			}
 		}


Reduced max joint torque. 1.25 seems sufficient to power the walker, any excess availabkle power can lead to 'excitable' walker strategies (e.g. jumping around and/or wildly flailing limbs).

--- src/SharpNeatDomainsExtra/WalkerBox2d/WalkerInterface.cs
+++ src/SharpNeatDomainsExtra/WalkerBox2d/WalkerInterface.cs
@@ -26,7 +26,7 @@
     /// </summary>
     public class WalkerInterface
     {
-        const float __jointMaxTorque = 2.5f;
+        const float __jointMaxTorque = 1.25f;
         Body _torsoBody;
         LegInterface _leftLegIface;
         LegInterface _rightLegIface;


DanielWagnerHall: Fix default URL

DanielWagnerHall: Fix default URL

git-svn-id: 4179480af2c2519a5eb5e1e9b541cbdf5cf27696@16539 07704840-8298-11de-bf8c-fd130f914ac9

--- dotnet/src/WebDriver/Android/AndroidDriver.cs
+++ dotnet/src/WebDriver/Android/AndroidDriver.cs
@@ -129,7 +129,7 @@

         private static Uri GetDefaultUrl()
         {
-            return new Uri("http://localhost:8080/hub");
+            return new Uri("http://localhost:8080/wd/hub");
         }

         private static DesiredCapabilities GetAndroidCapabilities()


Fix chat bots list performing the wrong HTTP action

--- src/Tgstation.Server.Client/Components/ChatBotsClient.cs
+++ src/Tgstation.Server.Client/Components/ChatBotsClient.cs
@@ -37,7 +37,7 @@
 		public Task Delete(ChatBot settings, CancellationToken cancellationToken) => apiClient.Delete(Routes.SetID(Routes.Chat, settings?.Id ?? throw new ArgumentNullException(nameof(settings))), instance.Id, cancellationToken);

 		/// <inheritdoc />
-		public Task<IReadOnlyList<ChatBot>> List(CancellationToken cancellationToken) => apiClient.Create<IReadOnlyList<ChatBot>>(Routes.List(Routes.Chat), instance.Id, cancellationToken);
+		public Task<IReadOnlyList<ChatBot>> List(CancellationToken cancellationToken) => apiClient.Read<IReadOnlyList<ChatBot>>(Routes.List(Routes.Chat), instance.Id, cancellationToken);

 		/// <inheritdoc />
 		public Task<ChatBot> Update(ChatBot settings, CancellationToken cancellationToken) => apiClient.Update<ChatBot, ChatBot>(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id, cancellationToken);


Minimal change to the sql statement for sessions.

--- src/Twainsoft.KeyCatcher.DB.Firebird/KeyboardSessions.cs
+++ src/Twainsoft.KeyCatcher.DB.Firebird/KeyboardSessions.cs
@@ -16,7 +16,7 @@

         public void Save(KeyboardSession keyboardSession)
         {
-            var sql = "INSERT INTO Sessions () VALUES ()";
+            var sql = "INSERT INTO Sessions (SID, Name, Start, End, Keys) VALUES ()";

             using (var saveCommand = new FbCommand("",
                 new FbConnection(Persistence.ConnectionString)))


Replace Enumerable.Repeat call with an one-element array.

--- src/VisualStudio/PackageSource/AggregatePackageSource.cs
+++ src/VisualStudio/PackageSource/AggregatePackageSource.cs
@@ -10,7 +10,7 @@
         }

         public static IEnumerable<PackageSource> GetPackageSourcesWithAggregate(this IPackageSourceProvider provider) {
-            return Enumerable.Repeat(Instance, 1).Concat(provider.LoadPackageSources());
+            return new[] { Instance }.Concat(provider.LoadPackageSources());
         }

         public static IEnumerable<PackageSource> GetPackageSourcesWithAggregate() {


Fix global tool to check for rootDirectory instead of buildScript when asking for setup

--- source/Nuke.GlobalTool/Program.cs
+++ source/Nuke.GlobalTool/Program.cs
@@ -57,7 +57,7 @@
                 return (int) commandHandler.Invoke(obj: null, commandArguments);
             }

-            if (buildScript == null)
+            if (rootDirectory == null)
             {
                 if (UserConfirms($"Could not find {Constants.ConfigurationFileName} file. Do you want to setup a build?"))
                     return Setup(new string[0], rootDirectory, buildScript: null);


Created the page load event. Formatted the new product item in GetSelectedProduct according to ReSharper rules

--- source/Order.aspx.cs
+++ source/Order.aspx.cs
@@ -9,26 +9,36 @@

     protected void Page_Load(object sender, System.EventArgs e)
     {
-
+        //bind drop-down list on first load
+        //get and show product on every load
+        if (!IsPostBack) this.ddlProducts.DataBind();
+        this.selectedProduct = this.GetSelectedProduct();
+        this.lblName.Text = this.selectedProduct.Name;
+        this.lblShortDescription.Text = this.selectedProduct.ShortDescription;
+        this.lblLongDescription.Text = this.selectedProduct.LongDescription;
+        this.lblUnitPrice.Text = this.selectedProduct.UnitPrice.ToString("c") + "each";
+        this.imgProduct.ImageUrl = "Images/Products/" + this.selectedProduct.ImageFile;
     }

     private Product GetSelectedProduct()
     {
         //get row from SqlDataSource based on value in dropdown list
-        DataView productsTable = (DataView)
+        var productsTable = (DataView)
             this.SqlDataSource.Select(DataSourceSelectArguments.Empty);
         productsTable.RowFilter = string.Format("ProductID = '{0}'",
             this.ddlProducts.SelectedValue);
         var row = (DataRowView) productsTable[0];

         //create a new product object and load with data from row
-        Product p = new Product();
-        p.ProductId = row["ProductID"].ToString();
-        p.Name = row["Name"].ToString();
-        p.ShortDescription = row["ShortDescription"].ToString();
-        p.LongDescription = row["LongDescription"].ToString();
-        p.UnitPrice = (decimal) row["UnitPrice"];
-        p.ImageFile = row["ImageFile"].ToString();
+        var p = new Product
+        {
+            ProductId = row["ProductID"].ToString(),
+            Name = row["Name"].ToString(),
+            ShortDescription = row["ShortDescription"].ToString(),
+            LongDescription = row["LongDescription"].ToString(),
+            UnitPrice = (decimal) row["UnitPrice"],
+            ImageFile = row["ImageFile"].ToString()
+        };
         return p;
     }
 }


Update UseTestName and UseTestFixtureName methods of AtataContextBuilder to allow null argument value

--- src/Atata/Context/AtataContextBuilder.cs
+++ src/Atata/Context/AtataContextBuilder.cs
@@ -525,8 +525,6 @@
         /// <returns>The <see cref="AtataContextBuilder"/> instance.</returns>
         public AtataContextBuilder UseTestName(string testName)
         {
-            testName.CheckNotNull(nameof(testName));
-
             BuildingContext.TestNameFactory = () => testName;
             return this;
         }
@@ -551,8 +549,6 @@
         /// <returns>The <see cref="AtataContextBuilder"/> instance.</returns>
         public AtataContextBuilder UseTestFixtureName(string testFixtureName)
         {
-            testFixtureName.CheckNotNull(nameof(testFixtureName));
-
             BuildingContext.TestFixtureNameFactory = () => testFixtureName;
             return this;
         }


Use the string representation of the Uri

A string is the only documented parameter and the dll installed on the Mac only includes the string constructor

--- src/Bugsnag.Unity/ThreadQueueDelivery.cs
+++ src/Bugsnag.Unity/ThreadQueueDelivery.cs
@@ -47,7 +47,7 @@
       while (true)
       {
         var payload = _queue.Dequeue();
-        var request = new UnityWebRequest(payload.Endpoint, "POST");
+        var request = new UnityWebRequest(payload.Endpoint.OriginalString.ToString(), "POST");

         request.SetRequestHeader("Content-Type", "application/json; charset=utf-8");
         request.SetRequestHeader("Bugsnag-Sent-At", DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture));


Add record error to the error context and not to the record context

--- BeanIO/Internal/Parser/UnmarshallingContext.cs
+++ BeanIO/Internal/Parser/UnmarshallingContext.cs
@@ -430,7 +430,7 @@

             var pattern = MessageFactory.GetRecordErrorMessage(recordName, rule);
             var message = string.Format(Culture, pattern, messageParams);
-            _recordContext.AddRecordError(message);
+            errorContext.AddRecordError(message);
             return message;
         }


Cambio color desafío 8

Cambio color desafío 8

--- BeatIt!/AppCode/Challenges/ChallengeDetail8.cs
+++ BeatIt!/AppCode/Challenges/ChallengeDetail8.cs
@@ -8,7 +8,7 @@
         {
             ChallengeId = 8;
             Name = "Challenge 8";
-            ColorHex = "#FFFA6800";
+            ColorHex = "#FF0050EF";
             Description = "Description 8";
             IsEnabled = false;
             Level = 1;


Check for source and output folders missing from build command before attempting to normalize the path slash-style. Was causing crashes if the source or output was not specified in the command.


Added ModuleManager.JoinedServer

Added ModuleManager.JoinedServer

--- src/Discord.Net.Modules/ModuleManager.cs
+++ src/Discord.Net.Modules/ModuleManager.cs
@@ -14,6 +14,7 @@
         public event EventHandler<ChannelEventArgs> ChannelEnabled = delegate { };
         public event EventHandler<ChannelEventArgs> ChannelDisabled = delegate { };

+        public event EventHandler<ServerEventArgs> JoinedServer = delegate { };
         public event EventHandler<ServerEventArgs> LeftServer = delegate { };
         public event EventHandler<ServerUpdatedEventArgs> ServerUpdated = delegate { };
         public event EventHandler<ServerEventArgs> ServerUnavailable = delegate { };
@@ -96,7 +97,8 @@
 			client.RoleUpdated += (s, e) => { if (HasIndirectServer(e.Server)) RoleUpdated(s, e); };
 			client.RoleDeleted += (s, e) => { if (HasIndirectServer(e.Server)) RoleDeleted(s, e); };

-			client.LeftServer += (s, e) => { if (HasIndirectServer(e.Server)) { DisableServer(e.Server); LeftServer(s, e); } };
+            client.JoinedServer += (s, e) => { if (_allowAll) JoinedServer(s, e); };
+            client.LeftServer += (s, e) => { if (HasIndirectServer(e.Server)) { DisableServer(e.Server); LeftServer(s, e); } };
 			client.ServerUpdated += (s, e) => { if (HasIndirectServer(e.After)) ServerUpdated(s, e); };
 			client.ServerUnavailable += (s, e) => { if (HasIndirectServer(e.Server)) ServerUnavailable(s, e); };
 			client.ServerAvailable += (s, e) => { if (HasIndirectServer(e.Server)) ServerAvailable(s, e); };


Increment version

Increment version

--- ByteArray/ByteArray/Properties/AssemblyInfo.cs
+++ ByteArray/ByteArray/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.1.0")]
-[assembly: AssemblyFileVersion("1.0.1.0")]
+[assembly: AssemblyVersion("1.0.2.0")]
+[assembly: AssemblyFileVersion("1.0.2.0")]


Removed dead assembly redirect code

Removed dead assembly redirect code

--- src/Dotnet.Script.Core/ScriptCompiler.cs
+++ src/Dotnet.Script.Core/ScriptCompiler.cs
@@ -99,10 +99,6 @@

             IList<RuntimeDependency> runtimeDependencies =
                 _runtimeDependencyResolver.GetDependencies(context.WorkingDirectory).ToList();
-
-            AssemblyLoadContext.Default.Resolving +=
-                (assemblyLoadContext, assemblyName) => MapUnresolvedAssemblyToRuntimeLibrary(runtimeDependencies.ToList(), assemblyLoadContext, assemblyName);
-

             foreach (var runtimeDependency in runtimeDependencies)
             {
@@ -132,22 +128,5 @@

             return new ScriptCompilationContext<TReturn>(script, context.Code, loader);
         }
-
-        private Assembly MapUnresolvedAssemblyToRuntimeLibrary(IList<RuntimeDependency> runtimeDependencies, AssemblyLoadContext loadContext, AssemblyName assemblyName)
-        {
-            //var runtimeDependency = runtimeDependencies.SingleOrDefault(r => AssemblyLoadContext.GetAssemblyName(r.Path).Name == assemblyName.Name);
-            //if (runtimeDependency != null)
-            //{
-            //    AssemblyName an = AssemblyName.GetAssemblyName(runtimeDependency.Path);
-            //    var runtimeDependencyAssemblyName = AssemblyLoadContext.GetAssemblyName(runtimeDependency.Path);
-            //    if (runtimeDependencyAssemblyName.Version != assemblyName.Version)
-            //    {
-            //        _logger.Verbose(
-            //            $"Unresolved assembly {assemblyName}. Loading from resolved runtime dependencies at path: {runtimeDependency.Path}");
-            //        return loadContext.LoadFromAssemblyPath(runtimeDependency.Path);
-            //    }
-            //}
-            return null;
-        }
     }
 }


Added second object intiializer example

Added second object intiializer example

--- CSharpLesson1/CSharpLesson1.Console/Program.cs
+++ CSharpLesson1/CSharpLesson1.Console/Program.cs
@@ -22,8 +22,14 @@
                 Size = 4
             };

+            var dot3 = new Dot(null, dot1Position, 8)
+            {
+                Color = "purple"
+            };
+
             Console.WriteLine(dot1);
             Console.WriteLine(dot2);
+            Console.WriteLine(dot3);
             Console.Read();
         }
     }


Remove unused using directives.

Remove unused using directives.

--- src/Fixie.Tests/Execution/RunnerTests.cs
+++ src/Fixie.Tests/Execution/RunnerTests.cs
@@ -5,9 +5,7 @@
     using System.Linq;
     using System.Reflection;
     using Fixie.Execution;
-    using static System.Environment;
     using static Utility;
-    using Lifecycle = Fixie.Lifecycle;

     public class RunnerTests
     {


Updated AssemblyInfo

Updated AssemblyInfo

--- src/FluentBdd/Properties/AssemblyInfo.cs
+++ src/FluentBdd/Properties/AssemblyInfo.cs
@@ -8,11 +8,10 @@
 [assembly: AssemblyTitle("FluentBdd")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyCompany("TheDev6")]
 [assembly: AssemblyProduct("FluentBdd")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2017")]
 [assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
+[assembly: AssemblyCulture("English")]

 // Setting ComVisible to false makes the types in this assembly not visible
 // to COM components.  If you need to access a type in this assembly from


Fix GetMaximumStartOffset to consider lines behind scroll bars

--- src/FujiyNotepad.UI/FujiyTextBox.xaml.cs
+++ src/FujiyNotepad.UI/FujiyTextBox.xaml.cs
@@ -194,7 +194,7 @@
             {
                 fs.Seek(0, SeekOrigin.End);
                 int newLines = 0;
-                int visibleLines = CountVisibleLines();
+                int visibleLines = CountVisibleLines() - 2;//Rows behind horizontal scrollbar

                 while (newLines < visibleLines && fs.Position > 0)//TODO testar arquivo pequeno
                 {


Use CountdownDisposable

Use CountdownDisposable

--- src/Host/Client/Impl/Session/RSession.cs
+++ src/Host/Client/Impl/Session/RSession.cs
@@ -58,6 +58,7 @@
         private volatile bool _delayedMutatedOnReadConsole;
         private volatile IRSessionCallback _callback;
         private volatile RHostStartupInfo _startupInfo;
+        private readonly CountdownDisposable _readUserInputReentrancyCounter = new CountdownDisposable();

         public int Id { get; }
         public string Name { get; }
@@ -67,7 +68,7 @@
         public Task HostStarted => _hostStartedTcs.Task;
         public bool IsRemote => BrokerClient.IsRemote;
         public bool IsProcessing { get; private set; }
-        public bool IsReadingUserInput { get; private set; }
+        public bool IsReadingUserInput => _readUserInputReentrancyCounter.Count > 0;

         public bool RestartOnBrokerSwitch { get; set; }

@@ -565,10 +566,10 @@
             var callback = _callback;
             if (!addToHistory && callback != null) {
                 try {
-                    IsReadingUserInput = true;
+                    _readUserInputReentrancyCounter.Increment();
                     return await callback.ReadUserInput(prompt, len, ct);
                 } finally {
-                    IsReadingUserInput = false;
+                    _readUserInputReentrancyCounter.Decrement();
                 }
             }


LIBOMV-738: Update tracked objects/avatars from ImprovedTerseObjectUpdateHandler

git-svn-id: e915c4f8b2ea2a6e63cbe989b51c0994a698cc26@3207 52acb1d6-8a22-11de-b505-999d5b087335

--- OpenMetaverse/ObjectManager.cs
+++ OpenMetaverse/ObjectManager.cs
@@ -2045,7 +2045,7 @@

                     #endregion Decode update data

-                    Primitive obj = (update.Avatar) ?
+                    Primitive obj = !Client.Settings.OBJECT_TRACKING ? null : (update.Avatar) ?
                         (Primitive)GetAvatar(simulator, update.LocalID, UUID.Zero) :
                         (Primitive)GetPrimitive(simulator, update.LocalID, UUID.Zero);

@@ -2063,6 +2063,18 @@
                         Client.Self.angularVelocity = update.AngularVelocity;
                     }
                     #endregion Update Client.Self
+                     if (Client.Settings.OBJECT_TRACKING && obj != null)
+                     {
+                         obj.Position = update.Position;
+                         obj.Rotation = update.Rotation;
+                         obj.Velocity = update.Velocity;
+                         obj.CollisionPlane = update.CollisionPlane;
+                         obj.Acceleration = update.Acceleration;
+                         obj.AngularVelocity = update.AngularVelocity;
+                         obj.PrimData.State = update.State;
+                         obj.Textures = update.Textures;
+                     }
+
                 }
                 catch (Exception ex)
                 {


Fixed rebuild.server target

Fixed rebuild.server target

--- BuildScript.cs
+++ BuildScript.cs
@@ -58,8 +58,8 @@

         context.CreateTarget("rebuild.server")
             .SetAsDefault()
-            .DependsOn(compile, flubuTests, merge, nuget)
-            .DependsOn("package.SystemTests");
+            ////.DependsOn(compile, flubuTests, merge, nuget)
+            .DependsOn("compile", "test", "merge", "nuget.publish", "package.SystemTests");
     }

     private static void PublishNuGetPackage(ITaskContext context)


adjust C# indentation

adjust C# indentation

--- C#/bkkcrypt.cs
+++ C#/bkkcrypt.cs
@@ -9,9 +9,9 @@

 	public class BKKCrypt : ICrypt
 	{
-    	public string Encrypt(string input)
-    	{
-      		return input;
-    	}
+    		public string Encrypt(string input)
+    		{
+      			return input;
+    		}
   	}
 }


Revert "Remove RandomTrace stuff from main"

This reverts commit f4533db6c2eb955d5433cf52e85d32a223a7bba8.

--- CIV/Program.cs
+++ CIV/Program.cs
@@ -1,7 +1,6 @@
 using static System.Console;
-using System.Linq;
-using CIV.Ccs;
-using CIV.Hml;
+using CIV.Ccs;
+using CIV.Interfaces;

 namespace CIV
 {
@@ -12,9 +11,11 @@
   			var text = System.IO.File.ReadAllText(args[0]);

 			var processes = CcsFacade.ParseAll(text);
-            var hmlText = "[[ack]][[ack]][[ack]](<<ack>>tt and [[freeAll]]ff)";
-            var prova = HmlFacade.ParseAll(hmlText);
-            WriteLine(prova.Check(processes["Prison"]));
+            var trace = CcsFacade.RandomTrace(processes["Prison"], 450);
+            foreach (var action in trace)
+            {
+                WriteLine(action);
+            }
         }
     }
 }


Performance project now runs all benchmarks by default

--- Code/Light.GuardClauses.Performance/Program.cs
+++ Code/Light.GuardClauses.Performance/Program.cs
@@ -2,7 +2,6 @@
 using System.Reflection;
 using BenchmarkDotNet.Attributes.Jobs;
 using BenchmarkDotNet.Running;
-using Light.GuardClauses.Performance.CommonAssertions;

 namespace Light.GuardClauses.Performance
 {
@@ -10,7 +9,7 @@
     {
         public static void Main()
         {
-            BenchmarkRunner.Run<MustNotBeNullWithParameterNameBenchmarks>();
+            RunAllBenchmarks();
         }

         private static void RunAllBenchmarks()


kick users if they ignore warning about invite links

--- CompatBot/EventHandlers/DiscordInviteFilter.cs
+++ CompatBot/EventHandlers/DiscordInviteFilter.cs
@@ -26,14 +26,10 @@
     private static readonly TimeSpan CacheDuration = TimeSpan.FromHours(24);

     public static async Task OnMessageCreated(DiscordClient c, MessageCreateEventArgs args)
-    {
-        args.Handled = !await CheckMessageForInvitesAsync(c, args.Message).ConfigureAwait(false);
-    }
+        => args.Handled = !await CheckMessageForInvitesAsync(c, args.Message).ConfigureAwait(false);

     public static async Task OnMessageUpdated(DiscordClient c, MessageUpdateEventArgs args)
-    {
-        args.Handled = !await CheckMessageForInvitesAsync(c, args.Message).ConfigureAwait(false);
-    }
+        => args.Handled = !await CheckMessageForInvitesAsync(c, args.Message).ConfigureAwait(false);

     public static async Task CheckBacklogAsync(DiscordClient client, DiscordGuild guild)
     {
@@ -134,7 +130,7 @@
             if (!await InviteWhitelistProvider.IsWhitelistedAsync(invite).ConfigureAwait(false))
             {
                 if (!InviteCodeCache.TryGetValue(message.Author.Id, out HashSet<string> recentInvites))
-                    recentInvites = new HashSet<string>();
+                    recentInvites = new();
                 var circumventionAttempt = !recentInvites.Add(invite.Code) && attemptedWorkaround; //do not flip, must add to cache always
                 InviteCodeCache.Set(message.Author.Id, recentInvites, CacheDuration);
                 var removed = false;
@@ -166,6 +162,21 @@
                         userMsg += "Please remove it and refrain from posting it again until you have received an approval from a moderator.";
                 }
                 await client.ReportAsync("🛃 An unapproved discord invite", message, reportMsg, null, null, null, ReportSeverity.Low).ConfigureAwait(false);
+                if (recentInvites.Count > 1)
+                    try
+                    {
+                        var member = client.GetMember(message.Channel.Guild, message.Author);
+                        if (member is not null)
+                        {
+                            await member.RemoveAsync("Multiple invites after being warned").ConfigureAwait(false);
+                            return false;
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        Config.Log.Warn(e, $"Failed to kick user {message.Author.GetUsernameWithNickname(client)} for repeated invite spam");
+                    }
+
                 await message.Channel.SendMessageAsync(userMsg).ConfigureAwait(false);
                 if (circumventionAttempt)
                     await Warnings.AddAsync(client, message, message.Author.Id, message.Author.Username, client.CurrentUser, "Attempted to circumvent discord invite filter", codeResolveMsg);


Specified attribute usage constraints on ContextualAttribute.

--- Piccolo/ContextualAttribute.cs
+++ Piccolo/ContextualAttribute.cs
@@ -2,6 +2,7 @@

 namespace Piccolo
 {
+	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
 	public class ContextualAttribute : Attribute
 	{
 	}


Some minor updates in the form helper.

Some minor updates in the form helper.

--- Piranha/WebPages/FormHelper.cs
+++ Piranha/WebPages/FormHelper.cs
@@ -107,7 +107,7 @@
 		/// <param name="expr">The model expression</param>
 		/// <returns>The checkbox</returns>
 		public IHtmlString CheckBoxFor<TProperty>(Expression<Func<TModel, TProperty>> expr) {
-			return Page.Html.CheckBox(expr.Body.ToString(), GetValue(expr)) ;
+			return Page.Html.CheckBox(expr.Body.ToString(), (bool)GetValue(expr), new { @value = "true" }) ;
 		}

 		/// <summary>
@@ -118,6 +118,17 @@
 		/// <returns>The password</returns>
 		public IHtmlString PasswordFor<TProperty>(Expression<Func<TModel, TProperty>> expr) {
 			return Page.Html.Password(expr.Body.ToString()) ;
+		}
+
+		/// <summary>
+		/// Gets a password for the specified model property.
+		/// </summary>
+		/// <typeparam name="TProperty">The property type</typeparam>
+		/// <param name="expr">The model expression</param>
+		/// <param name="htmlAttributes">Additional html attributes</param>
+		/// <returns>The password</returns>
+		public IHtmlString PasswordFor<TProperty>(Expression<Func<TModel, TProperty>> expr, object htmlAttributes) {
+			return Page.Html.Password(expr.Body.ToString(), null, htmlAttributes) ;
 		}

 		/// <summary>


Use I18N where possible. Made ReadColor() public.

--- PlayOnline.FFXI/FFXIGraphic.cs
+++ PlayOnline.FFXI/FFXIGraphic.cs
@@ -67,7 +67,7 @@
 	  for (int i = 0; i < 4; ++i)
 	    FourCC = (char) BR.ReadByte() + FourCC;
 	  FourCC = FourCC.TrimEnd('\0');
-	  FG.Format = FourCC;
+	  FG.Format = String.Format(I18N.GetText("GraphicTypeDXT"), FourCC);
 	  // Currently, only the DirectX texture format is (partially) supported
 	  if (FourCC.StartsWith("DXT")) { // DirectX Texture format
 	  int TexelBlockCount = PixelCount / 16; // 4x4 blocks
@@ -97,7 +97,7 @@
 	  if (FG.Flag == 0xB1)
 	    BR.ReadInt32(); // Unknown - always seems to be 10 (0x0000000A)
 	Bitmap BM = new Bitmap(FG.Width, FG.Height, PixelFormat.Format32bppArgb);
-	  FG.Format = String.Format("{0}-bit Bitmap", FG.BitCount);
+	  FG.Format = String.Format(I18N.GetText("GraphicTypeBitmap"), FG.BitCount);
 	  if (FG.BitCount == 8) { // 8-bit, with palette
 	  Color[] Palette = new Color[256];
 	    for (int i = 0; i < 256; ++i)
@@ -122,7 +122,7 @@
       return ((FG != null && FG.Bitmap != null) ? FG : null);
     }

-    private static Color ReadColor(BinaryReader BR, int BitDepth) {
+    public static Color ReadColor(BinaryReader BR, int BitDepth) {
       switch (BitDepth) {
 	case 16: return FFXIGraphic.DecodeRGB565(BR.ReadUInt16());
 	case 32: case 24: {


added new check for cInviteUserToGuild

added new check for cInviteUserToGuild

--- DamageMeter.Core/Heuristic/S_SYSTEM_MESSAGE.cs
+++ DamageMeter.Core/Heuristic/S_SYSTEM_MESSAGE.cs
@@ -44,6 +44,7 @@
             if (msg.StartsWith("@970") && msg.Contains("ChannelName")) S_JOIN_PRIVATE_CHANNEL.Confirm();
             if (msg.StartsWith("@3459") && msg.Contains("UserName")) C_ADD_FRIEND.Confirm();
             if (msg.StartsWith("@436") && msg.Contains("UserName")) C_DELETE_FRIEND.Confirm();
+            if (msg.StartsWith("@3641") && msg.Contains("userName")) C_INVITE_USER_TO_GUILD.Confirm();

         }
     }


utility function

utility function

--- DbShell.Driver.Common/Utility/ListExtension.cs
+++ DbShell.Driver.Common/Utility/ListExtension.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Text;

@@ -15,16 +16,15 @@
             list[i2] = tmp;
         }

-
         public static void SortByKey<ElementType, KeyType>(this List<ElementType> lst, Func<ElementType, KeyType> key)
             where KeyType : IComparable
         {
-            lst.Sort((Comparison<ElementType>)(delegate(ElementType a, ElementType b) { return key(a).CompareTo(key(b)); }));
+            lst.Sort((Comparison<ElementType>) (delegate(ElementType a, ElementType b) { return key(a).CompareTo(key(b)); }));
         }

         public static void RemoveIf<T>(this IList<T> list, Func<T, bool> testFunc)
         {
-            for (int i = 0; i < list.Count; )
+            for (int i = 0; i < list.Count;)
             {
                 if (testFunc(list[i])) list.RemoveAt(i);
                 else i++;
@@ -44,5 +44,12 @@
             for (int i = 0; i < list.Count; i++) if (Object.Equals(list[i], item)) return i;
             return -1;
         }
+
+        public static void Exchange<T>(this ObservableCollection<T> list, int i1, int i2)
+        {
+            T tmp = list[i1];
+            list[i1] = list[i2];
+            list[i2] = tmp;
+        }
     }
 }


BuildingPart update

BuildingPart update

--- Pluton/Objects/BuildingPart.cs
+++ Pluton/Objects/BuildingPart.cs
@@ -17,6 +17,20 @@
         public Construction.Socket FindSocket(string name)
         {
             return buildingBlock.FindSocket(name);
+        }
+
+        public void ChangeOwner(Player player)
+        {
+            if (player == null)
+                return;
+
+            OwnerID = player.GameID;
+            OwnerName = player.Name;
+        }
+
+        public void Destroy()
+        {
+            buildingBlock.Kill(ProtoBuf.EntityDestroy.Mode.Gib, 2, 0, buildingBlock.transform.position);
         }

         public float Health {
@@ -53,11 +67,17 @@
             get {
                 return buildingBlock.deployerUserID;
             }
+            set {
+                buildingBlock.deployerUserID = value;
+            }
         }

         public string OwnerName {
             get {
                 return buildingBlock.deployerUserName;
+            }
+            set {
+                buildingBlock.deployerUserName = value;
             }
         }


GitHubSync update

GitHubSync update

--- deployment/cake/docker-tasks.cake
+++ deployment/cake/docker-tasks.cake
@@ -178,7 +178,7 @@

             CakeContext.CreateDirectory(confTargetDirectory);

-            var confSourceDirectory = string.Format("{0}*", dockerImageSpecificationDirectory);
+            var confSourceDirectory = string.Format("{0}/*", dockerImageSpecificationDirectory);
             CakeContext.Information("Copying files from '{0}' => '{1}'", confSourceDirectory, confTargetDirectory);

             CakeContext.CopyFiles(confSourceDirectory, confTargetDirectory, true);


Generate speakers.

Generate speakers.

--- Desktop/FacetedWorlds.MyCon.DevLink/Program.cs
+++ Desktop/FacetedWorlds.MyCon.DevLink/Program.cs
@@ -4,6 +4,7 @@
 using System.Text;
 using FacetedWorlds.MyCon.DevLink.DevLinkServiceReference;
 using System.Threading;
+using System.Text.RegularExpressions;

 namespace FacetedWorlds.MyCon.DevLink
 {
@@ -16,15 +17,14 @@
             _entities = new devlink2011Entities(new Uri("http://devlink.us/odata.svc/", UriKind.Absolute));

             GenerateTimeSlots();
+            GenerateSpeakers();
         }

         private static void GenerateTimeSlots()
         {
             TimeZoneInfo est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

-            var times = _entities.timeslots;
-
-            foreach (var time in times)
+            foreach (var time in _entities.timeslots)
             {
                 DateTime localStart = TimeZoneInfo.ConvertTimeFromUtc(time.start, est);
                 Console.WriteLine(String.Format("_timeById[\"{1}\"] = conference.GetTime(DateTime.Parse(\"{0}\"));", localStart, time.timeslotid));
@@ -34,5 +34,26 @@
                 }
             }
         }
+
+        private static void GenerateSpeakers()
+        {
+            foreach (var speaker in _entities.speakers)
+            {
+                string speakerName = speaker.firstname + " " + speaker.lastname;
+                string contact = "@" + speaker.twitter;
+                string speakerBio = StringEncode(speaker.bio);
+                string speakerImageUrl = speaker.imageurl;
+
+                Console.WriteLine(String.Format("_speakerById[\"{4}\"] = conference.NewSpeaker(\"{0}\", \"{1}\", \"{2}\", \"{3}\");", speakerName, contact, speakerBio, speakerImageUrl, speaker.speakerid));
+            }
+        }
+
+        private static string StringEncode(string value)
+        {
+            return value
+                .Replace("\\", "\\\\")
+                .Replace("\n", "\\n")
+                .Replace("\"", "\\\"");
+        }
     }
 }


Minor refactor.

Minor refactor.

--- src/LineBot/Messages/Text/TextMessage.cs
+++ src/LineBot/Messages/Text/TextMessage.cs
@@ -48,9 +48,9 @@
             Text = text;
         }

-        internal TextMessage(ITextMessage self)
+        internal TextMessage(ITextMessage other)
         {
-            Text = self.Text;
+            Text = other.Text;
         }

         /// <summary>


Added comments

Added comments

--- src/Logikfabrik.Overseer/IAppSettings.cs
+++ src/Logikfabrik.Overseer/IAppSettings.cs
@@ -25,12 +25,36 @@
         /// </value>
         bool ShowNotifications { get; set; }

+        /// <summary>
+        /// Gets or sets a value indicating whether to show notifications for in progress builds.
+        /// </summary>
+        /// <value>
+        ///   <c>true</c> if to show notifications for in progress builds; otherwise, <c>false</c>.
+        /// </value>
         bool ShowNotificationsForInProgressBuilds { get; set; }

+        /// <summary>
+        /// Gets or sets a value indicating whether to show notifications for failed builds.
+        /// </summary>
+        /// <value>
+        ///   <c>true</c> if to show notifications for failed builds; otherwise, <c>false</c>.
+        /// </value>
         bool ShowNotificationsForFailedBuilds { get; set; }

+        /// <summary>
+        /// Gets or sets a value indicating whether to show notifications for succeeded builds.
+        /// </summary>
+        /// <value>
+        ///   <c>true</c> if to show notifications for succeeded builds; otherwise, <c>false</c>.
+        /// </value>
         bool ShowNotificationsForSucceededBuilds { get; set; }

+        /// <summary>
+        /// Gets or sets a value indicating whether to show notifications for stopped builds.
+        /// </summary>
+        /// <value>
+        ///   <c>true</c> if to show notifications for stopped builds; otherwise, <c>false</c>.
+        /// </value>
         bool ShowNotificationsForStoppedBuilds { get; set; }

         /// <summary>


Send admin notification on share recorder policy fallback engage

--- src/MiningCore/Payments/ShareRecorder.cs
+++ src/MiningCore/Payments/ShareRecorder.cs
@@ -28,11 +28,13 @@
 using System.Reactive.Concurrency;
 using System.Reactive.Linq;
 using System.Text;
+using Autofac.Features.Metadata;
 using AutoMapper;
 using MiningCore.Blockchain;
 using MiningCore.Configuration;
 using MiningCore.Extensions;
 using MiningCore.Mining;
+using MiningCore.Notifications;
 using MiningCore.Persistence;
 using MiningCore.Persistence.Model;
 using MiningCore.Persistence.Repositories;
@@ -51,17 +53,20 @@
     {
         public ShareRecorder(IConnectionFactory cf, IMapper mapper,
             JsonSerializerSettings jsonSerializerSettings,
-            IShareRepository shareRepo, IBlockRepository blockRepo)
+            IShareRepository shareRepo, IBlockRepository blockRepo,
+            IEnumerable<Meta<INotificationSender, NotificationSenderMetadataAttribute>> notificationSenders)
         {
             Contract.RequiresNonNull(cf, nameof(cf));
             Contract.RequiresNonNull(mapper, nameof(mapper));
             Contract.RequiresNonNull(shareRepo, nameof(shareRepo));
             Contract.RequiresNonNull(blockRepo, nameof(blockRepo));
             Contract.RequiresNonNull(jsonSerializerSettings, nameof(jsonSerializerSettings));
+            Contract.RequiresNonNull(notificationSenders, nameof(notificationSenders));

             this.cf = cf;
             this.mapper = mapper;
             this.jsonSerializerSettings = jsonSerializerSettings;
+            this.notificationSenders = notificationSenders;

             this.shareRepo = shareRepo;
             this.blockRepo = blockRepo;
@@ -73,6 +78,8 @@

         private readonly IConnectionFactory cf;
         private readonly JsonSerializerSettings jsonSerializerSettings;
+        private readonly IEnumerable<Meta<INotificationSender, NotificationSenderMetadataAttribute>> notificationSenders;
+        private ClusterConfig clusterConfig;
         private readonly IMapper mapper;
         private readonly BlockingCollection<IShare> queue = new BlockingCollection<IShare>();

@@ -85,6 +92,7 @@
         private string recoveryFilename;
         private const int RetryCount = 3;
         private const string PolicyContextKeyShares = "share";
+        private bool notifiedAdminOnPolicyFallback = false;

         private static readonly ILogger logger = LogManager.GetCurrentClassLogger();

@@ -144,6 +152,8 @@
                         }
                     }
                 }
+
+                NotifyAdminOnPolicyFallback();
             }

             catch (Exception ex)
@@ -263,6 +273,33 @@
             }
         }

+        private async void NotifyAdminOnPolicyFallback()
+        {
+            if (clusterConfig.Notifications?.Admin?.Enabled == true &&
+                clusterConfig.Notifications?.Admin?.NotifyPaymentSuccess == true &&
+                !notifiedAdminOnPolicyFallback)
+            {
+                notifiedAdminOnPolicyFallback = true;
+
+                try
+                {
+                    var adminEmail = clusterConfig.Notifications.Admin.EmailAddress;
+
+                    var emailSender = notificationSenders
+                        .Where(x => x.Metadata.NotificationType == NotificationType.Email)
+                        .Select(x => x.Value)
+                        .First();
+
+                    await emailSender.NotifyAsync(adminEmail, "Share Recorder Policy Fallback", $"The Share Recorder's Policy Fallback has been engaged. Check share recovery file {recoveryFilename}.");
+                }
+
+                catch (Exception ex)
+                {
+                    logger.Error(ex);
+                }
+            }
+        }
+
         #region API-Surface

         public void AttachPool(IMiningPool pool)
@@ -311,6 +348,8 @@

         private void ConfigureRecovery(ClusterConfig clusterConfig)
         {
+            this.clusterConfig = clusterConfig;
+
             recoveryFilename = !string.IsNullOrEmpty(clusterConfig.PaymentProcessing?.ShareRecoveryFile)
                 ? clusterConfig.PaymentProcessing.ShareRecoveryFile
                 : "recovered-shares.txt";


Fix API endpoint in GetBodies(string)

Fix API endpoint in GetBodies(string)

--- EliteDangerous/EDSM/EDSMClass.cs
+++ EliteDangerous/EDSM/EDSMClass.cs
@@ -710,7 +710,7 @@
             string encodedSys = HttpUtility.UrlEncode(sysName);

             string query = "bodies?systemName=" + sysName;
-            var response = RequestGet("api-v1/" + query, handleException: true);
+            var response = RequestGet("api-system-v1/" + query, handleException: true);
             if (response.Error)
                 return null;


Catch rare ObjectDisposedException when connecting.

This seems like it could be caused by a rare race condition when timeout occurs during connection; see https://github.com/mysql-net/MySqlConnector/issues/1033#issuecomment-925222138.

Signed-off-by: Bradley Grainger <dae7ff431bf350b84a58dc5360c13b9e7c97b48a@gmail.com>

--- src/MySqlConnector/Core/ServerSession.cs
+++ src/MySqlConnector/Core/ServerSession.cs
@@ -1024,12 +1024,24 @@
 					throw new MySqlException(MySqlErrorCode.UnableToConnectToHost, "Connect Timeout expired.");
 				}

-				HostName = hostName;
-				m_tcpClient = tcpClient;
-				m_socket = m_tcpClient.Client;
-				m_socket.NoDelay = true;
-				m_stream = m_tcpClient.GetStream();
-				m_socket.SetKeepAlive(cs.Keepalive);
+				try
+				{
+					HostName = hostName;
+					m_tcpClient = tcpClient;
+					m_socket = m_tcpClient.Client;
+					m_socket.NoDelay = true;
+					m_stream = m_tcpClient.GetStream();
+					m_socket.SetKeepAlive(cs.Keepalive);
+				}
+				catch (ObjectDisposedException) when (cancellationToken.IsCancellationRequested)
+				{
+					Utility.Dispose(ref m_stream);
+					SafeDispose(ref m_tcpClient);
+					SafeDispose(ref m_socket);
+					Log.Info("Session{0} connect timeout expired connecting to IpAddress {1} for HostName '{2}'", m_logArguments[0], ipAddress, hostName);
+					throw new MySqlException(MySqlErrorCode.UnableToConnectToHost, "Connect Timeout expired.");
+				}
+
 				lock (m_lock)
 					m_state = State.Connected;
 				Log.Trace("Session{0} connected to IpAddress {1} for HostName '{2}' with local Port {3}", m_logArguments[0], ipAddress, hostName, (m_socket.LocalEndPoint as IPEndPoint)?.Port);


Update file system utils.

Update file system utils.

--- Engine/Utility/FileSystemUtil.cs
+++ Engine/Utility/FileSystemUtil.cs
@@ -21,7 +21,18 @@

                 Debug.Log("CreateDirectoryIfNeededAndAllowed:" + path);

-                Directory.CreateDirectory(path);
+                path = path.TrimEnd('/');
+
+                Debug.Log("CreateDirectoryIfNeededAndAllowed:trimmed:path:" + path);
+
+                //Directory.CreateDirectory(path);
+
+                DirectoryInfo dir = new DirectoryInfo(path);
+
+                if(!dir.Exists) {
+                    dir.Create();
+                    Debug.Log("CreateDirectoryIfNeededAndAllowed:info:path:" + path);
+                }
             }
         }
 #endif


NH-4070 - Add missing function overrides to MsSqlCe

--- src/NHibernate/Dialect/MsSqlCeDialect.cs
+++ src/NHibernate/Dialect/MsSqlCeDialect.cs
@@ -170,6 +170,7 @@
 			RegisterFunction("substring", new EmulatedLengthSubstringFunction());
 			RegisterFunction("str", new SQLFunctionTemplate(NHibernateUtil.String, "cast(?1 as nvarchar)"));

+			RegisterFunction("current_timestamp", new NoArgSQLFunction("getdate", NHibernateUtil.DateTime, true));
 			RegisterFunction("date", new SQLFunctionTemplate(NHibernateUtil.DateTime, "dateadd(dd, 0, datediff(dd, 0, ?1))"));
 			RegisterFunction("second", new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(second, ?1)"));
 			RegisterFunction("minute", new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(minute, ?1)"));
@@ -187,10 +188,15 @@
 			RegisterFunction("lower", new StandardSQLFunction("lower"));

 			RegisterFunction("trim", new AnsiTrimEmulationFunction());
+			RegisterFunction("iif", new SQLFunctionTemplate(null, "case when ?1 then ?2 else ?3 end"));

 			RegisterFunction("concat", new VarArgsSQLFunction(NHibernateUtil.String, "(", "+", ")"));
+			RegisterFunction("mod", new SQLFunctionTemplate(NHibernateUtil.Int32, "((?1) % (?2))"));

 			RegisterFunction("round", new StandardSQLFunction("round"));
+
+			RegisterFunction("bit_length", new SQLFunctionTemplate(NHibernateUtil.Int32, "datalength(?1) * 8"));
+			RegisterFunction("extract", new SQLFunctionTemplate(NHibernateUtil.Int32, "datepart(?1, ?3)"));
 		}

 		protected virtual void RegisterDefaultProperties()


Added self links.

Added self links.

--- ExampleService/HomeController.cs
+++ ExampleService/HomeController.cs
@@ -31,6 +31,12 @@
                             new AtomLinkModel
                             {
                                 Href = this.linker.GetUri<HomeController>(r =>
+                                    r.Get()).ToString(),
+                                Rel = "self"
+                            },
+                            new AtomLinkModel
+                            {
+                                Href = this.linker.GetUri<HomeController>(r =>
                                     r.Get("ploeh")).ToString(),
                                 Rel = "http://sample.ploeh.dk/rels/specific-home"
                             }
@@ -41,6 +47,12 @@
                         Name = "fnaah",
                         Links = new[]
                         {
+                            new AtomLinkModel
+                            {
+                                Href = this.linker.GetUri<HomeController>(r =>
+                                    r.Get()).ToString(),
+                                Rel = "self"
+                            },
                             new AtomLinkModel
                             {
                                 Href = this.linker.GetUri<HomeController>(r =>
@@ -63,6 +75,12 @@
                     new AtomLinkModel
                     {
                         Href = this.linker.GetUri<HomeController>(r =>
+                            r.Get(id)).ToString(),
+                        Rel = "self"
+                    },
+                    new AtomLinkModel
+                    {
+                        Href = this.linker.GetUri<HomeController>(r =>
                             r.Get()).ToString(),
                         Rel = "http://sample.ploeh.dk/rels/home"
                     }


Added extension points to JsonReferenceResolver, #263

--- src/NJsonSchema/JsonReferenceResolver.cs
+++ src/NJsonSchema/JsonReferenceResolver.cs
@@ -45,12 +45,7 @@
             }
             else if (jsonPath.StartsWith("#/"))
             {
-                var allSegments = jsonPath.Split('/').Skip(1).ToList();
-                var schema = ResolveReference(rootObject, allSegments, allSegments, new HashSet<object>());
-                if (schema == null)
-                    throw new InvalidOperationException("Could not resolve the path '" + jsonPath + "'.");
-
-                return schema;
+                return ResolveDocumentReference(rootObject, jsonPath);
             }
             else if (jsonPath.StartsWith("http://") || jsonPath.StartsWith("https://"))
                 return ResolveUrlReference(jsonPath, jsonPath);
@@ -78,7 +73,80 @@
             }
         }

-        private JsonSchema4 ResolveReference(object obj, List<string> segments, List<string> allSegments, HashSet<object> checkedObjects)
+        /// Resolves a document reference.
+        /// <param name="rootObject">The root object.</param>
+        /// <param name="jsonPath">The JSON path to resolve.</param>
+        /// <returns>The resolved JSON Schema.</returns>
+        /// <exception cref="InvalidOperationException">Could not resolve the JSON path.</exception>
+        protected virtual JsonSchema4 ResolveDocumentReference(object rootObject, string jsonPath)
+        {
+            var allSegments = jsonPath.Split('/').Skip(1).ToList();
+            var schema = ResolveDocumentReference(rootObject, allSegments, new HashSet<object>());
+            if (schema == null)
+                throw new InvalidOperationException("Could not resolve the path '" + jsonPath + "'.");
+
+            return schema;
+        }
+
+        /// Resolves a file reference.
+        /// <param name="fullJsonPath">The full JSON path to resolve.</param>
+        /// <param name="jsonPath">The JSON path to resolve.</param>
+        /// <returns>The resolved JSON Schema.</returns>
+        /// <exception cref="InvalidOperationException">Could not resolve the JSON path.</exception>
+        /// <exception cref="NotSupportedException">Could not resolve the JSON path because JSON web references are not supported on this platform.</exception>
+        protected virtual JsonSchema4 ResolveFileReference(string fullJsonPath, string jsonPath)
+        {
+            if (DynamicApis.SupportsFileApis)
+            {
+                try
+                {
+                    var arr = Regex.Split(fullJsonPath, @"(?=#)");
+
+                    if (!_resolvedSchemas.ContainsKey(arr[0]))
+                        JsonSchema4.FromFile(arr[0], this);
+
+                    var result = _resolvedSchemas[arr[0]];
+                    return arr.Length == 1 ? result : ResolveReference(result, arr[1]);
+                }
+                catch (Exception exception)
+                {
+                    throw new InvalidOperationException("Could not resolve the JSON path '" + jsonPath + "' with the file path '" + fullJsonPath + "': " + exception.Message, exception);
+                }
+            }
+            else
+                throw new NotSupportedException("Could not resolve the JSON path '" + jsonPath + "' because JSON file references are not supported on this platform.");
+        }
+
+        /// Resolves an URL reference.
+        /// <param name="fullJsonPath">The full JSON path to resolve.</param>
+        /// <param name="jsonPath">The JSON path to resolve.</param>
+        /// <returns>The resolved JSON Schema.</returns>
+        /// <exception cref="InvalidOperationException">Could not resolve the JSON path.</exception>
+        /// <exception cref="NotSupportedException">Could not resolve the JSON path because JSON web references are not supported on this platform.</exception>
+        protected virtual JsonSchema4 ResolveUrlReference(string fullJsonPath, string jsonPath)
+        {
+            if (DynamicApis.SupportsWebClientApis)
+            {
+                try
+                {
+                    var arr = fullJsonPath.Split('#');
+
+                    if (!_resolvedSchemas.ContainsKey(arr[0]))
+                        JsonSchema4.FromUrl(arr[0], this);
+
+                    var result = _resolvedSchemas[arr[0]];
+                    return arr.Length == 1 ? result : ResolveReference(result, "#" + arr[1]);
+                }
+                catch (Exception exception)
+                {
+                    throw new InvalidOperationException("Could not resolve the JSON path '" + jsonPath + "' with the URL '" + fullJsonPath + "': " + exception.Message, exception);
+                }
+            }
+            else
+                throw new NotSupportedException("Could not resolve the JSON path '" + jsonPath + "' because JSON web references are not supported on this platform.");
+        }
+
+        private JsonSchema4 ResolveDocumentReference(object obj, List<string> segments, HashSet<object> checkedObjects)
         {
             if (obj == null || obj is string || checkedObjects.Contains(obj))
                 return null;
@@ -92,7 +160,7 @@
             if (obj is IDictionary)
             {
                 if (((IDictionary)obj).Contains(firstSegment))
-                    return ResolveReference(((IDictionary)obj)[firstSegment], segments.Skip(1).ToList(), allSegments, checkedObjects);
+                    return ResolveDocumentReference(((IDictionary)obj)[firstSegment], segments.Skip(1).ToList(), checkedObjects);
             }
             else if (obj is IEnumerable)
             {
@@ -101,7 +169,7 @@
                 {
                     var enumerable = ((IEnumerable)obj).Cast<object>().ToArray();
                     if (enumerable.Length > index)
-                        return ResolveReference(enumerable[index], segments.Skip(1).ToList(), allSegments, checkedObjects);
+                        return ResolveDocumentReference(enumerable[index], segments.Skip(1).ToList(), checkedObjects);
                 }
             }
             else
@@ -112,60 +180,12 @@
                     if (pathSegment == firstSegment)
                     {
                         var value = member.GetValue(obj);
-                        return ResolveReference(value, segments.Skip(1).ToList(), allSegments, checkedObjects);
+                        return ResolveDocumentReference(value, segments.Skip(1).ToList(), checkedObjects);
                     }
                 }
             }

             return null;
         }
-
-        private JsonSchema4 ResolveFileReference(string url, string jsonPath)
-        {
-            if (DynamicApis.SupportsFileApis)
-            {
-                try
-                {
-                    var arr = Regex.Split(url, @"(?=#)");
-
-                    if (!_resolvedSchemas.ContainsKey(arr[0]))
-                        JsonSchema4.FromFile(arr[0], this);
-
-                    var result = _resolvedSchemas[arr[0]];
-                    return arr.Length == 1 ? result : ResolveReference(result, arr[1]);
-                }
-                catch (Exception exception)
-                {
-                    throw new InvalidOperationException("Could not resolve the path '" + jsonPath + "' with the file path '" + url + "': " + exception.Message, exception);
-                }
-            }
-            else
-                throw new NotSupportedException("Could not resolve the path '" + jsonPath +
-                    "' because JSON file references are not supported on this platform.");
-        }
-
-        private JsonSchema4 ResolveUrlReference(string filePath, string jsonPath)
-        {
-            if (DynamicApis.SupportsWebClientApis)
-            {
-                try
-                {
-                    var arr = filePath.Split('#');
-
-                    if (!_resolvedSchemas.ContainsKey(arr[0]))
-                        JsonSchema4.FromUrl(arr[0], this);
-
-                    var result = _resolvedSchemas[arr[0]];
-                    return arr.Length == 1 ? result : ResolveReference(result, "#" + arr[1]);
-                }
-                catch (Exception exception)
-                {
-                    throw new InvalidOperationException("Could not resolve the path '" + jsonPath + "' with the URL '" + filePath + "': " + exception.Message, exception);
-                }
-            }
-            else
-                throw new NotSupportedException("Could not resolve the path '" + jsonPath +
-                    "' because JSON web references are not supported on this platform.");
-        }
     }
 }


performance tuning.

performance tuning.

--- Project/Performance/Program.cs
+++ Project/Performance/Program.cs
@@ -13,7 +13,7 @@
     {
         static void Main(string[] args)
         {
-            Test1();
+            Test2();
         }

         public class SelectedData
@@ -127,8 +127,54 @@
             Console.ReadKey();
         }

+        static void Test3()
+        {
+            Console.ReadKey();
+            Console.WriteLine("Start");
+            var times = new List<double>();
+            var watch = new Stopwatch();

-    }
+
+            for (int i = 0; i < 10000; i++)
+            {
+                watch.Start();
+
+                DbX<Data>.Sql(db =>
+
+                    Select(new SelectedData()
+                    {
+                        name = db.tbl_staff.name,
+                        payment_date = db.tbl_remuneration.payment_date,
+                        money = db.tbl_remuneration.money,
+                    }).
+                    From(db.tbl_remuneration).
+                        Join(db.tbl_staff, db.tbl_remuneration.staff_id == db.tbl_staff.id).
+                    Where(3000 < db.tbl_remuneration.money && db.tbl_remuneration.money < 4000));
+
+                watch.Stop();
+                if (i != 0)
+                {
+                    times.Add(watch.Elapsed.TotalMilliseconds);
+                }
+                watch.Reset();
+
+            }
+
+            times = times.Skip(1).ToList();
+            times.Select(e => e.ToString()).ToList().ForEach(e => Console.WriteLine(e));
+            Console.WriteLine(times.Average().ToString());
+            Console.ReadKey();
+        }
+
+        public class DbX<T> where T : class
+        {
+            public static Expression e;
+            public static void Sql<TSelected>(Expression<Func<T, ClauseChain<TSelected>>> expression)
+            {
+                e = expression;
+            }
+        }
+        }

     class XXX<TDB>
     {


Add anyOf schema reference handling, closes https://github.com/RicoSuter/NSwag/issues/2107

--- src/NJsonSchema/JsonSchema4.Reference.cs
+++ src/NJsonSchema/JsonSchema4.Reference.cs
@@ -42,9 +42,9 @@
             }
         }

-        /// Gets a value indicating whether this is a schema reference ($ref, <see cref="HasAllOfSchemaReference"/> or <see cref="HasOneOfSchemaReference"/>).
+        /// Gets a value indicating whether this is a schema reference ($ref, <see cref="HasAllOfSchemaReference"/>, <see cref="HasOneOfSchemaReference"/> or <see cref="HasAnyOfSchemaReference"/>).
         [JsonIgnore]
-        public bool HasReference => Reference != null || HasAllOfSchemaReference || HasOneOfSchemaReference;
+        public bool HasReference => Reference != null || HasAllOfSchemaReference || HasOneOfSchemaReference || HasAnyOfSchemaReference;

         /// Gets a value indicating whether this is an allOf schema reference.
         [JsonIgnore]
@@ -74,6 +74,20 @@
                                                MultipleOf == null &&
                                                IsEnumeration == false;

+        /// Gets a value indicating whether this is an anyOf schema reference.
+        [JsonIgnore]
+        public bool HasAnyOfSchemaReference => AnyOf.Count == 1 &&
+                                               AnyOf.Any(s => s.HasReference) &&
+                                               Type == JsonObjectType.None &&
+                                               AllOf.Count == 0 &&
+                                               OneOf.Count == 0 &&
+                                               Properties.Count == 0 &&
+                                               PatternProperties.Count == 0 &&
+                                               AllowAdditionalProperties &&
+                                               AdditionalPropertiesSchema == null &&
+                                               MultipleOf == null &&
+                                               IsEnumeration == false;
+
         /// Gets or sets the type reference.
         [JsonIgnore]
         [Obsolete("Use the Reference property instead.")]
@@ -83,7 +97,7 @@
             set => Reference = value;
         }

-        /// Gets a value indicating whether this is a schema reference ($ref, <see cref="HasAllOfSchemaReference"/> or <see cref="HasOneOfSchemaReference"/>).
+        /// Gets a value indicating whether this is a schema reference ($ref, <see cref="HasAllOfSchemaReference"/>, <see cref="HasOneOfSchemaReference"/> or <see cref="HasAnyOfSchemaReference"/>).
         [JsonIgnore]
         [Obsolete("Use the HasReference property instead.")]
         public bool HasSchemaReference => HasReference;
@@ -107,6 +121,9 @@

                 if (HasOneOfSchemaReference)
                     return OneOf.First().GetActualSchema(checkedSchemas);
+
+                if (HasAnyOfSchemaReference)
+                    return AnyOf.First().GetActualSchema(checkedSchemas);

                 return Reference.GetActualSchema(checkedSchemas);
             }


Examples: Make sure example is set up to send only 20 messages

--- Examples/SimpleSender/Program.cs
+++ Examples/SimpleSender/Program.cs
@@ -31,7 +31,7 @@
             var loggerFactory = new LoggerFactory();
             var connection = new ServiceBusConnection(_connectionString, loggerFactory.CreateLogger<ServiceBusConnection>());
             IMessagingSender sender = null;
-            var messageCount = 20000;
+            var messageCount = 20;
             try
             {
                 var linkFactory = new LinkFactory(connection, loggerFactory.CreateLogger<LinkFactory>());


Improve error message on version incompatibility (#2172)

--- src/NSwag.AspNetCore.Launcher/Program.cs
+++ src/NSwag.AspNetCore.Launcher/Program.cs
@@ -188,7 +188,7 @@
                 var assemblyInfo = item.Value;
                 if (loadedAssembly.GetName().Version < assemblyInfo.MinimumRequiredVersion)
                 {
-                    Console.Error.WriteLine("Application references version lower than required.");
+                    Console.Error.WriteLine($"Application references version '{loadedAssembly.GetName().Version}' of '{item.Key}' which is lower than the required version '{assemblyInfo.MinimumRequiredVersion}'.");
                     return false;
                 }


UI: Added version to window title

UI: Added version to window title

--- src/NSwagStudio/Views/MainWindow.xaml.cs
+++ src/NSwagStudio/Views/MainWindow.xaml.cs
@@ -27,7 +27,7 @@
             LoadWindowState();
             RegisterFileOpenHandler();

-            Title += IntPtr.Size == 4 ? " (x86)" : " (x64)";
+            Title += IntPtr.Size == 4 ? " (x86), v" : " (x64), v" + Model.NSwagVersion;
         }

         private MainWindowModel Model => (MainWindowModel)Resources["ViewModel"];


增加一个private_playurl方法

--- QiniuSample/VideoController.cs
+++ QiniuSample/VideoController.cs
@@ -217,6 +217,18 @@
             return GetDownloadUrl(fileKey);
         }

+        [HttpGet]
+        [ActionName("private-playurl")]
+        public HttpResponseMessage PrivatePlayUrl(int videoId)
+        {
+            //refer to: http://developer.qiniu.com/docs/v6/sdk/csharp-sdk.html#private-download
+            //refer to: http://developer.qiniu.com/docs/v6/api/reference/fop/av/pm3u8.html
+
+            //根据Video Id获取到视频缩略图对应的m3u8文件Key
+            string fileKey = "m3u8_8262811ab0894fadb7b4f72c488e3af0.m3u?pm3u8/0";
+            return GetDownloadUrl(fileKey);
+        }
+
         private HttpResponseMessage GetDownloadUrl(string fileKey)
         {
             string baseUrl = GetPolicy.MakeBaseUrl(domain, fileKey);


rm unused

rm unused

--- FluentFTP/Utils/FtpReflection.cs
+++ FluentFTP/Utils/FtpReflection.cs
@@ -1,93 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-#if !NETSTANDARD
-using System.Reflection;
-using System.Linq;
-
-#endif
-
-namespace FluentFTP {
-	internal static class FtpReflection {
-#if !NETSTANDARD
-		public static object GetField(this object obj, string fieldName) {
-			var tp = obj.GetType();
-			var info = GetAllFields(tp).Where(f => f.Name == fieldName).Single();
-			return info.GetValue(obj);
-		}
-
-		public static void SetField(this object obj, string fieldName, object value) {
-			var tp = obj.GetType();
-			var info = GetAllFields(tp).Where(f => f.Name == fieldName).Single();
-			info.SetValue(obj, value);
-		}
-
-		public static object GetStaticField(this Assembly assembly, string typeName, string fieldName) {
-			var tp = assembly.GetType(typeName);
-			var info = GetAllFields(tp).Where(f => f.IsStatic).Where(f => f.Name == fieldName).Single();
-			return info.GetValue(null);
-		}
-
-		public static object GetProperty(this object obj, string propertyName) {
-			var tp = obj.GetType();
-			var info = GetAllProperties(tp).Where(f => f.Name == propertyName).Single();
-			return info.GetValue(obj, null);
-		}
-
-		public static object CallMethod(this object obj, string methodName, params object[] prm) {
-			var tp = obj.GetType();
-			var info = GetAllMethods(tp).Where(f => f.Name == methodName && f.GetParameters().Length == prm.Length).Single();
-			var rez = info.Invoke(obj, prm);
-			return rez;
-		}
-
-		public static object NewInstance(this Assembly assembly, string typeName, params object[] prm) {
-			var tp = assembly.GetType(typeName);
-			var info = tp.GetConstructors().Where(f => f.GetParameters().Length == prm.Length).Single();
-			var rez = info.Invoke(prm);
-			return rez;
-		}
-
-		public static object InvokeStaticMethod(this Assembly assembly, string typeName, string methodName, params object[] prm) {
-			var tp = assembly.GetType(typeName);
-			var info = GetAllMethods(tp).Where(f => f.IsStatic).Where(f => f.Name == methodName && f.GetParameters().Length == prm.Length).Single();
-			var rez = info.Invoke(null, prm);
-			return rez;
-		}
-
-		public static object GetEnumValue(this Assembly assembly, string typeName, int value) {
-			var tp = assembly.GetType(typeName);
-			var rez = Enum.ToObject(tp, value);
-			return rez;
-		}
-
-		private static IEnumerable<FieldInfo> GetAllFields(Type t) {
-			if (t == null) {
-				return Enumerable.Empty<FieldInfo>();
-			}
-
-			var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-			return t.GetFields(flags).Concat(GetAllFields(t.BaseType));
-		}
-
-		private static IEnumerable<PropertyInfo> GetAllProperties(Type t) {
-			if (t == null) {
-				return Enumerable.Empty<PropertyInfo>();
-			}
-
-			var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-			return t.GetProperties(flags).Concat(GetAllProperties(t.BaseType));
-		}
-
-		private static IEnumerable<MethodInfo> GetAllMethods(Type t) {
-			if (t == null) {
-				return Enumerable.Empty<MethodInfo>();
-			}
-
-			var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-			return t.GetMethods(flags).Concat(GetAllMethods(t.BaseType));
-		}
-
-#endif
-	}
-}


Remove unused field.

Remove unused field.

--- binder/Generators/Template.cs
+++ binder/Generators/Template.cs
@@ -8,9 +8,6 @@
     {
         public BindingContext Context { get; private set; }
         public Options Options { get; private set; }
-
-
-        public Assembly Assembly { get; set; }

         protected Template(BindingContext context, Options options)
         {


Added silent output

Added silent output

--- Addons/Entitas.CodeGeneration.CodeGenerator.CLI/Program.cs
+++ Addons/Entitas.CodeGeneration.CodeGenerator.CLI/Program.cs
@@ -63,7 +63,7 @@
                         _logger.Error(e.ToString());
                     }
                 } else {
-                    if(args.Any(arg => arg == "-v")) {
+                    if(isVerbose(args)) {
                         _logger.Error(ex.ToString());
                     } else {
                         _logger.Error(ex.Message);
@@ -83,13 +83,24 @@
        entitas scan     - Scans and prints available types found in specified assemblies
        entitas dry      - Simulates generating files without writing to disk
        entitas gen      - Generates files based on Entitas.properties
-       [-v]             - verbose output"
+       [-v]             - verbose output
+       [-s]             - silent output (errors only)"
             );
         }

+        static bool isVerbose(string[] args) {
+            return args.Any(arg => arg == "-v");
+        }
+
+        static bool isSilent(string[] args) {
+            return args.Any(arg => arg == "-s");
+        }
+
         static void setupLogging(string[] args) {
-            if(args.Any(arg => arg == "-v")) {
+            if(isVerbose(args)) {
                 fabl.globalLogLevel = LogLevel.On;
+            } else if(isSilent(args)) {
+                fabl.globalLogLevel = LogLevel.Error;
             } else {
                 fabl.globalLogLevel = LogLevel.Info;
             }