X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fserver.cpp;h=1e644ce6ce3a672a5f4d414f63409a66940e0fad;hb=37b7f094e3ea502339794f64e8bad22444c6fb54;hp=288f254ed5b815b27bb357253f5d41f90f76c085;hpb=1cd512913e4d4ad1fb43d4b6e3d7971bb6c67528;p=oweals%2Fminetest.git diff --git a/src/server.cpp b/src/server.cpp index 288f254ed..1e644ce6c 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -344,7 +344,7 @@ Server::Server( // Initialize Environment ServerMap *servermap = new ServerMap(path_world, this, m_emerge); - m_env = new ServerEnvironment(servermap, m_script, this); + m_env = new ServerEnvironment(servermap, m_script, this, m_path_world); m_clients.setEnv(m_env); @@ -361,19 +361,13 @@ Server::Server( servermap->addEventReceiver(this); // If file exists, load environment metadata - if(fs::PathExists(m_path_world+DIR_DELIM+"env_meta.txt")) + if(fs::PathExists(m_path_world + DIR_DELIM "env_meta.txt")) { infostream<<"Server: Loading environment metadata"<loadMeta(m_path_world); + m_env->loadMeta(); } - // Load players - infostream<<"Server: Loading players"<deSerializePlayers(m_path_world); - - /* - Add some test ActiveBlockModifiers to environment - */ + // Add some test ActiveBlockModifiers to environment add_legacy_abms(m_env, m_nodedef); m_liquid_transform_every = g_settings->getFloat("liquid_update"); @@ -383,42 +377,23 @@ Server::~Server() { infostream<<"Server destructing"<on_shutdown(); - } - - { - JMutexAutoLock envlock(m_env_mutex); - /* - Save players - */ infostream<<"Server: Saving players"<serializePlayers(m_path_world); + m_env->saveLoadedPlayers(); - /* - Save environment metadata - */ infostream<<"Server: Saving environment metadata"<saveMeta(m_path_world); + m_env->saveMeta(); } - /* - Stop threads - */ + // Stop threads stop(); delete m_thread; @@ -444,12 +419,10 @@ Server::~Server() delete m_script; // Delete detached inventories - { - for(std::map::iterator - i = m_detached_inventories.begin(); - i != m_detached_inventories.end(); i++){ - delete i->second; - } + for (std::map::iterator + i = m_detached_inventories.begin(); + i != m_detached_inventories.end(); i++) { + delete i->second; } } @@ -703,15 +676,15 @@ void Server::AsyncRunStep(bool initial_step) { float &counter = m_masterserver_timer; if(!isSingleplayer() && (!counter || counter >= 300.0) && - g_settings->getBool("server_announce") == true) + g_settings->getBool("server_announce")) { - ServerList::sendAnnounce(!counter ? "start" : "update", - m_clients.getPlayerNames(), - m_uptime.get(), - m_env->getGameTime(), - m_lag, - m_gamespec.id, - m_mods); + ServerList::sendAnnounce(counter ? "update" : "start", + m_clients.getPlayerNames(), + m_uptime.get(), + m_env->getGameTime(), + m_lag, + m_gamespec.id, + m_mods); counter = 0.01; } counter += dtime; @@ -741,7 +714,7 @@ void Server::AsyncRunStep(bool initial_step) // If definitions and textures have not been sent, don't // send objects either - if (client->getState() < DefinitionsSent) + if (client->getState() < CS_DefinitionsSent) continue; Player *player = m_env->getPlayer(client->peer_id); @@ -1141,18 +1114,19 @@ void Server::AsyncRunStep(bool initial_step) ScopeProfiler sp(g_profiler, "Server: saving stuff"); - //Ban stuff - if(m_banmanager->isModified()) + // Save ban file + if (m_banmanager->isModified()) { m_banmanager->save(); + } // Save changed parts of map m_env->getMap().save(MOD_STATE_WRITE_NEEDED); // Save players - m_env->serializePlayers(m_path_world); + m_env->saveLoadedPlayers(); // Save environment metadata - m_env->saveMeta(m_path_world); + m_env->saveMeta(); } } } @@ -1173,20 +1147,10 @@ void Server::Receive() "InvalidIncomingDataException: what()=" <removePlayer(peer_id);*/ + catch(SerializationError &e) { + infostream<<"Server::Receive(): " + "SerializationError: what()=" + <getName(); playersao = emergePlayer(playername.c_str(), peer_id); @@ -1291,7 +1259,7 @@ PlayerSAO* Server::StageTwoClientInit(u16 peer_id) actionstream << *i << " "; } - actionstream<getName() <getState() > Created) + if(client->getState() > CS_Created) { verbosestream<<"Server: Ignoring multiple TOSERVER_INITs from " <= g_settings->getU16("max_users") && + if(m_clients.getClientIDs(CS_Created).size() >= g_settings->getU16("max_users") && !checkPriv(playername, "server") && !checkPriv(playername, "ban") && !checkPriv(playername, "privs") && @@ -1637,7 +1605,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // Send as reliable m_clients.send(peer_id, 0, reply, true); - m_clients.event(peer_id, Init); + m_clients.event(peer_id, CSE_Init); } return; @@ -1649,7 +1617,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) verbosestream<<"Server: Got TOSERVER_INIT2 from " <on_joinplayer(playersao); } ///// end compatibility code @@ -1713,8 +1681,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) return; } - u8 peer_ser_ver = getClient(peer_id,InitDone)->serialization_version; - u16 peer_proto_ver = getClient(peer_id,InitDone)->net_proto_version; + u8 peer_ser_ver = getClient(peer_id, CS_InitDone)->serialization_version; + u16 peer_proto_ver = getClient(peer_id, CS_InitDone)->net_proto_version; if(peer_ser_ver == SER_FMT_VER_INVALID) { @@ -1752,7 +1720,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) else if(command == TOSERVER_CLIENT_READY) { // clients <= protocol version 22 did not send ready message, // they're already initialized - assert(peer_proto_ver > 22); + if (peer_proto_ver <= 22) { + infostream << "Client sent message not expected by a " + << "client using protocol version <= 22," + << "disconnecing peer_id: " << peer_id << std::endl; + m_con.DisconnectPeer(peer_id); + return; + } PlayerSAO* playersao = StageTwoClientInit(peer_id); @@ -1772,7 +1746,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) data[2], data[3], data[4], std::string((char*) &data[8],(u16) data[6])); - m_clients.event(peer_id, SetClientReady); + m_clients.event(peer_id, CSE_SetClientReady); m_script->on_joinplayer(playersao); } @@ -1804,7 +1778,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) return; } - if (m_clients.getClientState(peer_id) < Active) + if (m_clients.getClientState(peer_id) < CS_Active) { if (command == TOSERVER_PLAYERPOS) return; @@ -1815,18 +1789,20 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } Player *player = m_env->getPlayer(peer_id); - if(player == NULL){ + if(player == NULL) { errorstream<<"Server::ProcessData(): Cancelling: " "No player for peer_id="<getPlayerSAO(); - if(playersao == NULL){ + if(playersao == NULL) { errorstream<<"Server::ProcessData(): Cancelling: " "No player object for peer_id="<id=" <id<<", timeout="<id,Disconnect); + m_clients.event(peer->id, CSE_Disconnect); con::PeerChange c; c.type = con::PEER_REMOVED; c.peer_id = peer->id; @@ -2892,10 +2868,12 @@ bool Server::getClientInfo( { *state = m_clients.getClientState(peer_id); m_clients.Lock(); - RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id,Invalid); + RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid); - if (client == NULL) + if (client == NULL) { + m_clients.Unlock(); return false; + } *uptime = client->uptime(); *ser_vers = client->serialization_version; @@ -3156,10 +3134,11 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec, std::ostringstream os(std::ios_base::binary); u8 buf[12]; + // Write command writeU16(buf, TOCLIENT_SHOW_FORMSPEC); os.write((char*)buf, 2); - os<inventory_formspec); + os<inventory_formspec); // Make data buffer std::string s = os.str(); @@ -3861,7 +3844,7 @@ void Server::SendBlocks(float dtime) i = clients.begin(); i != clients.end(); ++i) { - RemoteClient *client = m_clients.lockedGetClientNoEx(*i,Active); + RemoteClient *client = m_clients.lockedGetClientNoEx(*i, CS_Active); if (client == NULL) return; @@ -3897,7 +3880,7 @@ void Server::SendBlocks(float dtime) continue; } - RemoteClient *client = m_clients.lockedGetClientNoEx(q.peer_id,Active); + RemoteClient *client = m_clients.lockedGetClientNoEx(q.peer_id, CS_Active); if(!client) continue; @@ -4288,7 +4271,7 @@ void Server::DenyAccess(u16 peer_id, const std::wstring &reason) DSTACK(__FUNCTION_NAME); SendAccessDenied(peer_id, reason); - m_clients.event(peer_id,SetDenied); + m_clients.event(peer_id, CSE_SetDenied); m_con.DisconnectPeer(peer_id); } @@ -4554,24 +4537,25 @@ bool Server::showFormspec(const char *playername, const std::string &formspec, c u32 Server::hudAdd(Player *player, HudElement *form) { if (!player) return -1; - - u32 id = player->getFreeHudID(); - if (id < player->hud.size()) - player->hud[id] = form; - else - player->hud.push_back(form); + u32 id = player->addHud(form); + SendHUDAdd(player->peer_id, id, form); + return id; } bool Server::hudRemove(Player *player, u32 id) { - if (!player || id >= player->hud.size() || !player->hud[id]) + if (!player) return false; - delete player->hud[id]; - player->hud[id] = NULL; + HudElement* todel = player->removeHud(id); + + if (!todel) + return false; + delete todel; + SendHUDRemove(player->peer_id, id); return true; } @@ -4589,6 +4573,7 @@ bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) { return false; SendHUDSetFlags(player->peer_id, flags, mask); + player->hud_flags = flags; m_script->player_event(player->getPlayerSAO(),"hud_changed"); return true; @@ -5013,15 +4998,16 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id) return NULL; } - /* - Create a new player if it doesn't exist yet - */ - if(player == NULL) - { + // Load player if it isn't already loaded + if (!player) { + player = static_cast(m_env->loadPlayer(name)); + } + + // Create player if it doesn't exist + if (!player) { newplayer = true; player = new RemotePlayer(this); player->updateName(name); - /* Set player position */ infostream<<"Server: Finding spawn place for player \"" <addPlayer(player); } - /* - Create a new player active object - */ + // Create a new player active object PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id, getPlayerEffectivePrivs(player->getName()), isSingleplayer()); /* Clean up old HUD elements from previous sessions */ - player->hud.clear(); + player->clearHud(); /* Add object to environment */ m_env->addActiveObject(playersao); /* Run scripts */ - if(newplayer) + if (newplayer) { m_script->on_newplayer(playersao); + } return playersao; }