]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/server.cpp
Fix building under MSVC
[dragonfireclient.git] / src / server.cpp
index 6b9e656e9a4566f260bcc4bf135941f38efeb36c..50141f843c64b9a8a95877755fc6ea0f6d5dcbba 100644 (file)
@@ -73,14 +73,14 @@ class ClientNotFoundException : public BaseException
        {}
 };
 
-class ServerThread : public SimpleThread
+class ServerThread : public JThread
 {
        Server *m_server;
 
 public:
 
        ServerThread(Server *server):
-               SimpleThread(),
+               JThread(),
                m_server(server)
        {
        }
@@ -90,15 +90,16 @@ class ServerThread : public SimpleThread
 
 void * ServerThread::Thread()
 {
-       ThreadStarted();
-
        log_register_thread("ServerThread");
 
        DSTACK(__FUNCTION_NAME);
-
        BEGIN_DEBUG_EXCEPTION_HANDLER
 
-       while(getRun())
+       m_server->AsyncRunStep(true);
+
+       ThreadStarted();
+
+       while(!StopRequested())
        {
                try{
                        //TimeTaker timer("AsyncRunStep() + Receive()");
@@ -675,6 +676,7 @@ Server::Server(
        m_savemap_timer = 0.0;
 
        m_step_dtime = 0.0;
+       m_lag = g_settings->getFloat("dedicated_server_step");
 
        if(path_world == "")
                throw ServerError("Supplied empty world path");
@@ -703,6 +705,10 @@ Server::Server(
        // Create emerge manager
        m_emerge = new EmergeManager(this);
 
+       // Create world if it doesn't exist
+       if(!initializeWorld(m_path_world, m_gamespec.id))
+               throw ServerError("Failed to initialize world");
+
        // Create ban manager
        std::string ban_path = m_path_world+DIR_DELIM+"ipban.txt";
        m_banmanager = new BanManager(ban_path);
@@ -711,10 +717,6 @@ Server::Server(
        std::string rollback_path = m_path_world+DIR_DELIM+"rollback.txt";
        m_rollback = createRollbackManager(rollback_path, this);
 
-       // Create world if it doesn't exist
-       if(!initializeWorld(m_path_world, m_gamespec.id))
-               throw ServerError("Failed to initialize world");
-
        ModConfiguration modconf(m_path_world);
        m_mods = modconf.getMods();
        std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods();
@@ -823,6 +825,7 @@ Server::Server(
        
        // Initialize mapgens
        m_emerge->initMapgens(mgparams);
+       servermap->setMapgenParams(m_emerge->params);
 
        // Give environment reference to scripting api
        m_script->initializeEnvironment(m_env);
@@ -962,14 +965,13 @@ void Server::start(unsigned short port)
        infostream<<"Starting server on port "<<port<<"..."<<std::endl;
 
        // Stop thread if already running
-       m_thread->stop();
+       m_thread->Stop();
 
        // Initialize connection
        m_con.SetTimeoutMs(30);
        m_con.Serve(port);
 
        // Start thread
-       m_thread->setRun(true);
        m_thread->Start();
 
        // ASCII art for the win!
@@ -992,9 +994,9 @@ void Server::stop()
        infostream<<"Server: Stopping and waiting threads"<<std::endl;
 
        // Stop threads (set run=false first so both start stopping)
-       m_thread->setRun(false);
+       m_thread->Stop();
        //m_emergethread.setRun(false);
-       m_thread->stop();
+       m_thread->Wait();
        //m_emergethread.stop();
 
        infostream<<"Server: Threads stopped"<<std::endl;
@@ -1017,7 +1019,7 @@ void Server::step(float dtime)
        }
 }
 
-void Server::AsyncRunStep()
+void Server::AsyncRunStep(bool initial_step)
 {
        DSTACK(__FUNCTION_NAME);
 
@@ -1034,7 +1036,7 @@ void Server::AsyncRunStep()
                SendBlocks(dtime);
        }
 
-       if(dtime < 0.001)
+       if((dtime < 0.001) && (initial_step == false))
                return;
 
        g_profiler->add("Server::AsyncRunStep with dtime (num)", 1);
@@ -1260,13 +1262,14 @@ void Server::AsyncRunStep()
        }
 
 
+       m_lag += (m_lag > dtime ? -1 : 1) * dtime/100;
 #if USE_CURL
        // send masterserver announce
        {
                float &counter = m_masterserver_timer;
                if(!isSingleplayer() && (!counter || counter >= 300.0) && g_settings->getBool("server_announce") == true)
                {
-                       ServerList::sendAnnounce(!counter ? "start" : "update", m_clients_names, m_uptime.get(), m_env->getGameTime(), m_gamespec.id, m_mods);
+                       ServerList::sendAnnounce(!counter ? "start" : "update", m_clients_names, m_uptime.get(), m_env->getGameTime(), m_lag, m_gamespec.id, m_mods);
                        counter = 0.01;
                }
                counter += dtime;
@@ -1526,7 +1529,7 @@ void Server::AsyncRunStep()
                                memcpy((char*)&reply[2], unreliable_data.c_str(),
                                                unreliable_data.size());
                                // Send as unreliable
-                               m_con.Send(client->peer_id, 0, reply, false);
+                               m_con.Send(client->peer_id, 1, reply, false);
                        }
 
                        /*if(reliable_data.size() > 0 || unreliable_data.size() > 0)
@@ -1681,7 +1684,7 @@ void Server::AsyncRunStep()
                {
                        counter = 0.0;
 
-                       m_emerge->triggerAllThreads();
+                       m_emerge->startAllThreads();
 
                        // Update m_enable_rollback_recording here too
                        m_enable_rollback_recording =
@@ -1970,6 +1973,19 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        return;
                }
 
+               {
+                       std::string reason;
+                       if(m_script->on_prejoinplayer(playername, addr_s, reason))
+                       {
+                               actionstream<<"Server: Player with the name \""<<playername<<"\" "
+                                               <<"tried to connect from "<<addr_s<<" "
+                                               <<"but it was disallowed for the following reason: "
+                                               <<reason<<std::endl;
+                               DenyAccess(peer_id, narrow_to_wide(reason.c_str()));
+                               return;
+                       }
+               }
+
                infostream<<"Server: New connection: \""<<playername<<"\" from "
                                <<addr_s<<" (peer_id="<<peer_id<<")"<<std::endl;
 
@@ -2731,7 +2747,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                std::string datastring((char*)&data[2], datasize-2);
                std::istringstream is(datastring, std::ios_base::binary);
 
-               std::list<MediaRequest> tosend;
+               std::list<std::string> tosend;
                u16 numfiles = readU16(is);
 
                infostream<<"Sending "<<numfiles<<" files to "
@@ -2740,7 +2756,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                for(int i = 0; i < numfiles; i++) {
                        std::string name = deSerializeString(is);
-                       tosend.push_back(MediaRequest(name));
+                       tosend.push_back(name);
                        verbosestream<<"TOSERVER_REQUEST_MEDIA: requested file "
                                        <<name<<std::endl;
                }
@@ -3557,7 +3573,7 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec,
 // Spawns a particle on peer with peer_id
 void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
                                float expirationtime, float size, bool collisiondetection,
-                               std::string texture)
+                               bool vertical, std::string texture)
 {
        DSTACK(__FUNCTION_NAME);
 
@@ -3570,6 +3586,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
        writeF1000(os, size);
        writeU8(os,  collisiondetection);
        os<<serializeLongString(texture);
+       writeU8(os, vertical);
 
        // Make data buffer
        std::string s = os.str();
@@ -3581,7 +3598,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
 // Spawns a particle on all peers
 void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
                                float expirationtime, float size, bool collisiondetection,
-                               std::string texture)
+                               bool vertical, std::string texture)
 {
        for(std::map<u16, RemoteClient*>::iterator
                i = m_clients.begin();
@@ -3594,14 +3611,14 @@ void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
                        continue;
 
                SendSpawnParticle(client->peer_id, pos, velocity, acceleration,
-                       expirationtime, size, collisiondetection, texture);
+                       expirationtime, size, collisiondetection, vertical, texture);
        }
 }
 
 // Adds a ParticleSpawner on peer with peer_id
 void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos,
        v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime,
-       float minsize, float maxsize, bool collisiondetection, std::string texture, u32 id)
+       float minsize, float maxsize, bool collisiondetection, bool vertical, std::string texture, u32 id)
 {
        DSTACK(__FUNCTION_NAME);
 
@@ -3623,6 +3640,7 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3
        writeU8(os,  collisiondetection);
        os<<serializeLongString(texture);
        writeU32(os, id);
+       writeU8(os, vertical);
 
        // Make data buffer
        std::string s = os.str();
@@ -3634,7 +3652,7 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3
 // Adds a ParticleSpawner on all peers
 void Server::SendAddParticleSpawnerAll(u16 amount, float spawntime, v3f minpos, v3f maxpos,
        v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime,
-       float minsize, float maxsize, bool collisiondetection, std::string texture, u32 id)
+       float minsize, float maxsize, bool collisiondetection, bool vertical, std::string texture, u32 id)
 {
        for(std::map<u16, RemoteClient*>::iterator
                i = m_clients.begin();
@@ -3648,7 +3666,7 @@ void Server::SendAddParticleSpawnerAll(u16 amount, float spawntime, v3f minpos,
 
                SendAddParticleSpawner(client->peer_id, amount, spawntime,
                        minpos, maxpos, minvel, maxvel, minacc, maxacc,
-                       minexptime, maxexptime, minsize, maxsize, collisiondetection, texture, id);
+                       minexptime, maxexptime, minsize, maxsize, collisiondetection, vertical, texture, id);
        }
 }
 
@@ -3706,7 +3724,7 @@ void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form)
        std::string s = os.str();
        SharedBuffer<u8> data((u8*)s.c_str(), s.size());
        // Send as reliable
-       m_con.Send(peer_id, 0, data, true);
+       m_con.Send(peer_id, 1, data, true);
 }
 
 void Server::SendHUDRemove(u16 peer_id, u32 id)
@@ -3721,7 +3739,8 @@ void Server::SendHUDRemove(u16 peer_id, u32 id)
        std::string s = os.str();
        SharedBuffer<u8> data((u8*)s.c_str(), s.size());
        // Send as reliable
-       m_con.Send(peer_id, 0, data, true);
+
+       m_con.Send(peer_id, 1, data, true);
 }
 
 void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value)
@@ -4189,7 +4208,7 @@ void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto
        /*
                Send packet
        */
-       m_con.Send(peer_id, 1, reply, true);
+       m_con.Send(peer_id, 2, reply, true);
 }
 
 void Server::SendBlocks(float dtime)
@@ -4439,7 +4458,7 @@ struct SendableMedia
 };
 
 void Server::sendRequestedMedia(u16 peer_id,
-               const std::list<MediaRequest> &tosend)
+               const std::list<std::string> &tosend)
 {
        DSTACK(__FUNCTION_NAME);
 
@@ -4456,17 +4475,19 @@ void Server::sendRequestedMedia(u16 peer_id,
 
        u32 file_size_bunch_total = 0;
 
-       for(std::list<MediaRequest>::const_iterator i = tosend.begin();
+       for(std::list<std::string>::const_iterator i = tosend.begin();
                        i != tosend.end(); ++i)
        {
-               if(m_media.find(i->name) == m_media.end()){
+               const std::string &name = *i;
+
+               if(m_media.find(name) == m_media.end()){
                        errorstream<<"Server::sendRequestedMedia(): Client asked for "
-                                       <<"unknown file \""<<(i->name)<<"\""<<std::endl;
+                                       <<"unknown file \""<<(name)<<"\""<<std::endl;
                        continue;
                }
 
                //TODO get path + name
-               std::string tpath = m_media[(*i).name].path;
+               std::string tpath = m_media[name].path;
 
                // Read data
                std::ifstream fis(tpath.c_str(), std::ios_base::binary);
@@ -4492,14 +4513,14 @@ void Server::sendRequestedMedia(u16 peer_id,
                }
                if(bad){
                        errorstream<<"Server::sendRequestedMedia(): Failed to read \""
-                                       <<(*i).name<<"\""<<std::endl;
+                                       <<name<<"\""<<std::endl;
                        continue;
                }
                /*infostream<<"Server::sendRequestedMedia(): Loaded \""
                                <<tname<<"\""<<std::endl;*/
                // Put in list
                file_bunches[file_bunches.size()-1].push_back(
-                               SendableMedia((*i).name, tpath, tmp_os.str()));
+                               SendableMedia(name, tpath, tmp_os.str()));
 
                // Start next bunch if got enough data
                if(file_size_bunch_total >= bytes_per_bunch){
@@ -4549,7 +4570,7 @@ void Server::sendRequestedMedia(u16 peer_id,
                                <<" size=" <<s.size()<<std::endl;
                SharedBuffer<u8> data((u8*)s.c_str(), s.size());
                // Send as reliable
-               m_con.Send(peer_id, 0, data, true);
+               m_con.Send(peer_id, 2, data, true);
        }
 }
 
@@ -5032,21 +5053,21 @@ void Server::notifyPlayers(const std::wstring msg)
 void Server::spawnParticle(const char *playername, v3f pos,
                v3f velocity, v3f acceleration,
                float expirationtime, float size, bool
-               collisiondetection, std::string texture)
+               collisiondetection, bool vertical, std::string texture)
 {
        Player *player = m_env->getPlayer(playername);
        if(!player)
                return;
        SendSpawnParticle(player->peer_id, pos, velocity, acceleration,
-                       expirationtime, size, collisiondetection, texture);
+                       expirationtime, size, collisiondetection, vertical, texture);
 }
 
 void Server::spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
                float expirationtime, float size,
-               bool collisiondetection, std::string texture)
+               bool collisiondetection, bool vertical, std::string texture)
 {
        SendSpawnParticleAll(pos, velocity, acceleration,
-                       expirationtime, size, collisiondetection, texture);
+                       expirationtime, size, collisiondetection, vertical, texture);
 }
 
 u32 Server::addParticleSpawner(const char *playername,
@@ -5056,7 +5077,7 @@ u32 Server::addParticleSpawner(const char *playername,
                v3f minacc, v3f maxacc,
                float minexptime, float maxexptime,
                float minsize, float maxsize,
-               bool collisiondetection, std::string texture)
+               bool collisiondetection, bool vertical, std::string texture)
 {
        Player *player = m_env->getPlayer(playername);
        if(!player)
@@ -5078,7 +5099,7 @@ u32 Server::addParticleSpawner(const char *playername,
        SendAddParticleSpawner(player->peer_id, amount, spawntime,
                minpos, maxpos, minvel, maxvel, minacc, maxacc,
                minexptime, maxexptime, minsize, maxsize,
-               collisiondetection, texture, id);
+               collisiondetection, vertical, texture, id);
 
        return id;
 }
@@ -5089,7 +5110,7 @@ u32 Server::addParticleSpawnerAll(u16 amount, float spawntime,
                v3f minacc, v3f maxacc,
                float minexptime, float maxexptime,
                float minsize, float maxsize,
-               bool collisiondetection, std::string texture)
+               bool collisiondetection, bool vertical, std::string texture)
 {
        u32 id = 0;
        for(;;) // look for unused particlespawner id
@@ -5107,7 +5128,7 @@ u32 Server::addParticleSpawnerAll(u16 amount, float spawntime,
        SendAddParticleSpawnerAll(amount, spawntime,
                minpos, maxpos, minvel, maxvel, minacc, maxacc,
                minexptime, maxexptime, minsize, maxsize,
-               collisiondetection, texture, id);
+               collisiondetection, vertical, texture, id);
 
        return id;
 }