diff options
Diffstat (limited to 'src/server.cpp')
-rw-r--r-- | src/server.cpp | 137 |
1 files changed, 68 insertions, 69 deletions
diff --git a/src/server.cpp b/src/server.cpp index b5352749c..a8d452783 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -351,6 +351,8 @@ Server::~Server() // Deinitialize scripting infostream << "Server: Deinitializing scripting" << std::endl; delete m_script; + delete m_startup_server_map; // if available + delete m_game_settings; while (!m_unsent_map_edit_queue.empty()) { delete m_unsent_map_edit_queue.front(); @@ -368,6 +370,8 @@ void Server::init() infostream << "- world: " << m_path_world << std::endl; infostream << "- game: " << m_gamespec.path << std::endl; + m_game_settings = Settings::createLayer(SL_GAME); + // Create world if it doesn't exist try { loadGameConfAndInitWorld(m_path_world, @@ -396,6 +400,7 @@ void Server::init() // Create the Map (loads map_meta.txt, overriding configured mapgen params) ServerMap *servermap = new ServerMap(m_path_world, this, m_emerge, m_metrics_backend.get()); + m_startup_server_map = servermap; // Initialize scripting infostream << "Server: Initializing Lua" << std::endl; @@ -437,6 +442,7 @@ void Server::init() m_craftdef->initHashes(this); // Initialize Environment + m_startup_server_map = nullptr; // Ownership moved to ServerEnvironment m_env = new ServerEnvironment(servermap, m_script, this, m_path_world); m_inventory_mgr->setEnv(m_env); @@ -1239,20 +1245,8 @@ bool Server::getClientConInfo(session_t peer_id, con::rtt_stat_type type, float* return *retval != -1; } -bool Server::getClientInfo( - session_t peer_id, - ClientState* state, - u32* uptime, - u8* ser_vers, - u16* prot_vers, - u8* major, - u8* minor, - u8* patch, - std::string* vers_string, - std::string* lang_code - ) -{ - *state = m_clients.getClientState(peer_id); +bool Server::getClientInfo(session_t peer_id, ClientInfo &ret) +{ m_clients.lock(); RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid); @@ -1261,15 +1255,18 @@ bool Server::getClientInfo( return false; } - *uptime = client->uptime(); - *ser_vers = client->serialization_version; - *prot_vers = client->net_proto_version; + ret.state = client->getState(); + ret.addr = client->getAddress(); + ret.uptime = client->uptime(); + ret.ser_vers = client->serialization_version; + ret.prot_vers = client->net_proto_version; + + ret.major = client->getMajor(); + ret.minor = client->getMinor(); + ret.patch = client->getPatch(); + ret.vers_string = client->getFullVer(); - *major = client->getMajor(); - *minor = client->getMinor(); - *patch = client->getPatch(); - *vers_string = client->getFull(); - *lang_code = client->getLangCode(); + ret.lang_code = client->getLangCode(); m_clients.unlock(); @@ -1355,7 +1352,7 @@ void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason return; session_t peer_id = playersao->getPeerID(); - bool is_alive = playersao->getHP() > 0; + bool is_alive = !playersao->isDead(); if (is_alive) SendPlayerHP(peer_id); @@ -1488,7 +1485,8 @@ void Server::SendChatMessage(session_t peer_id, const ChatMessage &message) NetworkPacket pkt(TOCLIENT_CHAT_MESSAGE, 0, peer_id); u8 version = 1; u8 type = message.type; - pkt << version << type << std::wstring(L"") << message.message << (u64)message.timestamp; + pkt << version << type << message.sender << message.message + << static_cast<u64>(message.timestamp); if (peer_id != PEER_ID_INEXISTENT) { RemotePlayer *player = m_env->getPlayer(peer_id); @@ -1823,6 +1821,9 @@ void Server::SendMovePlayer(session_t peer_id) PlayerSAO *sao = player->getPlayerSAO(); assert(sao); + // Send attachment updates instantly to the client prior updating position + sao->sendOutdatedData(); + NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id); pkt << sao->getBasePosition() << sao->getLookPitch() << sao->getRotation().Y; @@ -2495,7 +2496,9 @@ void Server::fillMediaCache() // Collect all media file paths std::vector<std::string> paths; - // The paths are ordered in descending priority + + // ordered in descending priority + paths.push_back(getBuiltinLuaPath() + DIR_DELIM + "locale"); fs::GetRecursiveDirs(paths, porting::path_user + DIR_DELIM + "textures" + DIR_DELIM + "server"); fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures"); m_modmgr->getModsMediaPaths(paths); @@ -2961,7 +2964,7 @@ void Server::handleChatInterfaceEvent(ChatEvent *evt) } } -std::wstring Server::handleChat(const std::string &name, const std::wstring &wname, +std::wstring Server::handleChat(const std::string &name, std::wstring wmessage, bool check_shout_priv, RemotePlayer *player) { // If something goes wrong, this player is to blame @@ -2999,7 +3002,7 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna auto message = trim(wide_to_utf8(wmessage)); if (message.find_first_of("\n\r") != std::wstring::npos) { - return L"New lines are not permitted in chat messages"; + return L"Newlines are not permitted in chat messages"; } // Run script hook, exit if script ate the chat message @@ -3020,10 +3023,10 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna the Cyrillic alphabet and some characters on older Android devices */ #ifdef __ANDROID__ - line += L"<" + wname + L"> " + wmessage; + line += L"<" + utf8_to_wide(name) + L"> " + wmessage; #else - line += narrow_to_wide(m_script->formatChatMessage(name, - wide_to_narrow(wmessage))); + line += utf8_to_wide(m_script->formatChatMessage(name, + wide_to_utf8(wmessage))); #endif } @@ -3036,35 +3039,23 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna /* Send the message to others */ - actionstream << "CHAT: " << wide_to_narrow(unescape_enriched(line)) << std::endl; - - std::vector<session_t> clients = m_clients.getClientIDs(); - - /* - Send the message back to the inital sender - if they are using protocol version >= 29 - */ + actionstream << "CHAT: " << wide_to_utf8(unescape_enriched(line)) << std::endl; - session_t peer_id_to_avoid_sending = - (player ? player->getPeerId() : PEER_ID_INEXISTENT); + ChatMessage chatmsg(line); - if (player && player->protocol_version >= 29) - peer_id_to_avoid_sending = PEER_ID_INEXISTENT; + std::vector<session_t> clients = m_clients.getClientIDs(); + for (u16 cid : clients) + SendChatMessage(cid, chatmsg); - for (u16 cid : clients) { - if (cid != peer_id_to_avoid_sending) - SendChatMessage(cid, ChatMessage(line)); - } return L""; } void Server::handleAdminChat(const ChatEventChat *evt) { std::string name = evt->nick; - std::wstring wname = utf8_to_wide(name); std::wstring wmessage = evt->evt_msg; - std::wstring answer = handleChat(name, wname, wmessage); + std::wstring answer = handleChat(name, wmessage); // If asked to send answer to sender if (!answer.empty()) { @@ -3101,46 +3092,43 @@ PlayerSAO *Server::getPlayerSAO(session_t peer_id) return player->getPlayerSAO(); } -std::wstring Server::getStatusString() +std::string Server::getStatusString() { - std::wostringstream os(std::ios_base::binary); - os << L"# Server: "; + std::ostringstream os(std::ios_base::binary); + os << "# Server: "; // Version - os << L"version=" << narrow_to_wide(g_version_string); + os << "version=" << g_version_string; // Uptime - os << L", uptime=" << m_uptime_counter->get(); + os << ", uptime=" << m_uptime_counter->get(); // Max lag estimate - os << L", max_lag=" << (m_env ? m_env->getMaxLagEstimate() : 0); + os << ", max_lag=" << (m_env ? m_env->getMaxLagEstimate() : 0); // Information about clients bool first = true; - os << L", clients={"; + os << ", clients={"; if (m_env) { std::vector<session_t> clients = m_clients.getClientIDs(); for (session_t client_id : clients) { RemotePlayer *player = m_env->getPlayer(client_id); // Get name of player - std::wstring name = L"unknown"; - if (player) - name = narrow_to_wide(player->getName()); + const char *name = player ? player->getName() : "<unknown>"; // Add name to information string if (!first) - os << L", "; + os << ", "; else first = false; - os << name; } } - os << L"}"; + os << "}"; if (m_env && !((ServerMap*)(&m_env->getMap()))->isSavingEnabled()) - os << std::endl << L"# Server: " << " WARNING: Map saving is disabled."; + os << std::endl << "# Server: " << " WARNING: Map saving is disabled."; if (!g_settings->get("motd").empty()) - os << std::endl << L"# Server: " << narrow_to_wide(g_settings->get("motd")); + os << std::endl << "# Server: " << g_settings->get("motd"); return os.str(); } @@ -3336,7 +3324,8 @@ void Server::hudSetHotbarSelectedImage(RemotePlayer *player, const std::string & Address Server::getPeerAddress(session_t peer_id) { - return m_con->GetPeerAddress(peer_id); + // Note that this is only set after Init was received in Server::handleCommand_Init + return getClient(peer_id, CS_Invalid)->getAddress(); } void Server::setLocalPlayerAnimations(RemotePlayer *player, @@ -3470,7 +3459,8 @@ void Server::deleteParticleSpawner(const std::string &playername, u32 id) SendDeleteParticleSpawner(peer_id, id); } -bool Server::dynamicAddMedia(const std::string &filepath) +bool Server::dynamicAddMedia(const std::string &filepath, + std::vector<RemotePlayer*> &sent_to) { std::string filename = fs::GetFilenameFromPath(filepath.c_str()); if (m_media.find(filename) != m_media.end()) { @@ -3490,9 +3480,17 @@ bool Server::dynamicAddMedia(const std::string &filepath) pkt << raw_hash << filename << (bool) true; pkt.putLongString(filedata); - auto client_ids = m_clients.getClientIDs(CS_DefinitionsSent); - for (session_t client_id : client_ids) { + m_clients.lock(); + for (auto &pair : m_clients.getClientList()) { + if (pair.second->getState() < CS_DefinitionsSent) + continue; + if (pair.second->net_proto_version < 39) + continue; + + if (auto player = m_env->getPlayer(pair.second->peer_id)) + sent_to.emplace_back(player); /* + FIXME: this is a very awful hack The network layer only guarantees ordered delivery inside a channel. Since the very next packet could be one that uses the media, we have to push the media over ALL channels to ensure it is processed before @@ -3501,9 +3499,10 @@ bool Server::dynamicAddMedia(const std::string &filepath) - channel 1 (HUD) - channel 0 (everything else: e.g. play_sound, object messages) */ - m_clients.send(client_id, 1, &pkt, true); - m_clients.send(client_id, 0, &pkt, true); + m_clients.send(pair.second->peer_id, 1, &pkt, true); + m_clients.send(pair.second->peer_id, 0, &pkt, true); } + m_clients.unlock(); return true; } |