diff --git a/Intersect.Server/Entities/Player.cs b/Intersect.Server/Entities/Player.cs
index 985e804ef8..28f1d927ac 100644
--- a/Intersect.Server/Entities/Player.cs
+++ b/Intersect.Server/Entities/Player.cs
@@ -3629,17 +3629,7 @@ public void CloseCraftingTable()
         //Craft a new item
         public void CraftItem()
         {
-            if (OpenCraftingTableId == default)
-            {
-                return;
-            }
-
-            if (!CraftingTableBase.TryGet(OpenCraftingTableId, out var table))
-            {
-                return;
-            }
-
-            if (!table.Crafts.Contains(CraftingState?.Id ?? default))
+            if(ShouldCancelCrafting())
             {
                 return;
             }
@@ -3649,12 +3639,6 @@ public void CraftItem()
                 return;
             }
 
-            if (!Conditions.MeetsConditionLists(craftDescriptor.CraftingRequirements, this, null))
-            {
-                PacketSender.SendChatMsg(this, Strings.Crafting.RequirementsNotMet.ToString(), ChatMessageType.Error);
-                return;
-            }
-
             var backupItems = new List<Item>();
             foreach (var backupItem in Items)
             {
@@ -3662,57 +3646,45 @@ public void CraftItem()
             }
 
             var craftItem = ItemBase.Get(craftDescriptor.ItemId);
-            if (craftItem == null)
-            {
-                PacketSender.SendChatMsg(this, Strings.Errors.UnknownErrorTryAgain, ChatMessageType.Error, CustomColors.Alerts.Error);
-                Log.Error($"Unable to find item descriptor {craftItem.Id} for craft {craftDescriptor.Id}.");
-                return;
-            }
 
-            //Quickly Look through the inventory and create a catalog of what items we have, and how many
-            var inventoryItems = new Dictionary<Guid, int>();
-            foreach (var inventoryItem in Items)
+            lock (EntityLock)
             {
-                if (inventoryItem == null)
+                var craftRoll = Randomization.Next(0, 101);
+                var failedCraft = craftRoll < craftDescriptor.FailureChance;
+                if (failedCraft)
                 {
-                    continue;
-                }
+                    var message = Strings.Crafting.CraftFailure;
 
-                var quantity = inventoryItem.Quantity;
-                if (inventoryItems.TryGetValue(inventoryItem.ItemId, out var currentQuantitySum))
-                {
-                    quantity += currentQuantitySum;
-                }
-                inventoryItems[inventoryItem.ItemId] = quantity;
-            }
+                    var itemLossRoll = Randomization.Next(0, 101);
+                    var itemLost = itemLossRoll < craftDescriptor.ItemLossChance;
+                    if (itemLost)
+                    {
+                        //Take the items
+                        foreach (var ingredient in craftDescriptor.Ingredients)
+                        {
+                            if (TryTakeItem(ingredient.ItemId, ingredient.Quantity))
+                            {
+                                continue;
+                            }
 
-            //Check the player actually has the items
-            foreach (var ingredient in craftDescriptor.Ingredients)
-            {
-                if (!inventoryItems.TryGetValue(ingredient.ItemId, out var currentQuantity))
-                {
-                    CraftingState.Id = Guid.Empty;
-                    return;
-                }
+                            for (var i = 0; i < backupItems.Count; i++)
+                            {
+                                Items[i].Set(backupItems[i]);
+                            }
 
-                if (currentQuantity < ingredient.Quantity)
-                {
-                    CraftingState.Id = Guid.Empty;
-                    return;
-                }
+                            PacketSender.SendInventory(this);
+                            CraftingState.RemainingCount--;
 
-                inventoryItems[ingredient.ItemId] = currentQuantity - ingredient.Quantity;
-            }
+                            return;
+                        }
 
-            var craftRoll = Randomization.Next(0, 101);
-            var failedCraft = craftRoll < craftDescriptor.FailureChance;
-            if (failedCraft)
-            {
-                var message = Strings.Crafting.CraftFailure;
+                        message = Strings.Crafting.CraftFailureLostItems;
+                    }
 
-                var itemLossRoll = Randomization.Next(0, 101);
-                var itemLost = itemLossRoll < craftDescriptor.ItemLossChance;
-                if (itemLost)
+                    PacketSender.SendInventory(this);
+                    PacketSender.SendChatMsg(this, message.ToString(craftItem.Name), ChatMessageType.Crafting, CustomColors.Alerts.Error);
+                }
+                else
                 {
                     //Take the items
                     foreach (var ingredient in craftDescriptor.Ingredients)
@@ -3722,9 +3694,9 @@ public void CraftItem()
                             continue;
                         }
 
