From 1b2f64473ed4f222d3b7f02df853730d4382105e Mon Sep 17 00:00:00 2001
From: Loic Blot <loic.blot@unix-experience.fr>
Date: Wed, 4 Mar 2015 11:29:34 +0100
Subject: [PATCH] Send Inventory packet on event, don't check it at each
 AsyncRunStep. * Call UpdateCrafting into SendInventory because this functions
 is only called before SendInventory * Use Player* instead of peer_id for
 UpdateCrafting because SendInventory already has the Player* pointer, then
 don't loop for searching Player* per peer_id * m_env_mutex don't need to be
 used with this modification because it's already locked before the calls

---
 src/content_sao.cpp                   |  6 ------
 src/content_sao.h                     |  2 --
 src/network/packethandlers/server.cpp |  4 +++-
 src/script/lua_api/l_object.cpp       |  3 +++
 src/server.cpp                        | 19 ++++---------------
 src/server.h                          |  8 +++++---
 src/serverobject.cpp                  |  9 ++-------
 7 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 0600689e4..ad48f95fb 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -717,7 +717,6 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
 	m_attachment_sent(false),
 	// public
 	m_moved(false),
-	m_inventory_not_sent(false),
 	m_physics_override_speed(1),
 	m_physics_override_jump(1),
 	m_physics_override_gravity(1),
@@ -1162,11 +1161,6 @@ InventoryLocation PlayerSAO::getInventoryLocation() const
 	return loc;
 }
 
-void PlayerSAO::setInventoryModified()
-{
-	m_inventory_not_sent = true;
-}
-
 std::string PlayerSAO::getWieldList() const
 {
 	return "main";
diff --git a/src/content_sao.h b/src/content_sao.h
index 6b7304944..a93029154 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -205,7 +205,6 @@ class PlayerSAO : public ServerActiveObject
 	Inventory* getInventory();
 	const Inventory* getInventory() const;
 	InventoryLocation getInventoryLocation() const;
-	void setInventoryModified();
 	std::string getWieldList() const;
 	int getWieldIndex() const;
 	void setWieldIndex(int i);
@@ -317,7 +316,6 @@ class PlayerSAO : public ServerActiveObject
 public:
 	// Some flags used by Server
 	bool m_moved;
-	bool m_inventory_not_sent;
 
 	float m_physics_override_speed;
 	float m_physics_override_jump;
diff --git a/src/network/packethandlers/server.cpp b/src/network/packethandlers/server.cpp
index 2deede0ca..9dd1c95dd 100644
--- a/src/network/packethandlers/server.cpp
+++ b/src/network/packethandlers/server.cpp
@@ -1390,7 +1390,9 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
 			// Placement was handled in lua
 
 			// Apply returned ItemStack
-			playersao->setWieldedItem(item);
+			if (playersao->setWieldedItem(item)) {
+				SendInventory(pkt->getPeerId());
+			}
 		}
 
 		// If item has node placement prediction, always send the
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 0bc6c0bbc..0f3848aac 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -355,6 +355,9 @@ int ObjectRef::l_set_wielded_item(lua_State *L)
 	// Do it
 	ItemStack item = read_item(L, 2, getServer(L));
 	bool success = co->setWieldedItem(item);
+	if (success && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
+		getServer(L)->SendInventory(((PlayerSAO*)co)->getPeerID());
+	}
 	lua_pushboolean(L, success);
 	return 1;
 }
diff --git a/src/server.cpp b/src/server.cpp
index cafeb951d..0bb91d758 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -609,14 +609,6 @@ void Server::AsyncRunStep(bool initial_step)
 				SendMovePlayer(*i);
 				playersao->m_moved = false;
 			}
-
-			/*
-				Send player inventories if necessary
-			*/
-			if(playersao->m_inventory_not_sent) {
-				UpdateCrafting(*i);
-				SendInventory(*i);
-			}
 		}
 	}
 
@@ -1164,7 +1156,6 @@ PlayerSAO* Server::StageTwoClientInit(u16 peer_id)
 	SendPlayerInventoryFormspec(peer_id);
 
 	// Send inventory
-	UpdateCrafting(peer_id);
 	SendInventory(peer_id);
 
 	// Send HP
@@ -1385,7 +1376,8 @@ void Server::setInventoryModified(const InventoryLocation &loc)
 		PlayerSAO *playersao = player->getPlayerSAO();
 		if(!playersao)
 			return;
-		playersao->m_inventory_not_sent = true;
+
+		SendInventory(playersao->getPeerID());
 	}
 		break;
 	case InventoryLocation::NODEMETA:
@@ -1650,7 +1642,7 @@ void Server::SendInventory(u16 peer_id)
 	PlayerSAO *playersao = getPlayerSAO(peer_id);
 	assert(playersao);
 
-	playersao->m_inventory_not_sent = false;
+	UpdateCrafting(playersao->getPlayer());
 
 	/*
 		Serialize it
@@ -2701,13 +2693,10 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason)
 		SendChatMessage(PEER_ID_INEXISTENT,message);
 }
 
-void Server::UpdateCrafting(u16 peer_id)
+void Server::UpdateCrafting(Player* player)
 {
 	DSTACK(__FUNCTION_NAME);
 
-	Player* player = m_env->getPlayer(peer_id);
-	assert(player);
-
 	// Get a preview for crafting
 	ItemStack preview;
 	InventoryLocation loc;
diff --git a/src/server.h b/src/server.h
index 8c5ea2e1e..b3d5d0fec 100644
--- a/src/server.h
+++ b/src/server.h
@@ -375,6 +375,9 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 	void SendPlayerHPOrDie(u16 peer_id, bool die) { die ? DiePlayer(peer_id) : SendPlayerHP(peer_id); }
 	void SendPlayerBreath(u16 peer_id);
 
+	// Envlock and conlock should be locked when calling these
+	void SendInventory(u16 peer_id);
+
 	// Bind address
 	Address m_bind_addr;
 
@@ -394,8 +397,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 	/* mark blocks not sent for all clients */
 	void SetBlocksNotSent(std::map<v3s16, MapBlock *>& block);
 
-	// Envlock and conlock should be locked when calling these
-	void SendInventory(u16 peer_id);
+
 	void SendChatMessage(u16 peer_id, const std::wstring &message);
 	void SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed);
 	void SendPlayerHP(u16 peer_id);
@@ -466,7 +468,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 	void DiePlayer(u16 peer_id);
 	void RespawnPlayer(u16 peer_id);
 	void DeleteClient(u16 peer_id, ClientDeletionReason reason);
-	void UpdateCrafting(u16 peer_id);
+	void UpdateCrafting(Player *player);
 
 	// When called, connection mutex should be locked
 	RemoteClient* getClient(u16 peer_id,ClientState state_min=CS_Active);
diff --git a/src/serverobject.cpp b/src/serverobject.cpp
index 9cf817859..699040bf2 100644
--- a/src/serverobject.cpp
+++ b/src/serverobject.cpp
@@ -90,14 +90,9 @@ ItemStack ServerActiveObject::getWieldedItem() const
 
 bool ServerActiveObject::setWieldedItem(const ItemStack &item)
 {
-	Inventory *inv = getInventory();
-	if(inv)
-	{
-		InventoryList *list = inv->getList(getWieldList());
-		if (list)
-		{
+	if(Inventory *inv = getInventory()) {
+		if (InventoryList *list = inv->getList(getWieldList())) {
 			list->changeItem(getWieldIndex(), item);
-			setInventoryModified();
 			return true;
 		}
 	}
-- 
GitLab