Commented out debug statements again
[oweals/minetest.git] / src / server.cpp
index 8a19306a9a55b7c1aeeaf12274178f5248494acc..fd93d7523b22f872fdbf8f2b9106c403a6382b21 100644 (file)
@@ -380,8 +380,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
        v3s16 center = getNodeBlockPos(center_nodepos);
        
        // Camera position and direction
-       v3f camera_pos =
-                       playerpos + v3f(0, BS+BS/2, 0);
+       v3f camera_pos = player->getEyePosition();
        v3f camera_dir = v3f(0,0,1);
        camera_dir.rotateYZBy(player->getPitch());
        camera_dir.rotateXZBy(player->getYaw());
@@ -585,7 +584,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                Don't generate or send if not in sight
                        */
 
-                       if(isBlockInSight(p, camera_pos, camera_dir, 10000*BS) == false)
+                       if(isBlockInSight(p, camera_pos, camera_dir, M_PI, 10000*BS) == false)
                        {
                                continue;
                        }
@@ -775,6 +774,7 @@ void RemoteClient::SendObjectData(
                u16 command
                u16 number of player positions
                for each player:
+                       u16 peer_id
                        v3s32 position*100
                        v3s32 speed*100
                        s32 pitch*100
@@ -1064,6 +1064,7 @@ Server::Server(
        m_env(new ServerMap(mapsavedir), this),
        m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
        m_authmanager(mapsavedir+"/auth.txt"),
+       m_banmanager(mapsavedir+"/ipban.txt"),
        m_thread(this),
        m_emergethread(this),
        m_time_counter(0),
@@ -1252,6 +1253,20 @@ void Server::AsyncRunStep()
                m_uptime.set(m_uptime.get() + dtime);
        }
        
+       {
+               // Process connection's timeouts
+               JMutexAutoLock lock2(m_con_mutex);
+               ScopeProfiler sp(&g_profiler, "Server: connection timeout processing");
+               m_con.RunTimeouts(dtime);
+       }
+       
+       {
+               // This has to be called so that the client list gets synced
+               // with the peer list of the connection
+               ScopeProfiler sp(&g_profiler, "Server: peer change handling");
+               handlePeerChanges();
+       }
+
        /*
                Update m_time_of_day and overall game time
        */
@@ -1294,20 +1309,6 @@ void Server::AsyncRunStep()
                }
        }
 
-       {
-               // Process connection's timeouts
-               JMutexAutoLock lock2(m_con_mutex);
-               ScopeProfiler sp(&g_profiler, "Server: connection timeout processing");
-               m_con.RunTimeouts(dtime);
-       }
-       
-       {
-               // This has to be called so that the client list gets synced
-               // with the peer list of the connection
-               ScopeProfiler sp(&g_profiler, "Server: peer change handling");
-               handlePeerChanges();
-       }
-
        {
                JMutexAutoLock lock(m_env_mutex);
                // Step environment
@@ -1732,9 +1733,15 @@ void Server::AsyncRunStep()
                        }
                        else if(event->type == MEET_OTHER)
                        {
+                               dstream<<"Server: MEET_OTHER"<<std::endl;
                                prof.add("MEET_OTHER", 1);
-                               dstream<<"WARNING: Server: MEET_OTHER not implemented"
-                                               <<std::endl;
+                               for(core::map<v3s16, bool>::Iterator
+                                               i = event->modified_blocks.getIterator();
+                                               i.atEnd()==false; i++)
+                               {
+                                       v3s16 p = i.getNode()->getKey();
+                                       setBlockNotSent(p);
+                               }
                        }
                        else
                        {
@@ -1835,6 +1842,10 @@ void Server::AsyncRunStep()
                        // Auth stuff
                        if(m_authmanager.isModified())
                                m_authmanager.save();
+
+                       //Bann stuff
+                       if(m_banmanager.isModified())
+                               m_banmanager.save();
                        
                        // Map
                        JMutexAutoLock lock(m_env_mutex);
@@ -1924,6 +1935,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                <<peer_id<<" not found"<<std::endl;
                return;
        }
+
+       // drop player if is ip is banned
+       if(m_banmanager.isIpBanned(peer->address.serializeString())){
+               SendAccessDenied(m_con, peer_id,
+                               L"Your ip is banned. Banned name was "
+                               +narrow_to_wide(m_banmanager.getBanName(
+                                       peer->address.serializeString())));
+               m_con.deletePeer(peer_id, false);
+               return;
+       }
        
        u8 peer_ser_ver = getClient(peer->id)->serialization_version;
 