-                        for (var i = 0; i < backupItems.Count; i++)
+                        for (var slotIndex = 0; slotIndex < backupItems.Count; slotIndex++)
                         {
-                            Items[i].Set(backupItems[i]);
+                            Items[slotIndex].Set(backupItems[slotIndex]);
                         }
 
                         PacketSender.SendInventory(this);
@@ -3733,110 +3705,113 @@ public void CraftItem()
                         return;
                     }
 
-                    message = Strings.Crafting.CraftFailureLostItems;
-                }
-
-                PacketSender.SendInventory(this);
-                PacketSender.SendChatMsg(this, message.ToString(craftItem.Name), ChatMessageType.Crafting, CustomColors.Alerts.Error);
-            }
-            else
-            {
-                //Take the items
-                foreach (var ingredient in craftDescriptor.Ingredients)
-                {
-                    if (TryTakeItem(ingredient.ItemId, ingredient.Quantity))
+                    //Give them the craft
+                    var quantity = Math.Max(craftDescriptor.Quantity, 1);
+                    if (!craftItem.IsStackable)
                     {
-                        continue;
+                        quantity = 1;
                     }
 
-                    for (var slotIndex = 0; slotIndex < backupItems.Count; slotIndex++)
+                    if (TryGiveItem(craftItem.Id, quantity))
                     {
-                        Items[slotIndex].Set(backupItems[slotIndex]);
-                    }
-
-                    PacketSender.SendInventory(this);
-                    CraftingState.RemainingCount--;
-
-                    return;
-                }
-
-                //Give them the craft
-                var quantity = Math.Max(craftDescriptor.Quantity, 1);
-                if (!craftItem.IsStackable)
-                {
-                    quantity = 1;
-                }
-
-                if (TryGiveItem(craftItem.Id, quantity))
-                {
-                    PacketSender.SendChatMsg(
-                        this, Strings.Crafting.crafted.ToString(craftItem.Name), ChatMessageType.Crafting,
-                        CustomColors.Alerts.Success
-                    );
+                        PacketSender.SendChatMsg(
+                            this, Strings.Crafting.crafted.ToString(craftItem.Name), ChatMessageType.Crafting,
+                            CustomColors.Alerts.Success
+                        );
 
-                    if (craftDescriptor.Event != default)
-                    {
-                        EnqueueStartCommonEvent(craftDescriptor.Event);
+                        if (craftDescriptor.Event != default)
+                        {
+                            EnqueueStartCommonEvent(craftDescriptor.Event);
+                        }
                     }
-                }
-                else
-                {
-                    for (var i = 0; i < backupItems.Count; i++)
+                    else
                     {
-                        Items[i].Set(backupItems[i]);
-                    }
+                        for (var i = 0; i < backupItems.Count; i++)
+                        {
+                            Items[i].Set(backupItems[i]);
+                        }
 
-                    PacketSender.SendInventory(this);
-                    PacketSender.SendChatMsg(
-                        this, Strings.Crafting.nospace.ToString(craftItem.Name), ChatMessageType.Crafting,
-                        CustomColors.Alerts.Error
-                    );
+                        PacketSender.SendInventory(this);
+                        PacketSender.SendChatMsg(
+                            this, Strings.Crafting.nospace.ToString(craftItem.Name), ChatMessageType.Crafting,
+                            CustomColors.Alerts.Error
+                        );
+                    }
                 }
-            }
 
