added PlayerSAO and RemotePlayer, removed ServerRemotePlayer
authorKahrl <kahrl@gmx.net>
Mon, 19 Mar 2012 02:04:16 +0000 (03:04 +0100)
committerPerttu Ahola <celeron55@gmail.com>
Thu, 29 Mar 2012 11:05:45 +0000 (14:05 +0300)
20 files changed:
src/CMakeLists.txt
src/client.cpp
src/clientserver.h
src/constants.h
src/content_cao.cpp
src/content_sao.cpp
src/content_sao.h
src/environment.cpp
src/inventory.cpp
src/inventory.h
src/player.cpp
src/player.h
src/scriptapi.cpp
src/scriptapi.h
src/server.cpp
src/server.h
src/servercommand.cpp
src/serverobject.h
src/serverremoteplayer.cpp [deleted file]
src/serverremoteplayer.h [deleted file]

index 2f963e24d35fdbb191cb6fddc83d2e74d08c6c79..2558be9cb19254416c7c76ebe4741cae0129ab88 100644 (file)
@@ -159,7 +159,6 @@ set(common_SRCS
        subgame.cpp
        inventorymanager.cpp
        mods.cpp
-       serverremoteplayer.cpp
        content_abm.cpp
        craftdef.cpp
        nameidmapping.cpp
index 29872fb6ef08de374e93476399de17d1286952b2..7f1b39c33a2b3367206e7f815c07d50cdefb8c4c 100644 (file)
@@ -1397,45 +1397,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
        }
        else if(command == TOCLIENT_PLAYERITEM)
        {
-               std::string datastring((char*)&data[2], datasize-2);
-               std::istringstream is(datastring, std::ios_base::binary);
-
-               u16 count = readU16(is);
-
-               for (u16 i = 0; i < count; ++i) {
-                       u16 peer_id = readU16(is);
-                       Player *player = m_env.getPlayer(peer_id);
-
-                       if (player == NULL)
-                       {
-                               infostream<<"Client: ignoring player item "
-                                       << deSerializeString(is)
-                                       << " for non-existing peer id " << peer_id
-                                       << std::endl;
-                               continue;
-                       } else if (player->isLocal()) {
-                               infostream<<"Client: ignoring player item "
-                                       << deSerializeString(is)
-                                       << " for local player" << std::endl;
-                               continue;
-                       } else {
-                               InventoryList *inv = player->inventory.getList("main");
-                               std::string itemstring(deSerializeString(is));
-                               ItemStack item;
-                               item.deSerialize(itemstring, m_itemdef);
-                               inv->changeItem(0, item);
-                               if(itemstring.empty())
-                               {
-                                       infostream<<"Client: empty player item for peer "
-                                               <<peer_id<<std::endl;
-                               }
-                               else
-                               {
-                                       infostream<<"Client: player item for peer "
-                                               <<peer_id<<": "<<itemstring<<std::endl;
-                               }
-                       }
-               }
+               infostream<<"Client: WARNING: Ignoring TOCLIENT_PLAYERITEM"<<std::endl;
        }
        else if(command == TOCLIENT_DEATHSCREEN)
        {
index 203f8a7278045966cbf8717283f3283a5997ec6a..def4570e1ecf62e91e7684956f51034375364c5c 100644 (file)
@@ -200,7 +200,7 @@ enum ToClientCommand
                wstring reason
        */
 
-       TOCLIENT_PLAYERITEM = 0x36,
+       TOCLIENT_PLAYERITEM = 0x36, // Obsolete
        /*
                u16 command
                u16 count of player items
index a7cf1709b6ec036d864641616aecc02018f7b306..d4afc96d7fdce34a4ce3a5999be655b25ee7f8f3 100644 (file)
@@ -99,9 +99,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 // Length of cracking animation in count of images
 #define CRACK_ANIMATION_LENGTH 5
 
-// Some stuff needed by old code moved to here from heightmap.h
-#define GROUNDHEIGHT_NOTFOUND_SETVALUE (-10e6)
-#define GROUNDHEIGHT_VALID_MINVALUE    ( -9e6)
+// Maximum hit points of a player
+#define PLAYER_MAX_HP 20
 
 #endif
 
index fc1df377a7875624a56156ca2df98741f78b5f34..11c9ad9c6fd7ee676f31cc1f411cb035e27e3573 100644 (file)
@@ -1011,6 +1011,7 @@ private:
        float m_damage_visual_timer;
        bool m_dead;
        float m_step_distance_counter;
+       std::string m_wielded_item;
 
 public:
        PlayerCAO(IGameDef *gamedef, ClientEnvironment *env):
@@ -1024,7 +1025,8 @@ public:
                m_local_player(NULL),
                m_damage_visual_timer(0),
                m_dead(false),
-               m_step_distance_counter(0)
+               m_step_distance_counter(0),
+               m_wielded_item("")
        {
                if(gamedef == NULL)
                        ClientActiveObject::registerType(getType(), create);
@@ -1048,6 +1050,11 @@ public:
                m_yaw = readF1000(is);
                // dead
                m_dead = readU8(is);
+               // wielded item
+               try{
+                       m_wielded_item = deSerializeString(is);
+               }
+               catch(SerializationError &e){}
 
                pos_translator.init(m_position);
 
@@ -1263,6 +1270,11 @@ public:
                        m_dead = readU8(is);
                        updateVisibility();
                }
+               else if(cmd == 3) // wielded item
+               {
+                       m_wielded_item = deSerializeString(is);
+                       updateWieldedItem();
+               }
        }
 
        void updateTextures(const std::string &mod)
@@ -1288,6 +1300,50 @@ public:
                        }
                }
        }
+
+       void updateWieldedItem()
+       {
+               if(m_is_local_player)
+               {
+                       // ignoring player item for local player
+                       return;
+               }
+
+               ItemStack item;
+               try
+               {
+                       item.deSerialize(m_wielded_item, m_gamedef->idef());
+               }
+               catch(SerializationError &e)
+               {
+                       errorstream<<"PlayerCAO: SerializationError "
+                               "while reading wielded item: "
+                               <<m_wielded_item<<std::endl;
+                       return;
+               }
+
+               // do something with the item, for example:
+               Player *player = m_env->getPlayer(m_name.c_str());
+               if(player)
+               {
+                       InventoryList *inv = player->inventory.getList("main");
+                       assert(inv);
+                       inv->changeItem(0, item);
+               }
+
+               if(item.empty())
+               {
+                       infostream<<"PlayerCAO: empty player item for player "
+                                       <<m_name<<std::endl;
+               }
+               else
+               {
+                       infostream<<"PlayerCAO: player item for player "
+                                       <<m_name<<": "
+                                       <<item.getItemString()<<std::endl;
+               }
+       }
+
 };
 
 // Prototype
index 85340981db7c64be614e1cbfdbd709d118e857a5..d01b023de069fa3b5e38be7847e309ccc50bc7b6 100644 (file)
@@ -26,6 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "serialization.h" // For compressZlib
 #include "tool.h" // For ToolCapabilities
 #include "gamedef.h"
+#include "player.h"
+#include "scriptapi.h"
 
 core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
 
@@ -333,7 +335,6 @@ ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
        LuaEntitySAO
 */
 
-#include "scriptapi.h"
 #include "luaentity_common.h"
 
 // Prototype (registers item for deserialization)
@@ -610,7 +611,7 @@ void LuaEntitySAO::setHP(s16 hp)
        m_hp = hp;
 }
 
-s16 LuaEntitySAO::getHP()
+s16 LuaEntitySAO::getHP() const
 {
        return m_hp;
 }
@@ -749,3 +750,345 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
        m_messages_out.push_back(aom);
 }
 
