Update Mapgen VoxelManipulator on buffer invalidation
[oweals/minetest.git] / src / clientiface.cpp
index 5394cd0029b503ede00ce44180ff53bc0e409310..ebbbc65bcf9a5f31c54a0bdfa41abe641a299aa4 100644 (file)
@@ -17,6 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#include <sstream>
+
 #include "clientiface.h"
 #include "player.h"
 #include "settings.h"
@@ -32,6 +34,32 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "main.h"                      // for g_settings
 
+const char *ClientInterface::statenames[] = {
+       "Invalid",
+       "Disconnecting",
+       "Denied",
+       "Created",
+       "InitSent",
+       "InitDone",
+       "DefinitionsSent",
+       "Active"
+};
+
+
+
+std::string ClientInterface::state2Name(ClientState state)
+{
+       return statenames[state];
+}
+
+void RemoteClient::ResendBlockIfOnWire(v3s16 p)
+{
+       // if this block is on wire, mark it for sending again as soon as possible
+       if (m_blocks_sending.find(p) != m_blocks_sending.end()) {
+               SetBlockNotSent(p);
+       }
+}
+
 void RemoteClient::GetNextBlocks(
                ServerEnvironment *env,
                EmergeManager * emerge,
@@ -397,125 +425,118 @@ void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks)
 
 void RemoteClient::notifyEvent(ClientStateEvent event)
 {
+       std::ostringstream myerror;
        switch (m_state)
        {
-       case Invalid:
-               assert("State update for client in invalid state" != 0);
+       case CS_Invalid:
+               //intentionally do nothing
                break;
-
-       case Created:
+       case CS_Created:
                switch(event)
                {
-               case Init:
-                       m_state = InitSent;
+               case CSE_Init:
+                       m_state = CS_InitSent;
                        break;
-
-               case Disconnect:
-                       m_state = Disconnecting;
+               case CSE_Disconnect:
+                       m_state = CS_Disconnecting;
                        break;
-
-               case SetDenied:
-                       m_state = Denied;
+               case CSE_SetDenied:
+                       m_state = CS_Denied;
                        break;
-
                /* GotInit2 SetDefinitionsSent SetMediaSent */
                default:
-                       assert("Invalid client state transition!" == 0);
+                       myerror << "Created: Invalid client state transition! " << event;
+                       throw ClientStateError(myerror.str());
                }
                break;
-
-       case Denied:
+       case CS_Denied:
                /* don't do anything if in denied state */
                break;
-
-       case InitSent:
+       case CS_InitSent:
                switch(event)
                {
-               case GotInit2:
+               case CSE_GotInit2:
                        confirmSerializationVersion();
-                       m_state = InitDone;
+                       m_state = CS_InitDone;
                        break;
-
-               case Disconnect:
-                       m_state = Disconnecting;
+               case CSE_Disconnect:
+                       m_state = CS_Disconnecting;
                        break;
-
-               case SetDenied:
-                       m_state = Denied;
+               case CSE_SetDenied:
+                       m_state = CS_Denied;
                        break;
 
                /* Init SetDefinitionsSent SetMediaSent */
                default:
-                       assert("Invalid client state transition!" == 0);
+                       myerror << "InitSent: Invalid client state transition! " << event;
+                       throw ClientStateError(myerror.str());
                }
                break;
 
-       case InitDone:
+       case CS_InitDone:
                switch(event)
                {
-               case SetDefinitionsSent:
-                       m_state = DefinitionsSent;
+               case CSE_SetDefinitionsSent:
+                       m_state = CS_DefinitionsSent;
                        break;
-
-               case Disconnect:
-                       m_state = Disconnecting;
+               case CSE_Disconnect:
+                       m_state = CS_Disconnecting;
                        break;
-
-               case SetDenied:
-                       m_state = Denied;
+               case CSE_SetDenied:
+                       m_state = CS_Denied;
                        break;
 
                /* Init GotInit2 SetMediaSent */
                default:
-                       assert("Invalid client state transition!" == 0);
+                       myerror << "InitDone: Invalid client state transition! " << event;
+                       throw ClientStateError(myerror.str());
                }
                break;
-
-       case DefinitionsSent:
+       case CS_DefinitionsSent:
                switch(event)
                {
-               case SetMediaSent:
-                       m_state = Active;
+               case CSE_SetClientReady:
+                       m_state = CS_Active;
                        break;
-
-               case Disconnect:
-                       m_state = Disconnecting;
+               case CSE_Disconnect:
+                       m_state = CS_Disconnecting;
                        break;
-
-               case SetDenied:
-                       m_state = Denied;
+               case CSE_SetDenied:
+                       m_state = CS_Denied;
                        break;
-
                /* Init GotInit2 SetDefinitionsSent */
                default:
-                       assert("Invalid client state transition!" == 0);
+                       myerror << "DefinitionsSent: Invalid client state transition! " << event;
+                       throw ClientStateError(myerror.str());
                }
                break;
-
-       case Active:
+       case CS_Active:
                switch(event)
                {
-               case SetDenied:
-                       m_state = Denied;
+               case CSE_SetDenied:
+                       m_state = CS_Denied;
                        break;
-
-               case Disconnect:
-                       m_state = Disconnecting;
+               case CSE_Disconnect:
+                       m_state = CS_Disconnecting;
                        break;
-
                /* Init GotInit2 SetDefinitionsSent SetMediaSent SetDenied */
                default:
-                       assert("Invalid client state transition!" == 0);
+                       myerror << "Active: Invalid client state transition! " << event;
+                       throw ClientStateError(myerror.str());
                        break;
                }
                break;
-
-       case Disconnecting:
+       case CS_Disconnecting:
                /* we are already disconnecting */
                break;
        }
 }
 
+u32 RemoteClient::uptime()
+{
+       return getTime(PRECISION_SECONDS) - m_connection_time;
+}
+
 ClientInterface::ClientInterface(con::Connection* con)
 :
        m_con(con),
@@ -667,7 +688,7 @@ ClientState ClientInterface::getClientState(u16 peer_id)
        // The client may not exist; clients are immediately removed if their
        // access is denied, and this event occurs later then.
        if(n == m_clients.end())
-               return Invalid;
+               return CS_Invalid;
 
        return n->second->getState();
 }
@@ -749,7 +770,9 @@ void ClientInterface::event(u16 peer_id, ClientStateEvent event)
                n->second->notifyEvent(event);
        }
 
-       if ((event == SetMediaSent) || (event == Disconnect) || (event == SetDenied))
+       if ((event == CSE_SetClientReady) ||
+               (event == CSE_Disconnect)     ||
+               (event == CSE_SetDenied))
        {
                UpdatePlayerList();
        }
@@ -763,9 +786,24 @@ u16 ClientInterface::getProtocolVersion(u16 peer_id)
        std::map<u16, RemoteClient*>::iterator n;
        n = m_clients.find(peer_id);
 
-       // No client to deliver event
+       // No client to get version
        if (n == m_clients.end())
                return 0;
 
        return n->second->net_proto_version;
 }
+
+void ClientInterface::setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full)
+{
+       JMutexAutoLock conlock(m_clients_mutex);
+
+       // Error check
+       std::map<u16, RemoteClient*>::iterator n;
+       n = m_clients.find(peer_id);
+
+       // No client to set versions
+       if (n == m_clients.end())
+               return;
+
+       n->second->setVersionInfo(major,minor,patch,full);
+}