-            CraftingState.RemainingCount--;
+                CraftingState.RemainingCount--;
+            }
         }
 
         public bool ShouldCancelCrafting()
         {
+            if (OpenCraftingTableId == default)
+            {
+                return true;
+            }
+
+            if (!CraftingTableBase.TryGet(OpenCraftingTableId, out var table))
+            {
+                return true;
+            }
+
+            if (!table.Crafts.Contains(CraftingState?.Id ?? default))
+            {
+                return true;
+            }
+
             if (!CraftBase.TryGet(CraftingState?.Id ?? default, out var craftDescriptor))
             {
                 return true;
             }
 
-            //See if we have lost the items needed for our current craft, if so end the crafting session
+            if (!Conditions.MeetsConditionLists(craftDescriptor.CraftingRequirements, this, null))
+            {
+                PacketSender.SendChatMsg(this, Strings.Crafting.RequirementsNotMet.ToString(), ChatMessageType.Error);
+                return true;
+            }
+
+            var craftItem = ItemBase.Get(craftDescriptor.ItemId);
+            if (craftItem == null)
+            {
+                PacketSender.SendChatMsg(this, Strings.Errors.UnknownErrorTryAgain, ChatMessageType.Error, CustomColors.Alerts.Error);
+                Log.Error($"Unable to find item descriptor {craftItem.Id} for craft {craftDescriptor.Id}.");
+                return true;
+            }
+
             //Quickly Look through the inventory and create a catalog of what items we have, and how many
             var inventoryItems = new Dictionary<Guid, int>();
-            foreach (var item in Items)
+            foreach (var inventoryItem in Items)
             {
-                if (item == default)
+                if (inventoryItem == null)
                 {
                     continue;
                 }
 
-                var quantity = item.Quantity;
-                if (inventoryItems.TryGetValue(item.ItemId, out var quantitySum))
+                var quantity = inventoryItem.Quantity;
+                if (inventoryItems.TryGetValue(inventoryItem.ItemId, out var currentQuantitySum))
                 {
-                    quantity += quantitySum;
+                    quantity += currentQuantitySum;
                 }
-
-                inventoryItems[item.ItemId] = quantity;
+                inventoryItems[inventoryItem.ItemId] = quantity;
             }
 
             //Check the player actually has the items
             foreach (var ingredient in craftDescriptor.Ingredients)
             {
-                if (!inventoryItems.TryGetValue(ingredient.ItemId, out int quantity))
+                if (!inventoryItems.TryGetValue(ingredient.ItemId, out var currentQuantity))
                 {
+                    CraftingState.Id = Guid.Empty;
                     return true;
                 }
 
-                if (quantity < ingredient.Quantity)
+                if (currentQuantity < ingredient.Quantity)
                 {
+                    CraftingState.Id = Guid.Empty;
                     return true;
                 }
 
-                inventoryItems[ingredient.ItemId] = quantity - ingredient.Quantity;
+                inventoryItems[ingredient.ItemId] = currentQuantity - ingredient.Quantity;
             }
 
             return false;
diff --git a/Intersect.Server/Networking/PacketHandler.cs b/Intersect.Server/Networking/PacketHandler.cs
index abff585ad2..3074245c78 100644
--- a/Intersect.Server/Networking/PacketHandler.cs
+++ b/Intersect.Server/Networking/PacketHandler.cs
@@ -1885,37 +1885,42 @@ public void HandlePacket(Client client, CraftItemPacket packet)
                 return;
             }
 
-            if (packet.CraftId == default)
+            lock(player.EntityLock)
             {
-                player.CraftingState = default;
-            }
+                //if player hit stop button in crafting window
+                if (packet.CraftId == default)
+                {
+                    player.CraftingState = default;
+                    return;
+                }
 
-            if (!CraftBase.TryGet(packet.CraftId, out var craftDescriptor))
-            {
-                Log.Warn($"Player {player.Id} tried to craft {packet.CraftId} which does not exist.");
-                return;
-            }
+                if (!CraftBase.TryGet(packet.CraftId, out var craftDescriptor))
+                {
+                    Log.Warn($"Player {player.Id} tried to craft {packet.CraftId} which does not exist.");
+                    return;
+                }
 
-            if (player.OpenCraftingTableId == default)
-            {
-                Log.Warn($"Player {player.Id} tried to craft {packet.CraftId} without having opened a table yet.");
-                return;
-            }
+                if (player.OpenCraftingTableId == default)
+                {
+                    Log.Warn($"Player {player.Id} tried to craft {packet.CraftId} without having opened a table yet.");
+                    return;
+                }
 
-            if (player.CraftingState != default)
-            {
-                PacketSender.SendChatMsg(player, Strings.Crafting.AlreadyCrafting, ChatMessageType.Crafting, CustomColors.Alerts.Error);
-                return;
-            }
+                if (player.CraftingState != default)
+                {
+                    PacketSender.SendChatMsg(player, Strings.Crafting.AlreadyCrafting, ChatMessageType.Crafting, CustomColors.Alerts.Error);
+                    return;
+                }
 
-            player.CraftingState = new CraftingState
-            {
-                Id = packet.CraftId,
-                CraftCount = packet.Count,
-                RemainingCount = packet.Count,
-                DurationPerCraft = craftDescriptor.Time,
-                NextCraftCompletionTime = Timing.Global.Milliseconds + craftDescriptor.Time
-            };
+                player.CraftingState = new CraftingState
+                {
+                    Id = packet.CraftId,
+                    CraftCount = packet.Count,
+                    RemainingCount = packet.Count,
+                    DurationPerCraft = craftDescriptor.Time,
+                    NextCraftCompletionTime = Timing.Global.Milliseconds + craftDescriptor.Time
+                };
+            }
         }
 
         //CloseBankPacket