+/*
+       PlayerSAO
+*/
+
+// No prototype, PlayerSAO does not need to be deserialized
+
+PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_):
+       ServerActiveObject(env_, v3f(0,0,0)),
+       m_player(player_),
+       m_peer_id(peer_id_),
+       m_inventory(NULL),
+       m_last_good_position(0,0,0),
+       m_last_good_position_age(0),
+       m_time_from_last_punch(0),
+       m_wield_index(0),
+       m_position_not_sent(false),
+       m_teleported(false),
+       m_inventory_not_sent(false),
+       m_hp_not_sent(false),
+       m_wielded_item_not_sent(false)
+{
+       assert(m_player);
+       assert(m_peer_id != 0);
+       setBasePosition(m_player->getPosition());
+       m_inventory = &m_player->inventory;
+}
+
+PlayerSAO::~PlayerSAO()
+{
+       if(m_inventory != &m_player->inventory)
+               delete m_inventory;
+
+}
+
+std::string PlayerSAO::getDescription()
+{
+       return std::string("player ") + m_player->getName();
+}
+
+// Called after id has been set and has been inserted in environment
+void PlayerSAO::addedToEnvironment()
+{
+       ServerActiveObject::addedToEnvironment();
+       ServerActiveObject::setBasePosition(m_player->getPosition());
+       m_player->setPlayerSAO(this);
+       m_player->peer_id = m_peer_id;
+       m_last_good_position = m_player->getPosition();
+       m_last_good_position_age = 0.0;
+}
+
+// Called before removing from environment
+void PlayerSAO::removingFromEnvironment()
+{
+       ServerActiveObject::removingFromEnvironment();
+       if(m_player->getPlayerSAO() == this)
+       {
+               m_player->setPlayerSAO(NULL);
+               m_player->peer_id = 0;
+       }
+}
+
+bool PlayerSAO::isStaticAllowed() const
+{
+       return false;
+}
+
+bool PlayerSAO::unlimitedTransferDistance() const
+{
+       return g_settings->getBool("unlimited_player_transfer_distance");
+}
+
+std::string PlayerSAO::getClientInitializationData()
+{
+       std::ostringstream os(std::ios::binary);
+       // version
+       writeU8(os, 0);
+       // name
+       os<<serializeString(m_player->getName());
+       // pos
+       writeV3F1000(os, m_player->getPosition());
+       // yaw
+       writeF1000(os, m_player->getYaw());
+       // dead
+       writeU8(os, getHP() == 0);
+       // wielded item
+       os<<serializeString(getWieldedItem().getItemString());
+       return os.str();
+}
+
+std::string PlayerSAO::getStaticData()
+{
+       assert(0);
+       return "";
+}
+
+void PlayerSAO::step(float dtime, bool send_recommended)
+{
+       m_time_from_last_punch += dtime;
+
+       /*
+               Check player movements
+
+               NOTE: Actually the server should handle player physics like the
+               client does and compare player's position to what is calculated
+               on our side. This is required when eg. players fly due to an
+               explosion.
+       */
+
+       //float player_max_speed = BS * 4.0; // Normal speed
+       float player_max_speed = BS * 20; // Fast speed
+       float player_max_speed_up = BS * 20;
+       player_max_speed *= 2.5; // Tolerance
+       player_max_speed_up *= 2.5;
+
+       m_last_good_position_age += dtime;
+       if(m_last_good_position_age >= 1.0){
+               float age = m_last_good_position_age;
+               v3f diff = (m_player->getPosition() - m_last_good_position);
+               float d_vert = diff.Y;
+               diff.Y = 0;
+               float d_horiz = diff.getLength();
+               /*infostream<<m_player->getName()<<"'s horizontal speed is "
+                               <<(d_horiz/age)<<std::endl;*/
+               if(d_horiz <= age * player_max_speed &&
+                               (d_vert < 0 || d_vert < age * player_max_speed_up)){
+                       m_last_good_position = m_player->getPosition();
+               } else {
+                       actionstream<<"Player "<<m_player->getName()
+                                       <<" moved too fast; resetting position"
+                                       <<std::endl;
+                       m_player->setPosition(m_last_good_position);
+                       m_teleported = true;
+               }
+               m_last_good_position_age = 0;
+       }
+
+       if(send_recommended == false)
+               return;
+
+       if(m_position_not_sent)
+       {
+               m_position_not_sent = false;
+
+               std::ostringstream os(std::ios::binary);
+               // command (0 = update position)
+               writeU8(os, 0);
+               // pos
+               writeV3F1000(os, m_player->getPosition());
+               // yaw
+               writeF1000(os, m_player->getYaw());
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), false, os.str());
+               m_messages_out.push_back(aom);
+       }
+
+       if(m_wielded_item_not_sent)
+       {
+               m_wielded_item_not_sent = false;
+
+               std::ostringstream os(std::ios::binary);
+               // command (3 = wielded item)
+               writeU8(os, 3);
+               // wielded item
+               os<<serializeString(getWieldedItem().getItemString());
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), false, os.str());
+               m_messages_out.push_back(aom);
+       }
+}
+
+void PlayerSAO::setBasePosition(const v3f &position)
+{
+       ServerActiveObject::setBasePosition(position);
+       m_position_not_sent = true;
+}
+
+void PlayerSAO::setPos(v3f pos)
+{
+       m_player->setPosition(pos);
+       // Movement caused by this command is always valid
+       m_last_good_position = pos;
+       m_last_good_position_age = 0;
+       // Force position change on client
+       m_teleported = true;
+}
+
+void PlayerSAO::moveTo(v3f pos, bool continuous)
+{
+       m_player->setPosition(pos);
+       // Movement caused by this command is always valid
+       m_last_good_position = pos;
+       m_last_good_position_age = 0;
+       // Force position change on client
+       m_teleported = true;
+}
+
+int PlayerSAO::punch(v3f dir,
+       const ToolCapabilities *toolcap,
+       ServerActiveObject *puncher,
+       float time_from_last_punch)
+{
+       if(!toolcap)
+               return 0;
+
+       // No effect if PvP disabled
+       if(g_settings->getBool("enable_pvp") == false){
+               if(puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER)
+                       return 0;
+       }
+
+       // "Material" groups of the player
+       ItemGroupList groups;
+       groups["choppy"] = 2;
+       groups["fleshy"] = 3;
+
+       HitParams hitparams = getHitParams(groups, toolcap, time_from_last_punch);
+
+       actionstream<<"Player "<<m_player->getName()<<" punched by "
+                       <<puncher->getDescription()<<", damage "<<hitparams.hp
+                       <<" HP"<<std::endl;
+
+       setHP(getHP() - hitparams.hp);
+
+       if(hitparams.hp != 0)
+       {
+               std::ostringstream os(std::ios::binary);
+               // command (1 = punched)
+               writeU8(os, 1);
+               // damage
+               writeS16(os, hitparams.hp);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), false, os.str());
+               m_messages_out.push_back(aom);
+       }
+
+       return hitparams.wear;
+}
+
+void PlayerSAO::rightClick(ServerActiveObject *clicker)
+{
+}
+
+s16 PlayerSAO::getHP() const
+{
+       return m_player->hp;
+}
+
+void PlayerSAO::setHP(s16 hp)
+{
+       s16 oldhp = m_player->hp;
+
+       if(hp < 0)
+               hp = 0;
+       else if(hp > PLAYER_MAX_HP)
+               hp = PLAYER_MAX_HP;
+
+       if(hp < oldhp && g_settings->getBool("enable_damage") == false)
+       {
+               m_hp_not_sent = true; // fix wrong prediction on client
+               return;
+       }
+
+       m_player->hp = hp;
+
+       if(hp != oldhp)
+               m_hp_not_sent = true;
+
+       // On death or reincarnation send an active object message
+       if((hp == 0) != (oldhp == 0))
+       {
+               std::ostringstream os(std::ios::binary);
+               // command (2 = update death state)
+               writeU8(os, 2);
+               // dead?
+               writeU8(os, hp == 0);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), false, os.str());
+               m_messages_out.push_back(aom);
+       }
+}
+
+Inventory* PlayerSAO::getInventory()
+{
+       return m_inventory;
+}
+const Inventory* PlayerSAO::getInventory() const
+{
+       return m_inventory;
+}
+
+InventoryLocation PlayerSAO::getInventoryLocation() const
+{
+       InventoryLocation loc;
+       loc.setPlayer(m_player->getName());
+       return loc;
+}
+
+void PlayerSAO::setInventoryModified()
+{
+       m_inventory_not_sent = true;
+}
+
+std::string PlayerSAO::getWieldList() const
+{
+       return "main";
+}
+
+int PlayerSAO::getWieldIndex() const
+{
+       return m_wield_index;
+}
+
+void PlayerSAO::setWieldIndex(int i)
+{
+       if(i != m_wield_index)
+       {
+               m_wield_index = i;
+               m_wielded_item_not_sent = true;
+       }
+}
+
+void PlayerSAO::disconnected()
+{
+       m_peer_id = 0;
+       m_removed = true;
+       if(m_player->getPlayerSAO() == this)
+       {
+               m_player->setPlayerSAO(NULL);
+               m_player->peer_id = 0;
+       }
+}
+
+void PlayerSAO::createCreativeInventory()
+{
+       if(m_inventory != &m_player->inventory)
+               delete m_inventory;
+
+       m_inventory = new Inventory(m_player->inventory);
+       m_inventory->clearContents();
+       scriptapi_get_creative_inventory(m_env->getLua(), this);
+}
+
index 53e701d8c3313c22d095fced8dc5217ee30fd5cc..9ceb6ed6ae65879f523f4340ec07e677d7e3d2fe 100644 (file)
@@ -23,14 +23,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "serverobject.h"
 #include "content_object.h"
 #include "itemgroup.h"
+#include "player.h"
 
 ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
                const std::string itemstring);
 
 /*
-       LuaEntitySAO
-       
-       This is the only SAO that needs to have a bunch of it's internals exposed.
+       LuaEntitySAO needs some internals exposed.
 */
 
 struct LuaEntityProperties;
@@ -59,7 +58,7 @@ public:
        float getMinimumSavedMovement();
        std::string getDescription();
        void setHP(s16 hp);
-       s16 getHP();
+       s16 getHP() const;
        /* LuaEntitySAO-specific */
        void setVelocity(v3f velocity);
        v3f getVelocity();
@@ -94,5 +93,102 @@ private:
        bool m_armor_groups_sent;
 };
 