@@ -1960,7 +1981,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                //peer->serialization_version = deployed;
                getClient(peer->id)->pending_serialization_version = deployed;
-
+               
                if(deployed == SER_FMT_VER_INVALID)
                {
                        derr_server<<DTIME<<"Server: Cannot negotiate "
@@ -2158,6 +2179,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                UpdateCrafting(peer->id);
                SendInventory(peer->id);
 
+               // Send player items to all players
+               SendPlayerItems();
+
                // Send HP
                {
                        Player *player = m_env.getPlayer(peer_id);
@@ -2422,7 +2446,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                        if(g_settings.getBool("creative_mode") == false)
                                        {
                                                // Skip if inventory has no free space
-                                               if(ilist->getUsedSlots() == ilist->getSize())
+                                               if(ilist->roomForItem(item) == false)
                                                {
                                                        dout_server<<"Player inventory has no free space"<<std::endl;
                                                        return;
@@ -2899,6 +2923,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                        return;
                                }
 
+                               /*
+                                       If in creative mode, item dropping is disabled unless
+                                       player has build privileges
+                               */
+                               if(g_settings.getBool("creative_mode") &&
+                                       (getPlayerPrivs(player) & PRIV_BUILD) == 0)
+                               {
+                                       derr_server<<"Not allowing player to drop item: "
+                                                       "creative mode and no build privs"<<std::endl;
+                                       return;
+                               }
+
                                dout_server<<"Placing a miscellaneous item on map"
                                                <<std::endl;
                                
@@ -3162,6 +3198,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                mlist->addItem(item1);
                                        }
                                }
+                               // Disallow moving items if not allowed to build
+                               else if((getPlayerPrivs(player) & PRIV_BUILD) == 0)
+                                       return;
                        }
                        
                        if(disable_action == false)
@@ -3222,13 +3261,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                u64 privs = getPlayerPrivs(player);
 
                // Parse commands
-               std::wstring commandprefix = L"/#";
-               if(message.substr(0, commandprefix.size()) == commandprefix)
+               if(message[0] == L'/')
                {
-                       line += L"Server: ";
+                       size_t strip_size = 1;
+                       if (message[1] == L'#') // support old-style commans
+                               ++strip_size;
+                       message = message.substr(strip_size);
 
-                       message = message.substr(commandprefix.size());
-                       
                        WStrfnd f1(message);
                        f1.next(L" "); // Skip over /#whatever
                        std::wstring paramstring = f1.next(L"");
@@ -3241,9 +3280,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                player,
                                privs);
 
-                       line += processServerCommand(ctx);
-                       send_to_sender = ctx->flags & 1;
-                       send_to_others = ctx->flags & 2;
+                       std::wstring reply(processServerCommand(ctx));
+                       send_to_sender = ctx->flags & SEND_TO_SENDER;
+                       send_to_others = ctx->flags & SEND_TO_OTHERS;
+
+                       if (ctx->flags & SEND_NO_PREFIX)
+                               line += reply;
+                       else
+                               line += L"Server: " + reply;
+
                        delete ctx;
 
                }
@@ -3382,6 +3427,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                <<std::endl;
                SendChatMessage(peer_id, L"Password change successful");
        }
+       else if (command == TOSERVER_PLAYERITEM)
+       {
+               if (datasize < 2+2)
+                       return;
+
+               u16 item = readU16(&data[2]);
+               player->wieldItem(item);
+               SendWieldedItem(player);
+       }
        else
        {
                derr_server<<"WARNING: Server::ProcessData(): Ignoring "
@@ -3666,6 +3720,60 @@ void Server::SendInventory(u16 peer_id)
        m_con.Send(peer_id, 0, data, true);
 }
 
+std::string getWieldedItemString(const Player *player)
+{
+       const InventoryItem *item = player->getWieldItem();
+       if (item == NULL)
+               return std::string("");
+       std::ostringstream os(std::ios_base::binary);
+       item->serialize(os);
+       return os.str();
+}
+
+void Server::SendWieldedItem(const Player* player)
+{
+       DSTACK(__FUNCTION_NAME);
+
+       assert(player);
+
+       std::ostringstream os(std::ios_base::binary);
+
+       writeU16(os, TOCLIENT_PLAYERITEM);
+       writeU16(os, 1);
+       writeU16(os, player->peer_id);
+       os<<serializeString(getWieldedItemString(player));
+
+       // 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;
+               writeU16(os, p->peer_id);
+               os<<serializeString(getWieldedItemString(p));
+       }
+
+       // 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);