From 280946ba836cde9516f9344f47561f3356bdf869 Mon Sep 17 00:00:00 2001
From: PilzAdam <pilzadam@minetest.net>
Date: Fri, 28 Jun 2013 14:06:34 +0000
Subject: [PATCH] Dont write player files all the time

---
 src/environment.cpp |  3 +++
 src/inventory.cpp   | 33 +++++++++++++++++++++++++++++++++
 src/inventory.h     |  2 ++
 src/player.cpp      | 11 ++++++++++-
 src/player.h        | 23 +++++++++++++++++++++++
 5 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/src/environment.cpp b/src/environment.cpp
index 4b785998b..21a6258b7 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -434,6 +434,7 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
 		//infostream<<"Found matching player, overwriting."<<std::endl;
 
 		// OK, found. Save player there.
+		if(player->checkModified())
 		{
 			// Open file and serialize
 			std::ofstream os(path.c_str(), std::ios_base::binary);
@@ -444,6 +445,8 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
 			}
 			player->serialize(os);
 			saved_players.insert(player);
+		} else {
+			saved_players.insert(player);
 		}
 	}
 
diff --git a/src/inventory.cpp b/src/inventory.cpp
index d6815d329..928021c2f 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -562,6 +562,26 @@ InventoryList & InventoryList::operator = (const InventoryList &other)
 	return *this;
 }
 
+bool InventoryList::operator == (const InventoryList &other)
+{
+	if(m_size != other.m_size)
+		return false;
+	if(m_width != other.m_width)
+		return false;
+	if(m_name != other.m_name)
+		return false;
+	for(u32 i=0; i<m_items.size(); i++)
+	{
+		ItemStack s1 = m_items[i];
+		ItemStack s2 = other.m_items[i];
+		if(s1.name != s2.name || s1.wear!= s2.wear || s1.count != s2.count ||
+				s1.metadata != s2.metadata)
+			return false;
+	}
+
+	return true;
+}
+
 const std::string &InventoryList::getName() const
 {
 	return m_name;
@@ -855,6 +875,19 @@ Inventory & Inventory::operator = (const Inventory &other)
 	return *this;
 }
 
+bool Inventory::operator == (const Inventory &other)
+{
+	if(m_lists.size() != other.m_lists.size())
+		return false;
+
+	for(u32 i=0; i<m_lists.size(); i++)
+	{
+		if(m_lists[i] != other.m_lists[i])
+			return false;
+	}
+	return true;
+}
+
 void Inventory::serialize(std::ostream &os) const
 {
 	for(u32 i=0; i<m_lists.size(); i++)
diff --git a/src/inventory.h b/src/inventory.h
index 676088b94..1a66a13a4 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -183,6 +183,7 @@ class InventoryList
 
 	InventoryList(const InventoryList &other);
 	InventoryList & operator = (const InventoryList &other);
+	bool operator == (const InventoryList &other);
 
 	const std::string &getName() const;
 	u32 getSize() const;
@@ -258,6 +259,7 @@ class Inventory
 	Inventory(IItemDefManager *itemdef);
 	Inventory(const Inventory &other);
 	Inventory & operator = (const Inventory &other);
+	bool operator == (const Inventory &other);
 	
 	void serialize(std::ostream &os) const;
 	void deSerialize(std::istream &is);
diff --git a/src/player.cpp b/src/player.cpp
index ec1e3aff7..2a7a3084c 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -44,7 +44,12 @@ Player::Player(IGameDef *gamedef):
 	m_yaw(0),
 	m_speed(0,0,0),
 	m_position(0,0,0),
-	m_collisionbox(-BS*0.30,0.0,-BS*0.30,BS*0.30,BS*1.55,BS*0.30)
+	m_collisionbox(-BS*0.30,0.0,-BS*0.30,BS*0.30,BS*1.55,BS*0.30),
+	m_last_pitch(0),
+	m_last_yaw(0),
+	m_last_pos(0,0,0),
+	m_last_hp(PLAYER_MAX_HP),
+	m_last_inventory(gamedef->idef())
 {
 	updateName("<not set>");
 	inventory.clear();
@@ -53,6 +58,7 @@ Player::Player(IGameDef *gamedef):
 	craft->setWidth(3);
 	inventory.addList("craftpreview", 1);
 	inventory.addList("craftresult", 1);
+	m_last_inventory = inventory;
 
 	// Can be redefined via Lua
 	inventory_formspec = "size[8,7.5]"
@@ -224,6 +230,9 @@ void Player::deSerialize(std::istream &is, std::string playername)
 			inventory.getList("craftresult")->changeItem(0, ItemStack());
 		}
 	}
+
+	// Set m_last_*
+	checkModified();
 }
 
 /*
diff --git a/src/player.h b/src/player.h
index 89e4667c4..60645a60f 100644
--- a/src/player.h
+++ b/src/player.h
@@ -199,6 +199,23 @@ class Player
 	void serialize(std::ostream &os);
 	void deSerialize(std::istream &is, std::string playername);
 
+	bool checkModified()
+	{
+		if(m_last_hp != hp || m_last_pitch != m_pitch ||
+				m_last_pos != m_position || m_last_yaw != m_yaw ||
+				!(inventory == m_last_inventory))
+		{
+			m_last_hp = hp;
+			m_last_pitch = m_pitch;
+			m_last_pos = m_position;
+			m_last_yaw = m_yaw;
+			m_last_inventory = inventory;
+			return true;
+		} else {
+			return false;
+		}
+	}
+
 	bool touching_ground;
 	// This oscillates so that the player jumps a bit above the surface
 	bool in_liquid;
@@ -262,6 +279,12 @@ class Player
 	v3f m_speed;
 	v3f m_position;
 	core::aabbox3d<f32> m_collisionbox;
+
+	f32 m_last_pitch;
+	f32 m_last_yaw;
+	v3f m_last_pos;
+	u16 m_last_hp;
+	Inventory m_last_inventory;
 };
 
 
-- 
GitLab