+/*
+       PlayerSAO needs some internals exposed.
+*/
+
+class PlayerSAO : public ServerActiveObject
+{
+public:
+       PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_);
+       ~PlayerSAO();
+       u8 getType() const
+               {return ACTIVEOBJECT_TYPE_PLAYER;}
+       std::string getDescription();
+
+       /*
+               Active object <-> environment interface
+       */
+
+       void addedToEnvironment();
+       void removingFromEnvironment();
+       bool isStaticAllowed() const;
+       bool unlimitedTransferDistance() const;
+       std::string getClientInitializationData();
+       std::string getStaticData();
+       void step(float dtime, bool send_recommended);
+       void setBasePosition(const v3f &position);
+       void setPos(v3f pos);
+       void moveTo(v3f pos, bool continuous);
+
+       /*
+               Interaction interface
+       */
+
+       int punch(v3f dir,
+               const ToolCapabilities *toolcap,
+               ServerActiveObject *puncher,
+               float time_from_last_punch);
+       void rightClick(ServerActiveObject *clicker);
+       s16 getHP() const;
+       void setHP(s16 hp);
+
+       /*
+               Inventory interface
+       */
+
+       Inventory* getInventory();
+       const Inventory* getInventory() const;
+       InventoryLocation getInventoryLocation() const;
+       void setInventoryModified();
+       std::string getWieldList() const;
+       int getWieldIndex() const;
+       void setWieldIndex(int i);
+
+       /*
+               PlayerSAO-specific
+       */
+
+       void disconnected();
+
+       void createCreativeInventory();
+
+       Player* getPlayer()
+       {
+               return m_player;
+       }
+       u16 getPeerID() const
+       {
+               return m_peer_id;
+       }
+       v3f getLastGoodPosition() const
+       {
+               return m_last_good_position;
+       }
+       float resetTimeFromLastPunch()
+       {
+               float r = m_time_from_last_punch;
+               m_time_from_last_punch = 0.0;
+               return r;
+       }
+
+private:
+       Player *m_player;
+       u16 m_peer_id;
+       Inventory *m_inventory;
+       v3f m_last_good_position;
+       float m_last_good_position_age;
+       float m_time_from_last_punch;
+       int m_wield_index;
+       bool m_position_not_sent;
+
+public:
+       // Some flags used by Server
+       bool m_teleported;
+       bool m_inventory_not_sent;
+       bool m_hp_not_sent;
+       bool m_wielded_item_not_sent;
+};
+
 #endif
 
index e713ab610cbebe5dc72b578c1a6a0296c7df2f93..5e8f5edbaa81691fb89ce5b6cc1ecb7efb4765dd 100644 (file)
@@ -37,7 +37,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nodemetadata.h"
 #include "main.h" // For g_settings, g_profiler
 #include "gamedef.h"
-#include "serverremoteplayer.h"
 #ifndef SERVER
 #include "clientmap.h"
 #endif
@@ -368,7 +367,7 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
                //infostream<<"Checking player file "<<path<<std::endl;
 
                // Load player to see what is its name
-               ServerRemotePlayer testplayer(this);
+               RemotePlayer testplayer(m_gamedef);
                {
                        // Open file and deserialize
                        std::ifstream is(path.c_str(), std::ios_base::binary);
@@ -482,7 +481,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
                //infostream<<"Checking player file "<<path<<std::endl;
 
                // Load player to see what is its name
-               ServerRemotePlayer testplayer(this);
+               RemotePlayer testplayer(m_gamedef);
                {
                        // Open file and deserialize
                        std::ifstream is(path.c_str(), std::ios_base::binary);
@@ -510,12 +509,10 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
                if(player == NULL)
                {
                        //infostream<<"Is a new player"<<std::endl;
-                       player = new ServerRemotePlayer(this);
+                       player = new RemotePlayer(m_gamedef);
                        newplayer = true;
                }
 
-               ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
-
                // Load player
                {
                        verbosestream<<"Reading player "<<testplayer.getName()<<" from "
@@ -527,9 +524,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
                                infostream<<"Failed to read "<<path<<std::endl;
                                continue;
                        }
-                       srp->deSerialize(is);
-                       srp->m_last_good_position = srp->getBasePosition();
-                       srp->m_last_good_position_age = 0;
+                       player->deSerialize(is);
                }
 
                if(newplayer)
@@ -2074,7 +2069,7 @@ void ClientEnvironment::step(float dtime)
                catch(InvalidPositionException &e){
                        light = blend_light(getDayNightRatio(), LIGHT_SUN, 0);
                }
-               player->updateLight(light);
+               player->light = light;
        }
        
        /*
@@ -2226,8 +2221,19 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
        
        obj->setId(id);
 
-       obj->initialize(init_data);
-       
+       try
+       {
+               obj->initialize(init_data);
+       }
+       catch(SerializationError &e)
+       {
+               errorstream<<"ClientEnvironment::addActiveObject():"
+                               <<" id="<<id<<" type="<<type
+                               <<": SerializationError in initialize(),"
+                               <<" init_data="<<serializeJsonString(init_data)
+                               <<std::endl;
+       }
+
        addActiveObject(obj);
 }
 
@@ -2258,7 +2264,18 @@ void ClientEnvironment::processActiveObjectMessage(u16 id,
                                <<std::endl;
                return;
        }
-       obj->processMessage(data);
+       try
+       {
+               obj->processMessage(data);
+       }
+       catch(SerializationError &e)
+       {
+               errorstream<<"ClientEnvironment::processActiveObjectMessage():"
+                               <<" id="<<id<<" type="<<obj->getType()
+                               <<" SerializationError in processMessage(),"
+                               <<" message="<<serializeJsonString(data)
+                               <<std::endl;
+       }
 }
 
 /*
index 056cf552d681da8c0059e9fc83024943a43049d4..3d6707f60684b22a7209bc56456fc7bb00f7571b 100644 (file)
@@ -795,6 +795,18 @@ void Inventory::clear()
        m_lists.clear();
 }
 
+void Inventory::clearContents()
+{
+       for(u32 i=0; i<m_lists.size(); i++)
+       {
+               InventoryList *list = m_lists[i];
+               for(u32 j=0; j<list->getSize(); j++)
+               {
+                       list->deleteItem(j);
+               }
+       }
+}
+
 Inventory::Inventory(IItemDefManager *itemdef)
 {
        m_itemdef = itemdef;
index e27da15d53b467236802e10a8f4410185c96a094..0f620e83c0b724cd059c7c3686ca072474a8b8ee 100644 (file)
@@ -250,6 +250,7 @@ public:
        ~Inventory();
 
        void clear();
+       void clearContents();
 
        Inventory(IItemDefManager *itemdef);
        Inventory(const Inventory &other);
index 0d4a1cb695c05553fb9c21c7b8ac2273f7122475..ff272322f9a2d9349218304b8bbc04443ec597c7 100644 (file)
@@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "environment.h"
 #include "gamedef.h"
 #include "event.h"
+#include "content_sao.h"
 
 Player::Player(IGameDef *gamedef):
        touching_ground(false),
@@ -40,8 +41,7 @@ Player::Player(IGameDef *gamedef):
        is_climbing(false),
        swimming_up(false),
        inventory(gamedef->idef()),
-       inventory_backup(NULL),
-       hp(20),
+       hp(PLAYER_MAX_HP),
        peer_id(PEER_ID_INEXISTENT),
 // protected
        m_gamedef(gamedef),
@@ -51,16 +51,6 @@ Player::Player(IGameDef *gamedef):
        m_position(0,0,0)
 {
        updateName("<not set>");
-       resetInventory();
-}
-
-Player::~Player()
-{
-       delete inventory_backup;
-}
-
-void Player::resetInventory()
-{
        inventory.clear();
        inventory.addList("main", PLAYER_INVENTORY_SIZE);
        inventory.addList("craft", 9);
@@ -68,6 +58,10 @@ void Player::resetInventory()
        inventory.addList("craftresult", 1);
 }
 
+Player::~Player()
+{
+}
+
 // Y direction is ignored
 void Player::accelerate(v3f target_speed, f32 max_increase)
 {
@@ -126,12 +120,7 @@ void Player::serialize(std::ostream &os)
 
        os<<"PlayerArgsEnd\n";
        
-       // If actual inventory is backed up due to creative mode, save it
-       // instead of the dummy creative mode inventory
-       if(inventory_backup)
-               inventory_backup->serialize(os);
-       else
-               inventory.serialize(os);
+       inventory.serialize(os);
 }
 
 void Player::deSerialize(std::istream &is)
@@ -779,3 +768,13 @@ v3s16 LocalPlayer::getStandingNodePos()
 
 #endif
 
+/*
+       RemotePlayer
+*/
+
+void RemotePlayer::setPosition(const v3f &position)
+{
+       Player::setPosition(position);
+       if(m_sao)
+               m_sao->setBasePosition(position);
+}
index d0e1ac79923b7d521fe362e4d65513dc75e97d49..b6856b1d0015963175083a59c14806ad542f5026 100644 (file)
@@ -31,18 +31,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 class Map;
 class IGameDef;
 struct CollisionInfo;
+class PlayerSAO;
 
 class Player
 {
 public:
 
        Player(IGameDef *gamedef);
-       virtual ~Player();
+       virtual ~Player() = 0;
 
-       void resetInventory();
-
-       //void move(f32 dtime, Map &map);
-       virtual void move(f32 dtime, Map &map, f32 pos_max_d) = 0;
+       virtual void move(f32 dtime, Map &map, f32 pos_max_d)
+       {}
 
        v3f getSpeed()
        {
@@ -112,7 +111,7 @@ public:
                return (m_yaw + 90.) * core::DEGTORAD;
        }
 
-       virtual void updateName(const char *name)
+       void updateName(const char *name)
        {
                snprintf(m_name, PLAYERNAME_SIZE, "%s", name);
        }
@@ -122,17 +121,13 @@ public:
                return m_name;
        }
 
-       virtual bool isLocal() const = 0;
+       virtual bool isLocal() const
+       { return false; }
+       virtual PlayerSAO *getPlayerSAO()
+       { return NULL; }
+       virtual void setPlayerSAO(PlayerSAO *sao)
+       { assert(0); }
 
-       virtual void updateLight(u8 light_at_pos)
-       {
-               light = light_at_pos;
-       }
-       
-       // NOTE: Use peer_id == 0 for disconnected
-       /*virtual bool isClientConnected() { return false; }
-       virtual void setClientConnected(bool) {}*/
-       
        /*
                serialize() writes a bunch of text that can contain
                any characters except a '\0', and such an ending that
@@ -151,9 +146,8 @@ public:
        
        u8 light;
 
+       // In creative mode, this is the invisible backup inventory
        Inventory inventory;
-       // Actual inventory is backed up here when creative mode is used
-       Inventory *inventory_backup;
 
        u16 hp;
 
@@ -167,9 +161,6 @@ protected:
        f32 m_yaw;
        v3f m_speed;
        v3f m_position;
-
-public:
-
 };
 
 #ifndef SERVER
@@ -249,5 +240,24 @@ private:
 };
 #endif // !SERVER
 
+/*
+       Player on the server
+*/
+class RemotePlayer : public Player
+{
+public:
+       RemotePlayer(IGameDef *gamedef): Player(gamedef), m_sao(0) {}
+       virtual ~RemotePlayer() {}
+
+       PlayerSAO *getPlayerSAO()
+       { return m_sao; }
+       void setPlayerSAO(PlayerSAO *sao)
+       { m_sao = sao; }
+       void setPosition(const v3f &position);
+
+private:
+       PlayerSAO *m_sao;
+};
+
 #endif
 
index 863e2ba288af2d1ced20f600f61cc657303dc0bf..f8e4c471c6a64366b95c6e8b5bc4f497077ca29e 100644 (file)
@@ -35,7 +35,7 @@ extern "C" {
 #include "script.h"
 //#include "luna.h"
 #include "luaentity_common.h"
-#include "content_sao.h" // For LuaEntitySAO
+#include "content_sao.h" // For LuaEntitySAO and PlayerSAO
 #include "itemdef.h"
 #include "nodedef.h"
 #include "craftdef.h"
@@ -1095,7 +1095,6 @@ static ItemStack read_item(lua_State *L, int index);
 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
                lua_State *L, int tableindex, int forcesize=-1)
 {
-       dstream<<"inventory_set_list_from_lua\n";
        if(tableindex < 0)
                tableindex = lua_gettop(L) + 1 + tableindex;
        // If nil, delete list
@@ -1127,7 +1126,6 @@ static void inventory_set_list_from_lua(Inventory *inv, const char *name,
                invlist->deleteItem(index);
                index++;
        }
-       dstream<<"inventory_set_list_from_lua done\n";
 }
 
 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
@@ -2259,14 +2257,22 @@ private:
                return (LuaEntitySAO*)obj;
        }
        
-       static ServerRemotePlayer* getplayer(ObjectRef *ref)
+       static PlayerSAO* getplayersao(ObjectRef *ref)
        {
                ServerActiveObject *obj = getobject(ref);
                if(obj == NULL)
                        return NULL;
                if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
                        return NULL;
-               return static_cast<ServerRemotePlayer*>(obj);
+               return (PlayerSAO*)obj;
+       }
+       
+       static Player* getplayer(ObjectRef *ref)
+       {
+               PlayerSAO *playersao = getplayersao(ref);
+               if(playersao == NULL)
+                       return NULL;
+               return playersao->getPlayer();
        }
        
        // Exported functions
@@ -2319,10 +2325,6 @@ private:
                v3f pos = checkFloatPos(L, 2);
                // Do it
                co->setPos(pos);
-               // Move player if applicable
-               ServerRemotePlayer *player = getplayer(ref);
-               if(player != NULL)
-                       get_server(L)->SendMovePlayer(player);
                return 0;
        }
        
@@ -2626,7 +2628,7 @@ private:
        static int l_get_player_name(lua_State *L)
        {
                ObjectRef *ref = checkobject(L, 1);
-               ServerRemotePlayer *player = getplayer(ref);
+               Player *player = getplayer(ref);
                if(player == NULL){
                        lua_pushnil(L);
                        return 1;
@@ -2640,7 +2642,7 @@ private:
        static int l_get_look_dir(lua_State *L)
        {
                ObjectRef *ref = checkobject(L, 1);
-               ServerRemotePlayer *player = getplayer(ref);
+               Player *player = getplayer(ref);
                if(player == NULL) return 0;
                // Do it
                float pitch = player->getRadPitch();
@@ -2654,7 +2656,7 @@ private:
        static int l_get_look_pitch(lua_State *L)
        {
                ObjectRef *ref = checkobject(L, 1);
-               ServerRemotePlayer *player = getplayer(ref);
+               Player *player = getplayer(ref);
                if(player == NULL) return 0;
                // Do it
                lua_pushnumber(L, player->getRadPitch());
@@ -2665,7 +2667,7 @@ private:
        static int l_get_look_yaw(lua_State *L)
        {
                ObjectRef *ref = checkobject(L, 1);
-               ServerRemotePlayer *player = getplayer(ref);
+               Player *player = getplayer(ref);
                if(player == NULL) return 0;
                // Do it
                lua_pushnumber(L, player->getRadYaw());
@@ -2996,14 +2998,18 @@ private:
                if(env == NULL) return 0;
                // Do it
                const char *name = luaL_checkstring(L, 2);
-               ServerRemotePlayer *player =
-                               static_cast<ServerRemotePlayer*>(env->getPlayer(name));
+               Player *player = env->getPlayer(name);
                if(player == NULL){
                        lua_pushnil(L);
                        return 1;
                }
+               PlayerSAO *sao = player->getPlayerSAO();
+               if(sao == NULL){
+                       lua_pushnil(L);
+                       return 1;
+               }
                // Put player on stack
-               objectref_get_or_create(L, player);
+               objectref_get_or_create(L, sao);
                return 1;
        }
 
@@ -4211,8 +4217,6 @@ bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
        assert(lua_checkstack(L, 20));
        StackUnroller stack_unroller(L);
 
-       dstream<<"player: "<<player<<"   id: "<<player->getId()<<std::endl;
-
        bool positioning_handled_by_some = false;
 
        // Get minetest.registered_on_respawnplayers
@@ -4238,13 +4242,15 @@ bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
        return positioning_handled_by_some;
 }
 
-void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
+void scriptapi_get_creative_inventory(lua_State *L, ServerActiveObject *player)
 {
+       Inventory *inv = player->getInventory();
+       assert(inv);
+
        lua_getglobal(L, "minetest");
        lua_getfield(L, -1, "creative_inventory");
        luaL_checktype(L, -1, LUA_TTABLE);
-       inventory_set_list_from_lua(&player->inventory, "main", L, -1,
-                       PLAYER_INVENTORY_SIZE);
+       inventory_set_list_from_lua(inv, "main", L, -1, PLAYER_INVENTORY_SIZE);
 }
 
 /*
index 373262888cf2a1ee8a8f8156a58e826d2f00b245..c2c099a6da0dfaf73d89b602792fff985e3d44cd 100644 (file)
@@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 class Server;
 class ServerEnvironment;
 class ServerActiveObject;
-class ServerRemotePlayer;
 typedef struct lua_State lua_State;
 struct LuaEntityProperties;
 struct ItemStack;
@@ -58,7 +57,7 @@ void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp,
 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player);
 void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player);
 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player);
-void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player);
+void scriptapi_get_creative_inventory(lua_State *L, ServerActiveObject *player);
 
 /* item callbacks */
 bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
index c83fce3b044e624ef795d2145cc757bb149258ce..1635282351a254628d8b8dfb276e90178f69a86b 100644 (file)
@@ -30,8 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "config.h"
 #include "servercommand.h"
 #include "filesys.h"
-#include "content_mapnode.h"
-#include "content_nodemeta.h"
 #include "mapblock.h"
 #include "serverobject.h"
 #include "settings.h"
@@ -43,7 +41,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "itemdef.h"
 #include "craftdef.h"
 #include "mapgen.h"
+#include "content_mapnode.h"
+#include "content_nodemeta.h"
 #include "content_abm.h"
+#include "content_sao.h"
 #include "mods.h"
 #include "sha1.h"
 #include "base64.h"
@@ -379,6 +380,27 @@ void * EmergeThread::Thread()
        return NULL;
 }
 
+v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const
+{
+       if(pos_exists) *pos_exists = false;
+       switch(type){
+       case SSP_LOCAL:
+               return v3f(0,0,0);
+       case SSP_POSITIONAL:
+               if(pos_exists) *pos_exists = true;
+               return pos;
+       case SSP_OBJECT: {
+               if(object == 0)
+                       return v3f(0,0,0);
+               ServerActiveObject *sao = env->getActiveObject(object);
+               if(!sao)
+                       return v3f(0,0,0);
+               if(pos_exists) *pos_exists = true;
+               return sao->getBasePosition(); }
+       }
+       return v3f(0,0,0);
+}
+
 void RemoteClient::GetNextBlocks(Server *server, float dtime,
                core::array<PrioritySortedBlockTransfer> &dest)
 {
@@ -1250,8 +1272,6 @@ void Server::AsyncRunStep()
                                i.atEnd() == false; i++)
                        {
                                RemoteClient *client = i.getNode()->getValue();
-                               //Player *player = m_env->getPlayer(client->peer_id);
-                               
                                SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
                                                m_env->getTimeOfDay(), g_settings->getFloat("time_speed"));
                                // Send as reliable
@@ -1291,78 +1311,36 @@ void Server::AsyncRunStep()
 
                ScopeProfiler sp(g_profiler, "Server: handle players");
 
-               //float player_max_speed = BS * 4.0; // Normal speed
-               float player_max_speed = BS * 20; // Fast speed
-               float player_max_speed_up = BS * 20;
-               
-               player_max_speed *= 2.5; // Tolerance
-               player_max_speed_up *= 2.5;
-
                for(core::map<u16, RemoteClient*>::Iterator
                        i = m_clients.getIterator();
                        i.atEnd() == false; i++)
                {
                        RemoteClient *client = i.getNode()->getValue();
-                       ServerRemotePlayer *player =
-                                       static_cast<ServerRemotePlayer*>
-                                       (m_env->getPlayer(client->peer_id));
-                       if(player==NULL)
+                       PlayerSAO *playersao = getPlayerSAO(client->peer_id);
+                       if(playersao == NULL){
+                               errorstream<<"Handling client without PlayerSAO, peer_id="<<client->peer_id<<std::endl;
                                continue;
-                       
-                       /*
-                               Check player movements
-
-                               NOTE: Actually the server should handle player physics like the
-                               client does and compare player's position to what is calculated
-                               on our side. This is required when eg. players fly due to an
-                               explosion.
-                       */
-                       player->m_last_good_position_age += dtime;
-                       if(player->m_last_good_position_age >= 1.0){
-                               float age = player->m_last_good_position_age;
-                               v3f diff = (player->getPosition() - player->m_last_good_position);
-                               float d_vert = diff.Y;
-                               diff.Y = 0;
-                               float d_horiz = diff.getLength();
-                               /*infostream<<player->getName()<<"'s horizontal speed is "
-                                               <<(d_horiz/age)<<std::endl;*/
-                               if(d_horiz <= age * player_max_speed &&
-                                               (d_vert < 0 || d_vert < age * player_max_speed_up)){
-                                       player->m_last_good_position = player->getPosition();
-                               } else {
-                                       actionstream<<"Player "<<player->getName()
-                                                       <<" moved too fast; resetting position"
-                                                       <<std::endl;
-                                       player->setPosition(player->m_last_good_position);
-                                       SendMovePlayer(player);
-                               }
-                               player->m_last_good_position_age = 0;
                        }
 
                        /*
                                Handle player HPs (die if hp=0)
                        */
-                       if(player->hp == 0 && player->m_hp_not_sent)
-                               DiePlayer(player);
+                       if(playersao->getHP() == 0 && playersao->m_hp_not_sent)
+                               DiePlayer(client->peer_id);
 
                        /*
                                Send player inventories and HPs if necessary
                        */
-                       if(player->m_inventory_not_sent){
-                               UpdateCrafting(player->peer_id);
-                               SendInventory(player->peer_id);
+                       if(playersao->m_teleported){
+                               SendMovePlayer(client->peer_id);
+                               playersao->m_teleported = false;
                        }
-                       if(player->m_hp_not_sent){
-                               SendPlayerHP(player);
+                       if(playersao->m_inventory_not_sent){
+                               UpdateCrafting(client->peer_id);
+                               SendInventory(client->peer_id);
                        }
-
-                       /*
-                               Add to environment
-                       */
-                       if(!player->m_is_in_environment){
-                               player->m_removed = false;
-                               player->setId(0);
-                               m_env->addActiveObject(player);
+                       if(playersao->m_hp_not_sent){
+                               SendPlayerHP(client->peer_id);
                        }
                }
        }
@@ -2167,10 +2145,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                }
 
                // Get player
-               ServerRemotePlayer *player = emergePlayer(playername, peer_id);
+               PlayerSAO *playersao = emergePlayer(playername, peer_id);
 
                // If failed, cancel
-               if(player == NULL)
+               if(playersao == NULL)
                {
                        errorstream<<"Server: peer_id="<<peer_id
                                        <<": failed to emerge player"<<std::endl;
@@ -2184,7 +2162,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        SharedBuffer<u8> reply(2+1+6+8);
                        writeU16(&reply[0], TOCLIENT_INIT);
                        writeU8(&reply[2], deployed);
-                       writeV3S16(&reply[2+1], floatToInt(player->getPosition()+v3f(0,BS/2,0), BS));
+                       writeV3S16(&reply[2+1], floatToInt(playersao->getPlayer()->getPosition()+v3f(0,BS/2,0), BS));
                        writeU64(&reply[2+1+6], m_env->getServerMap().getSeed());
                        
                        // Send as reliable
@@ -2194,7 +2172,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                /*
                        Send complete position information
                */
-               SendMovePlayer(player);
+               SendMovePlayer(peer_id);
 
                return;
        }
@@ -2231,17 +2209,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                UpdateCrafting(peer_id);
                SendInventory(peer_id);
                
-               // Send player items to all players
-               SendPlayerItems();
-
                Player *player = m_env->getPlayer(peer_id);
 
                // Send HP
-               SendPlayerHP(player);
+               SendPlayerHP(peer_id);
                
                // Show death screen if necessary
                if(player->hp == 0)
-                       SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
+                       SendDeathscreen(m_con, peer_id, false, v3f(0,0,0));
 
                // Send time of day
                {
@@ -2314,14 +2289,21 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
        }
        
        Player *player = m_env->getPlayer(peer_id);
-       ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
-
        if(player == NULL){
                infostream<<"Server::ProcessData(): Cancelling: "
                                "No player for peer_id="<<peer_id
                                <<std::endl;
                return;
        }
+
+       PlayerSAO *playersao = player->getPlayerSAO();
+       if(playersao == NULL){
+               infostream<<"Server::ProcessData(): Cancelling: "
+                               "No player object for peer_id="<<peer_id
+                               <<std::endl;
+               return;
+       }
+
        if(command == TOSERVER_PLAYERPOS)
        {
                if(datasize < 2+12+12+4+4)
@@ -2644,7 +2626,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                }
                
                // Do the action
-               a->apply(this, srp, this);
+               a->apply(this, playersao, this);
                // Eat the action
                delete a;
        }
@@ -2775,27 +2757,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                std::istringstream is(datastring, std::ios_base::binary);
                u8 damage = readU8(is);
 
-               ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
-
-               if(g_settings->getBool("enable_damage"))
-               {
-                       actionstream<<player->getName()<<" damaged by "
-                                       <<(int)damage<<" hp at "<<PP(player->getPosition()/BS)
-                                       <<std::endl;
+               actionstream<<player->getName()<<" damaged by "
+                               <<(int)damage<<" hp at "<<PP(player->getPosition()/BS)
+                               <<std::endl;
 
-                       srp->setHP(srp->getHP() - damage);
+               playersao->setHP(playersao->getHP() - damage);
 
-                       if(srp->getHP() == 0 && srp->m_hp_not_sent)
-                               DiePlayer(srp);
+               if(playersao->getHP() == 0 && playersao->m_hp_not_sent)
+                       DiePlayer(peer_id);
 
-                       if(srp->m_hp_not_sent)
-                               SendPlayerHP(player);
-               }
-               else
-               {
-                       // Force send (to correct the client's predicted HP)
-                       SendPlayerHP(player);
-               }
+               if(playersao->m_hp_not_sent)
+                       SendPlayerHP(peer_id);
        }
        else if(command == TOSERVER_PASSWORD)
        {
@@ -2865,15 +2837,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        return;
 
                u16 item = readU16(&data[2]);
-               srp->setWieldIndex(item);
-               SendWieldedItem(srp);
+               playersao->setWieldIndex(item);
        }
        else if(command == TOSERVER_RESPAWN)
        {
                if(player->hp != 0)
                        return;
                
-               RespawnPlayer(player);
+               RespawnPlayer(peer_id);
                
                actionstream<<player->getName()<<" respawns at "
                                <<PP(player->getPosition()/BS)<<std::endl;
@@ -2934,19 +2905,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                if(player->hp == 0)
                {
-                       verbosestream<<"TOSERVER_INTERACT: "<<srp->getName()
+                       verbosestream<<"TOSERVER_INTERACT: "<<player->getName()
                                <<" tried to interact, but is dead!"<<std::endl;
                        return;
                }
 
-               v3f player_pos = srp->m_last_good_position;
+               v3f player_pos = playersao->getLastGoodPosition();
 
                // Update wielded item
-               if(srp->getWieldIndex() != item_i)
-               {
-                       srp->setWieldIndex(item_i);
-                       SendWieldedItem(srp);
-               }
+               playersao->setWieldIndex(item_i);
 
                // Get pointed to node (undefined if not POINTEDTYPE_NODE)
                v3s16 p_under = pointed.node_undersurface;
@@ -3038,7 +3005,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                        getNodeBlockPos(p_above), BLOCK_EMERGE_FLAG_FROMDISK);
                                }
                                if(n.getContent() != CONTENT_IGNORE)
-                                       scriptapi_node_on_punch(m_lua, p_under, n, srp);
+                                       scriptapi_node_on_punch(m_lua, p_under, n, playersao);
                        }
                        else if(pointed.type == POINTEDTHING_OBJECT)
                        {
@@ -3050,15 +3017,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                <<pointed.object_id<<": "
                                                <<pointed_object->getDescription()<<std::endl;
 
-                               ItemStack punchitem = srp->getWieldedItem();
+                               ItemStack punchitem = playersao->getWieldedItem();
                                ToolCapabilities toolcap =
                                                punchitem.getToolCapabilities(m_itemdef);
                                v3f dir = (pointed_object->getBasePosition() -
-                                               (srp->getPosition() + srp->getEyeOffset())
+                                               (player->getPosition() + player->getEyeOffset())
                                                        ).normalize();
-                               pointed_object->punch(dir, &toolcap, srp,
-                                               srp->m_time_from_last_punch);
-                               srp->m_time_from_last_punch = 0;
+                               float time_from_last_punch =
+                                       playersao->resetTimeFromLastPunch();
+                               pointed_object->punch(dir, &toolcap, playersao,
+                                               time_from_last_punch);
                        }
 
                } // action == 0
@@ -3092,7 +3060,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                        getNodeBlockPos(p_above), BLOCK_EMERGE_FLAG_FROMDISK);
                                }
                                if(n.getContent() != CONTENT_IGNORE)
-                                       scriptapi_node_on_dig(m_lua, p_under, n, srp);
+                                       scriptapi_node_on_dig(m_lua, p_under, n, playersao);
                        }
                } // action == 2
                
@@ -3101,7 +3069,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                */
                else if(action == 3)
                {
-                       ItemStack item = srp->getWieldedItem();
+                       ItemStack item = playersao->getWieldedItem();
 
                        // Reset build time counter
                        if(pointed.type == POINTEDTHING_NODE &&
@@ -3121,16 +3089,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                <<pointed_object->getDescription()<<std::endl;
 
                                // Do stuff
-                               pointed_object->rightClick(srp);
+                               pointed_object->rightClick(playersao);
                        }
                        else if(scriptapi_item_on_place(m_lua,
-                                       item, srp, pointed))
+                                       item, playersao, pointed))
                        {
                                // Placement was handled in lua
 
                                // Apply returned ItemStack
                                if(g_settings->getBool("creative_mode") == false)
-                                       srp->setWieldedItem(item);
+                                       playersao->setWieldedItem(item);
                        }
 
                } // action == 3
@@ -3140,17 +3108,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                */
                else if(action == 4)
                {
-                       ItemStack item = srp->getWieldedItem();
+                       ItemStack item = playersao->getWieldedItem();
 
                        actionstream<<player->getName()<<" uses "<<item.name
                                        <<", pointing at "<<pointed.dump()<<std::endl;
 
                        if(scriptapi_item_on_use(m_lua,
-                                       item, srp, pointed))
+                                       item, playersao, pointed))
                        {
                                // Apply returned ItemStack
                                if(g_settings->getBool("creative_mode") == false)
-                                       srp->setWieldedItem(item);
+                                       playersao->setWieldedItem(item);
                        }
 
                } // action == 4
@@ -3222,7 +3190,10 @@ Inventory* Server::getInventory(const InventoryLocation &loc)
                Player *player = m_env->getPlayer(loc.name.c_str());
                if(!player)
                        return NULL;
-               return &player->inventory;
+               PlayerSAO *playersao = player->getPlayerSAO();
+               if(!playersao)
+                       return NULL;
+               return playersao->getInventory();
        }
        break;
        case InventoryLocation::NODEMETA:
@@ -3273,11 +3244,14 @@ void Server::setInventoryModified(const InventoryLocation &loc)
        break;
        case InventoryLocation::PLAYER:
        {
-               ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>
-                               (m_env->getPlayer(loc.name.c_str()));
-               if(!srp)
+               Player *player = m_env->getPlayer(loc.name.c_str());
+               if(!player)
+                       return;
+               PlayerSAO *playersao = player->getPlayerSAO();
+               if(!playersao)
                        return;
-               srp->m_inventory_not_sent = true;
+               playersao->m_inventory_not_sent = true;
+               playersao->m_wielded_item_not_sent = true;
        }
        break;
        case InventoryLocation::NODEMETA:
@@ -3482,20 +3456,17 @@ void Server::SendInventory(u16 peer_id)
 {
        DSTACK(__FUNCTION_NAME);
        
-       ServerRemotePlayer* player =
-                       static_cast<ServerRemotePlayer*>(m_env->getPlayer(peer_id));
-       assert(player);
+       PlayerSAO *playersao = getPlayerSAO(peer_id);
+       assert(playersao);
 
-       player->m_inventory_not_sent = false;
+       playersao->m_inventory_not_sent = false;
 
        /*
                Serialize it
        */
 
        std::ostringstream os;
-       //os.imbue(std::locale("C"));
-
-       player->inventory.serialize(os);
+       playersao->getInventory()->serialize(os);
 
        std::string s = os.str();
        
@@ -3507,52 +3478,6 @@ void Server::SendInventory(u16 peer_id)
        m_con.Send(peer_id, 0, data, true);
 }
 
-void Server::SendWieldedItem(const ServerRemotePlayer* srp)
-{
-       DSTACK(__FUNCTION_NAME);
-
-       assert(srp);
-
-       std::ostringstream os(std::ios_base::binary);
-
-       writeU16(os, TOCLIENT_PLAYERITEM);
-       writeU16(os, 1);
-       writeU16(os, srp->peer_id);
-       os<<serializeString(srp->getWieldedItem().getItemString());
-
-       // Make data buffer
-       std::string s = os.str();
-       SharedBuffer<u8> data((u8*)s.c_str(), s.size());
-
-       m_con.SendToAll(0, data, true);
-}
-
-void Server::SendPlayerItems()
-{
-       DSTACK(__FUNCTION_NAME);
-
-       std::ostringstream os(std::ios_base::binary);
-       core::list<Player *> players = m_env->getPlayers(true);
-
-       writeU16(os, TOCLIENT_PLAYERITEM);
-       writeU16(os, players.size());
-       core::list<Player *>::Iterator i;
-       for(i = players.begin(); i != players.end(); ++i)
-       {
-               Player *p = *i;
-               ServerRemotePlayer *srp =
-                       static_cast<ServerRemotePlayer*>(p);
-               writeU16(os, p->peer_id);
-               os<<serializeString(srp->getWieldedItem().getItemString());
-       }
-
-       // Make data buffer
-       std::string s = os.str();
-       SharedBuffer<u8> data((u8*)s.c_str(), s.size());
-
-       m_con.SendToAll(0, data, true);
-}
-
 void Server::SendChatMessage(u16 peer_id, const std::wstring &message)
 {
        DSTACK(__FUNCTION_NAME);
@@ -3599,17 +3524,22 @@ void Server::BroadcastChatMessage(const std::wstring &message)
        }
 }
 
-void Server::SendPlayerHP(Player *player)
+void Server::SendPlayerHP(u16 peer_id)
 {
-       SendHP(m_con, player->peer_id, player->hp);
-       static_cast<ServerRemotePlayer*>(player)->m_hp_not_sent = false;
+       DSTACK(__FUNCTION_NAME);
+       PlayerSAO *playersao = getPlayerSAO(peer_id);
+       assert(playersao);
+       playersao->m_hp_not_sent = false;
+       SendHP(m_con, peer_id, playersao->getHP());
 }
 
-void Server::SendMovePlayer(Player *player)
+void Server::SendMovePlayer(u16 peer_id)
 {
        DSTACK(__FUNCTION_NAME);
-       std::ostringstream os(std::ios_base::binary);
+       Player *player = m_env->getPlayer(peer_id);
+       assert(player);
 
+       std::ostringstream os(std::ios_base::binary);
        writeU16(os, TOCLIENT_MOVE_PLAYER);
        writeV3F1000(os, player->getPosition());
        writeF1000(os, player->getPitch());
@@ -3630,7 +3560,7 @@ void Server::SendMovePlayer(Player *player)
        std::string s = os.str();
        SharedBuffer<u8> data((u8*)s.c_str(), s.size());
        // Send as reliable
-       m_con.Send(player->peer_id, 0, data, true);
+       m_con.Send(peer_id, 0, data, true);
 }
 
 s32 Server::playSound(const SimpleSoundSpec &spec,
@@ -4242,41 +4172,44 @@ void Server::sendRequestedMedia(u16 peer_id,
        Something random
 */
 
-void Server::DiePlayer(Player *player)
+void Server::DiePlayer(u16 peer_id)
 {
-       ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
+       DSTACK(__FUNCTION_NAME);
+       
+       PlayerSAO *playersao = getPlayerSAO(peer_id);
+       assert(playersao);
 
        infostream<<"Server::DiePlayer(): Player "
-                       <<player->getName()<<" dies"<<std::endl;
-       
-       srp->setHP(0);
-       
+                       <<playersao->getPlayer()->getName()
+                       <<" dies"<<std::endl;
+
+       playersao->setHP(0);
+
        // Trigger scripted stuff
-       scriptapi_on_dieplayer(m_lua, srp);
-       
-       // Handle players that are not connected
-       if(player->peer_id == PEER_ID_INEXISTENT){
-               RespawnPlayer(player);
-               return;
-       }
+       scriptapi_on_dieplayer(m_lua, playersao);
 
-       SendPlayerHP(player);
-       SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
+       SendPlayerHP(peer_id);
+       SendDeathscreen(m_con, peer_id, false, v3f(0,0,0));
 }
 
-void Server::RespawnPlayer(Player *player)
+void Server::RespawnPlayer(u16 peer_id)
 {
-       ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
-       srp->setHP(20);
-       bool repositioned = scriptapi_on_respawnplayer(m_lua, srp);
+       DSTACK(__FUNCTION_NAME);
+
+       PlayerSAO *playersao = getPlayerSAO(peer_id);
+       assert(playersao);
+
+       infostream<<"Server::RespawnPlayer(): Player "
+                       <<playersao->getPlayer()->getName()
+                       <<" respawns"<<std::endl;
+
+       playersao->setHP(PLAYER_MAX_HP);
+
+       bool repositioned = scriptapi_on_respawnplayer(m_lua, playersao);
        if(!repositioned){
                v3f pos = findSpawnPos(m_env->getServerMap());
-               player->setPosition(pos);
-               srp->m_last_good_position = pos;
-               srp->m_last_good_position_age = 0;
+               playersao->setPos(pos);
        }
-       SendMovePlayer(player);
-       SendPlayerHP(player);
 }
 
 void Server::UpdateCrafting(u16 peer_id)
@@ -4542,46 +4475,21 @@ v3f findSpawnPos(ServerMap &map)
        return intToFloat(nodepos, BS);
 }
 
-ServerRemotePlayer *Server::emergePlayer(const char *name, u16 peer_id)
+PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
 {
+       RemotePlayer *player = NULL;
+       bool newplayer = false;
+
        /*
                Try to get an existing player
        */
-       ServerRemotePlayer *player =
-                       static_cast<ServerRemotePlayer*>(m_env->getPlayer(name));
-       if(player != NULL)
-       {
-               // If player is already connected, cancel
-               if(player->peer_id != 0)
-               {
-                       infostream<<"emergePlayer(): Player already connected"<<std::endl;
-                       return NULL;
-               }
-
-               // Got one.
-               player->peer_id = peer_id;
-               
-               // Re-add player to environment
-               if(player->m_removed)
-               {
-                       player->m_removed = false;
-                       player->setId(0);
-                       m_env->addActiveObject(player);
-               }
+       player = static_cast<RemotePlayer*>(m_env->getPlayer(name));
 
-               // Reset inventory to creative if in creative mode
-               if(g_settings->getBool("creative_mode"))
-               {
-                       // Warning: double code below
-                       // Backup actual inventory
-                       player->inventory_backup = new Inventory(m_itemdef);
-                       *(player->inventory_backup) = player->inventory;
-                       // Set creative inventory
-                       player->resetInventory();
-                       scriptapi_get_creative_inventory(m_lua, player);
-               }
-
-               return player;
+       // If player is already connected, cancel
+       if(player != NULL && player->peer_id != 0)
+       {
+               infostream<<"emergePlayer(): Player already connected"<<std::endl;
+               return NULL;
        }
 
        /*
@@ -4593,43 +4501,43 @@ ServerRemotePlayer *Server::emergePlayer(const char *name, u16 peer_id)
                                " peer_id already exists"<<std::endl;
                return NULL;
        }
-       
+
        /*
-               Create a new player
+               Create a new player if it doesn't exist yet
        */
+       if(player == NULL)
        {
+               newplayer = true;
+               player = new RemotePlayer(this);
+               player->updateName(name);
+
                /* Set player position */
-               
                infostream<<"Server: Finding spawn place for player \""
                                <<name<<"\""<<std::endl;
-
                v3f pos = findSpawnPos(m_env->getServerMap());
-
-               player = new ServerRemotePlayer(m_env, pos, peer_id, name);
-               ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
+               player->setPosition(pos);
 
                /* Add player to environment */
                m_env->addPlayer(player);
-               m_env->addActiveObject(srp);
+       }
 
-               /* Run scripts */
-               scriptapi_on_newplayer(m_lua, srp);
+       /*
+               Create a new player active object
+       */
+       PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id);
 
-               /* Add stuff to inventory */
-               if(g_settings->getBool("creative_mode"))
-               {
-                       // Warning: double code above
-                       // Backup actual inventory
-                       player->inventory_backup = new Inventory(m_itemdef);
-                       *(player->inventory_backup) = player->inventory;
-                       // Set creative inventory
-                       player->resetInventory();
-                       scriptapi_get_creative_inventory(m_lua, player);
-               }
+       /* Add object to environment */
+       m_env->addActiveObject(playersao);
 
-               return player;
-               
-       } // create new player
+       /* Run scripts */
+       if(newplayer)
+               scriptapi_on_newplayer(m_lua, playersao);
+
+       /* Creative mode */
+       if(g_settings->getBool("creative_mode"))
+               playersao->createCreativeInventory();
+
+       return playersao;
 }
 
 void Server::handlePeerChange(PeerChange &c)
@@ -4699,8 +4607,7 @@ void Server::handlePeerChange(PeerChange &c)
                                i++;
                }
 
-               ServerRemotePlayer* player =
-                               static_cast<ServerRemotePlayer*>(m_env->getPlayer(c.peer_id));
+               Player *player = m_env->getPlayer(c.peer_id);
 
                // Collect information about leaving in chat
                std::wstring message;
@@ -4717,12 +4624,8 @@ void Server::handlePeerChange(PeerChange &c)
                }
                
                // Remove from environment
-               if(player != NULL)
-                       player->m_removed = true;
-               
-               // Set player client disconnected
-               if(player != NULL)
-                       player->peer_id = 0;
+               if(player->getPlayerSAO())
+                       player->getPlayerSAO()->disconnected();
        
                /*
                        Print out action
index 1b0cff7831725835944254705d3d47cedb4ed911..d40c7c73e87f19ac9ec5eb1843d261e27b815486 100644 (file)
@@ -31,7 +31,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "ban.h"
 #include "gamedef.h"
 #include "serialization.h" // For SER_FMT_VER_INVALID
-#include "serverremoteplayer.h"
 #include "mods.h"
 #include "inventorymanager.h"
 #include "subgame.h"
@@ -42,6 +41,7 @@ class IWritableItemDefManager;
 class IWritableNodeDefManager;
 class IWritableCraftDefManager;
 class EventManager;
+class PlayerSAO;
 
 class ServerError : public std::exception
 {
@@ -299,26 +299,7 @@ struct ServerSoundParams
                loop(false)
        {}
        
-       v3f getPos(ServerEnvironment *env, bool *pos_exists) const
-       {
-               if(pos_exists) *pos_exists = false;
-               switch(type){
-               case SSP_LOCAL:
-                       return v3f(0,0,0);
-               case SSP_POSITIONAL:
-                       if(pos_exists) *pos_exists = true;
-                       return pos;
-               case SSP_OBJECT: {
-                       if(object == 0)
-                               return v3f(0,0,0);
-                       ServerActiveObject *sao = env->getActiveObject(object);
-                       if(!sao)
-                               return v3f(0,0,0);
-                       if(pos_exists) *pos_exists = true;
-                       return sao->getBasePosition(); }
-               }
-               return v3f(0,0,0);
-       }
+       v3f getPos(ServerEnvironment *env, bool *pos_exists) const;
 };
 
 struct ServerPlayingSound
@@ -514,9 +495,6 @@ public:
                m_shutdown_requested = true;
        }
 
-       // Envlock and conlock should be locked when calling this
-       void SendMovePlayer(Player *player);
-       
        // Returns -1 if failed, sound handle on success
        // Envlock + conlock
        s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams &params);
@@ -620,14 +598,11 @@ private:
        */
 
        // Envlock and conlock should be locked when calling these
+       void SendMovePlayer(u16 peer_id);
        void SendInventory(u16 peer_id);
-       // send wielded item info about player to all
-       void SendWieldedItem(const ServerRemotePlayer *srp);
-       // send wielded item info about all players to all players
-       void SendPlayerItems();
        void SendChatMessage(u16 peer_id, const std::wstring &message);
        void BroadcastChatMessage(const std::wstring &message);
-       void SendPlayerHP(Player *player);
+       void SendPlayerHP(u16 peer_id);
        /*
                Send a node removal/addition event to all clients except ignore_id.
                Additionally, if far_players!=NULL, players further away than
@@ -655,8 +630,8 @@ private:
                Something random
        */
        
-       void DiePlayer(Player *player);
-       void RespawnPlayer(Player *player);
+       void DiePlayer(u16 peer_id);
+       void RespawnPlayer(u16 peer_id);
        
        void UpdateCrafting(u16 peer_id);
        
@@ -672,6 +647,15 @@ private:
                return player->getName();
        }
 
+       // When called, environment mutex should be locked
+       PlayerSAO* getPlayerSAO(u16 peer_id)
+       {
+               Player *player = m_env->getPlayer(peer_id);
+               if(player == NULL)
+                       return NULL;
+               return player->getPlayerSAO();
+       }
+
        /*
                Get a player from memory or creates one.
                If player is already connected, return NULL
@@ -679,7 +663,7 @@ private:
 
                Call with env and con locked.
        */
-       ServerRemotePlayer *emergePlayer(const char *name, u16 peer_id);
+       PlayerSAO *emergePlayer(const char *name, u16 peer_id);
        
        // Locks environment and connection by its own
        struct PeerChange;
index e2e84bacb000945e4bf2ac08a392217cc8045fea..c5b242b2ee35f1d5d88b0b485f358b340911e924 100644 (file)
@@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "utility.h"
 #include "settings.h"
 #include "main.h" // For g_settings
+#include "content_sao.h"
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
 
@@ -216,20 +217,26 @@ void cmd_teleport(std::wostringstream &os,
                return;
        }
 
-       v3f dest(stoi(coords[0])*10, stoi(coords[1])*10, stoi(coords[2])*10);
+       v3f dest(stoi(coords[0])*BS, stoi(coords[1])*BS, stoi(coords[2])*BS);
 
        actionstream<<ctx->player->getName()<<" teleports from "
                        <<PP(ctx->player->getPosition()/BS)<<" to "
                        <<PP(dest/BS)<<std::endl;
 
-       //ctx->player->setPosition(dest);
-
-       // Use the ServerActiveObject interface of ServerRemotePlayer
-       ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(ctx->player);
-       srp->setPos(dest);
-       ctx->server->SendMovePlayer(ctx->player);
-
-       os<< L"-!- Teleported.";
+       // Use the ServerActiveObject interface of RemotePlayer
+       // This forces a position change on the client
+       ServerActiveObject *sao = ctx->player->getPlayerSAO();
+       if(sao)
+       {
+               sao->setPos(dest);
+               os<< L"-!- Teleported.";
+       }
+       else
+       {
+               errorstream<<"Teleport failed, player object not found!"
+                       <<std::endl;
+               os<< L"-!- Teleport failed.";
+       }
 }
 
 void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx)
index 15bbe52f7bbf8e132d2e3497ff3868c434eb4564..8719267d7b1ff0e1ea1f089e8a55f606ba007439 100644 (file)
@@ -143,7 +143,7 @@ public:
        {}
        virtual void setHP(s16 hp)
        {}
-       virtual s16 getHP()
+       virtual s16 getHP() const
        { return 0; }
 
        // Inventory and wielded item
diff --git a/src/serverremoteplayer.cpp b/src/serverremoteplayer.cpp
deleted file mode 100644 (file)
index 667ece7..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "serverremoteplayer.h"
-#include "main.h" // For g_settings
-#include "settings.h"
-#include "log.h"
-#include "gamedef.h"
-#include "inventory.h"
-#include "environment.h"
-#include "tool.h"
-
-ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
-       Player(env->getGameDef()),
-       ServerActiveObject(env, v3f(0,0,0)),
-       m_last_good_position(0,0,0),
-       m_last_good_position_age(0),
-       m_wield_index(0),
-       m_inventory_not_sent(false),
-       m_hp_not_sent(false),
-       m_is_in_environment(false),
-       m_time_from_last_punch(0),
-       m_position_not_sent(false)
-{
-}
-ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
-               const char *name_):
-       Player(env->getGameDef()),
-       ServerActiveObject(env, pos_),
-       m_last_good_position(0,0,0),
-       m_last_good_position_age(0),
-       m_wield_index(0),
-       m_inventory_not_sent(false),
-       m_hp_not_sent(false),
-       m_is_in_environment(false),
-       m_time_from_last_punch(0),
-       m_position_not_sent(false)
-{
-       setPosition(pos_);
-       peer_id = peer_id_;
-       updateName(name_);
-}
-ServerRemotePlayer::~ServerRemotePlayer()
-{
-}
-
-void ServerRemotePlayer::setPosition(const v3f &position)
-{
-       Player::setPosition(position);
-       ServerActiveObject::setBasePosition(position);
-       m_position_not_sent = true;
-}
-
-Inventory* ServerRemotePlayer::getInventory()
-{
-       return &inventory;
-}
-
-const Inventory* ServerRemotePlayer::getInventory() const
-{
-       return &inventory;
-}
-
-InventoryLocation ServerRemotePlayer::getInventoryLocation() const
-{
-       InventoryLocation loc;
-       loc.setPlayer(getName());
-       return loc;
-}
-
-void ServerRemotePlayer::setInventoryModified()
-{
-       m_inventory_not_sent = true;
-}
-
-std::string ServerRemotePlayer::getWieldList() const
-{
-       return "main";
-}
-
-int ServerRemotePlayer::getWieldIndex() const
-{
-       return m_wield_index;
-}
-
-void ServerRemotePlayer::setWieldIndex(int i)
-{
-       m_wield_index = i;
-}
-
-/* ServerActiveObject interface */
-
-void ServerRemotePlayer::addedToEnvironment()
-{
-       assert(!m_is_in_environment);
-       m_is_in_environment = true;
-}
-
-void ServerRemotePlayer::removingFromEnvironment()
-{
-       assert(m_is_in_environment);
-       m_is_in_environment = false;
-}
-
-bool ServerRemotePlayer::unlimitedTransferDistance() const
-{
-       return g_settings->getBool("unlimited_player_transfer_distance");
-}
-
-void ServerRemotePlayer::step(float dtime, bool send_recommended)
-{
-       m_time_from_last_punch += dtime;
-       
-       if(send_recommended == false)
-               return;
-       
-       if(m_position_not_sent)
-       {
-               m_position_not_sent = false;
-
-               std::ostringstream os(std::ios::binary);
-               // command (0 = update position)
-               writeU8(os, 0);
-               // pos
-               writeV3F1000(os, getPosition());
-               // yaw
-               writeF1000(os, getYaw());
-               // create message and add to list
-               ActiveObjectMessage aom(getId(), false, os.str());
-               m_messages_out.push_back(aom);
-       }
-}
-
-std::string ServerRemotePlayer::getClientInitializationData()
-{
-       std::ostringstream os(std::ios::binary);
-       // version
-       writeU8(os, 0);
-       // name
-       os<<serializeString(getName());
-       // pos
-       writeV3F1000(os, getPosition());
-       // yaw
-       writeF1000(os, getYaw());
-       // dead
-       writeU8(os, getHP() == 0);
-       return os.str();
-}
-
-std::string ServerRemotePlayer::getStaticData()
-{
-       assert(0);
-       return "";
-}
-
-int ServerRemotePlayer::punch(v3f dir,
-               const ToolCapabilities *toolcap,
-               ServerActiveObject *puncher,
-               float time_from_last_punch)
-{
-       if(!toolcap)
-               return 0;
-       
-       // No effect if PvP disabled
-       if(g_settings->getBool("enable_pvp") == false){
-               if(puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER)
-                       return 0;
-       }
-       
-       // "Material" groups of the player
-       ItemGroupList groups;
-       groups["choppy"] = 2;
-       groups["fleshy"] = 3;
-
-       HitParams hitparams = getHitParams(groups, toolcap, time_from_last_punch);
-       
-       actionstream<<"Player "<<getName()<<" punched by "
-                       <<puncher->getDescription()<<", damage "<<hitparams.hp
-                       <<" HP"<<std::endl;
-       
-       setHP(getHP() - hitparams.hp);
-       
-       if(hitparams.hp != 0)
-       {
-               std::ostringstream os(std::ios::binary);
-               // command (1 = punched)
-               writeU8(os, 1);
-               // damage
-               writeS16(os, hitparams.hp);
-               // create message and add to list
-               ActiveObjectMessage aom(getId(), false, os.str());
-               m_messages_out.push_back(aom);
-       }
-
-       return hitparams.wear;
-}
-
-void ServerRemotePlayer::rightClick(ServerActiveObject *clicker)
-{
-}
-
-void ServerRemotePlayer::setPos(v3f pos)
-{
-       setPosition(pos);
-       // Movement caused by this command is always valid
-       m_last_good_position = pos;
-       m_last_good_position_age = 0;
-}
-void ServerRemotePlayer::moveTo(v3f pos, bool continuous)
-{
-       setPosition(pos);
-       // Movement caused by this command is always valid
-       m_last_good_position = pos;
-       m_last_good_position_age = 0;
-}
-
-void ServerRemotePlayer::setHP(s16 hp_)
-{
-       s16 oldhp = hp;
-
-       // FIXME: don't hardcode maximum HP, make configurable per object
-       if(hp_ < 0)
-               hp_ = 0;
-       else if(hp_ > 20)
-               hp_ = 20;
-       hp = hp_;
-
-       if(hp != oldhp)
-               m_hp_not_sent = true;
-
-       // On death or reincarnation send an active object message
-       if((hp == 0) != (oldhp == 0))
-       {
-               std::ostringstream os(std::ios::binary);
-               // command (2 = update death state)
-               writeU8(os, 2);
-               // dead?
-               writeU8(os, hp == 0);
-               // create message and add to list
-               ActiveObjectMessage aom(getId(), false, os.str());
-               m_messages_out.push_back(aom);
-       }
-}
-s16 ServerRemotePlayer::getHP()
-{
-       return hp;
-}
-
-
diff --git a/src/serverremoteplayer.h b/src/serverremoteplayer.h
deleted file mode 100644 (file)
index 2ff1b00..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef SERVERREMOTEPLAYER_HEADER
-#define SERVERREMOTEPLAYER_HEADER
-
-#include "player.h"
-#include "serverobject.h"
-#include "content_object.h" // Object type IDs
-
-/*
-       Player on the server
-*/
-
-class ServerRemotePlayer : public Player, public ServerActiveObject
-{
-public:
-       ServerRemotePlayer(ServerEnvironment *env);
-       ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
-                       const char *name_);
-
-       virtual ~ServerRemotePlayer();
-
-       virtual bool isLocal() const
-       { return false; }
-
-       virtual void move(f32 dtime, Map &map, f32 pos_max_d)
-       {
-       }
-       
-       virtual void setPosition(const v3f &position);
-       
-       /* ServerActiveObject interface */
-
-       u8 getType() const
-       {return ACTIVEOBJECT_TYPE_PLAYER;}
-       
-       // Called after id has been set and has been inserted in environment
-       void addedToEnvironment();
-       // Called before removing from environment
-       void removingFromEnvironment();
-       
-       bool environmentDeletes() const
-       { return false; }
-
-       virtual bool unlimitedTransferDistance() const;
-       
-       bool isStaticAllowed() const
-       { return false; }
-
-       void step(float dtime, bool send_recommended);
-       std::string getClientInitializationData();
-       std::string getStaticData();
-       int punch(v3f dir,
-                       const ToolCapabilities *toolcap,
-                       ServerActiveObject *puncher,
-                       float time_from_last_punch);
-       void rightClick(ServerActiveObject *clicker);
-       void setPos(v3f pos);
-       void moveTo(v3f pos, bool continuous);
-       virtual std::string getDescription()
-       {return std::string("player ")+getName();}
-
-       virtual Inventory* getInventory();
-       virtual const Inventory* getInventory() const;
-       virtual InventoryLocation getInventoryLocation() const;
-       virtual void setInventoryModified();
-       virtual std::string getWieldList() const;
-       virtual int getWieldIndex() const;
-       virtual void setWieldIndex(int i);
-
-       virtual void setHP(s16 hp_);
-       virtual s16 getHP();
-       
-       v3f m_last_good_position;
-       float m_last_good_position_age;
-       int m_wield_index;
-       bool m_inventory_not_sent;
-       bool m_hp_not_sent;
-       bool m_is_in_environment;
-       // Incremented by step(), read and reset by Server
-       float m_time_from_last_punch;
-
-private:
-       bool m_position_not_sent;
-};
-
-#endif
-