X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fserver.cpp;h=0daa610541dbed1253d253b00f43a5c228f7ffa6;hb=e7246d3f0deed22f7d81e8988f656c594720d672;hp=d3d5fd3d18986f7031bcef3d0985e82805ebb5ed;hpb=7279f0b37335396c85f6bdd7dc67ff56e53df0f9;p=oweals%2Fminetest.git diff --git a/src/server.cpp b/src/server.cpp index d3d5fd3d1..0daa61054 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "profiler.h" #include "log.h" -#include "scripting_game.h" +#include "serverscripting.h" #include "nodedef.h" #include "itemdef.h" #include "craftdef.h" @@ -53,7 +53,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "event_manager.h" #include "serverlist.h" #include "util/string.h" -#include "util/mathconstants.h" #include "rollback.h" #include "util/serialize.h" #include "util/thread.h" @@ -149,11 +148,13 @@ Server::Server( const SubgameSpec &gamespec, bool simple_singleplayer_mode, bool ipv6, + bool dedicated, ChatInterface *iface ): m_path_world(path_world), m_gamespec(gamespec), m_simple_singleplayer_mode(simple_singleplayer_mode), + m_dedicated(dedicated), m_async_fatal_error(""), m_env(NULL), m_con(PROTOCOL_ID, @@ -179,8 +180,8 @@ Server::Server( m_admin_chat(iface), m_ignore_map_edit_events(false), m_ignore_map_edit_events_peer_id(0), - m_next_sound_id(0) - + m_next_sound_id(0), + m_mod_storage_save_timer(10.0f) { m_liquid_transform_timer = 0.0; m_liquid_transform_every = 1.0; @@ -219,20 +220,12 @@ Server::Server( std::string ban_path = m_path_world + DIR_DELIM "ipban.txt"; m_banmanager = new BanManager(ban_path); - ModConfiguration modconf(m_path_world); + ServerModConfiguration modconf(m_path_world); m_mods = modconf.getMods(); std::vector unsatisfied_mods = modconf.getUnsatisfiedMods(); // complain about mods with unsatisfied dependencies - if(!modconf.isConsistent()) { - for(std::vector::iterator it = unsatisfied_mods.begin(); - it != unsatisfied_mods.end(); ++it) { - ModSpec mod = *it; - errorstream << "mod \"" << mod.name << "\" has unsatisfied dependencies: "; - for(std::set::iterator dep_it = mod.unsatisfied_depends.begin(); - dep_it != mod.unsatisfied_depends.end(); ++dep_it) - errorstream << " \"" << *dep_it << "\""; - errorstream << std::endl; - } + if (!modconf.isConsistent()) { + modconf.printUnsatisfiedModsError(); } Settings worldmt_settings; @@ -270,22 +263,19 @@ Server::Server( // Initialize scripting infostream<<"Server: Initializing Lua"<loadMod(script_path, BUILTIN_MOD_NAME); + m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME); // Print mods infostream << "Server: Loading mods: "; - for(std::vector::iterator i = m_mods.begin(); + for (std::vector::const_iterator i = m_mods.begin(); i != m_mods.end(); ++i) { - const ModSpec &mod = *i; - infostream << mod.name << " "; + infostream << (*i).name << " "; } infostream << std::endl; // Load and run "mod" scripts - for (std::vector::iterator it = m_mods.begin(); + for (std::vector::const_iterator it = m_mods.begin(); it != m_mods.end(); ++it) { const ModSpec &mod = *it; if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) { @@ -641,10 +631,10 @@ void Server::AsyncRunStep(bool initial_step) // send masterserver announce { float &counter = m_masterserver_timer; - if(!isSingleplayer() && (!counter || counter >= 300.0) && - g_settings->getBool("server_announce")) - { - ServerList::sendAnnounce(counter ? "update" : "start", + if (!isSingleplayer() && (!counter || counter >= 300.0) && + g_settings->getBool("server_announce")) { + ServerList::sendAnnounce(counter ? ServerList::AA_UPDATE : + ServerList::AA_START, m_bind_addr.getPort(), m_clients.getPlayerNames(), m_uptime.get(), @@ -652,7 +642,8 @@ void Server::AsyncRunStep(bool initial_step) m_lag, m_gamespec.id, Mapgen::getMapgenName(m_emerge->mgparams->mgtype), - m_mods); + m_mods, + m_dedicated); counter = 0.01; } counter += dtime; @@ -789,6 +780,18 @@ void Server::AsyncRunStep(bool initial_step) << "packet size is " << pktSize << std::endl; } m_clients.unlock(); + + m_mod_storage_save_timer -= dtime; + if (m_mod_storage_save_timer <= 0.0f) { + infostream << "Saving registered mod storages." << std::endl; + m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval"); + for (UNORDERED_MAP::const_iterator + it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) { + if (it->second->isModified()) { + it->second->save(getModStoragePath()); + } + } + } } /* @@ -1119,7 +1122,7 @@ PlayerSAO* Server::StageTwoClientInit(u16 peer_id) SendDeathscreen(peer_id, false, v3f(0,0,0)); // Note things in chat if not in simple singleplayer mode - if(!m_simple_singleplayer_mode) { + if (!m_simple_singleplayer_mode && g_settings->getBool("show_statusline_on_connect")) { // Send information about server to player in chat SendChatMessage(peer_id, getStatusString()); } @@ -2144,14 +2147,6 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, if (client != 0) { pkt << p << n.param0 << n.param1 << n.param2 << (u8) (remove_metadata ? 0 : 1); - - if (!remove_metadata) { - if (client->net_proto_version <= 21) { - // Old clients always clear metadata; fix it - // by sending the full block again. - client->SetBlockNotSent(getNodeBlockPos(p)); - } - } } m_clients.unlock(); @@ -2185,7 +2180,7 @@ void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto std::ostringstream os(std::ios_base::binary); block->serialize(os, ver, false); - block->serializeNetworkSpecific(os, net_proto_version); + block->serializeNetworkSpecific(os); std::string s = os.str(); NetworkPacket pkt(TOCLIENT_BLOCKDATA, 2 + 2 + 2 + 2 + s.size(), peer_id); @@ -2791,40 +2786,41 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna RollbackScopeActor rollback_scope(m_rollback, std::string("player:") + name); - // Line to send - std::wstring line; - // Whether to send line to the player that sent the message, or to all players - bool broadcast_line = true; - - // Run script hook - bool ate = m_script->on_chat_message(name, - wide_to_utf8(wmessage)); - // If script ate the message, don't proceed - if (ate) - return L""; - if (player) { switch (player->canSendChatMessage()) { case RPLAYER_CHATRESULT_FLOODING: { std::wstringstream ws; ws << L"You cannot send more messages. You are limited to " - << g_settings->getFloat("chat_message_limit_per_10sec") - << L" messages per 10 seconds."; + << g_settings->getFloat("chat_message_limit_per_10sec") + << L" messages per 10 seconds."; return ws.str(); } case RPLAYER_CHATRESULT_KICK: - DenyAccess_Legacy(player->peer_id, L"You have been kicked due to message flooding."); + DenyAccess_Legacy(player->peer_id, + L"You have been kicked due to message flooding."); return L""; - case RPLAYER_CHATRESULT_OK: break; - default: FATAL_ERROR("Unhandled chat filtering result found."); + case RPLAYER_CHATRESULT_OK: + break; + default: + FATAL_ERROR("Unhandled chat filtering result found."); } } - if (m_max_chatmessage_length > 0 && wmessage.length() > m_max_chatmessage_length) { + if (m_max_chatmessage_length > 0 + && wmessage.length() > m_max_chatmessage_length) { return L"Your message exceed the maximum chat message limit set on the server. " - L"It was refused. Send a shorter message"; + L"It was refused. Send a shorter message"; } + // Run script hook, exit if script ate the chat message + if (m_script->on_chat_message(name, wide_to_utf8(wmessage))) + return L""; + + // Line to send + std::wstring line; + // Whether to send line to the player that sent the message, or to all players + bool broadcast_line = true; + // Commands are implemented in Lua, so only catch invalid // commands that were not "eaten" and send an error back if (wmessage[0] == L'/') { @@ -2865,7 +2861,7 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna */ u16 peer_id_to_avoid_sending = (player ? player->peer_id : PEER_ID_INEXISTENT); - if (player->protocol_version >= 29) + if (player && player->protocol_version >= 29) peer_id_to_avoid_sending = PEER_ID_INEXISTENT; for (u16 i = 0; i < clients.size(); i++) { @@ -3404,6 +3400,11 @@ std::string Server::getBuiltinLuaPath() return porting::path_share + DIR_DELIM + "builtin"; } +std::string Server::getModStoragePath() const +{ + return m_path_world + DIR_DELIM + "mod_storage"; +} + v3f Server::findSpawnPos() { ServerMap &map = m_env->getServerMap(); @@ -3525,6 +3526,28 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version return playersao; } +bool Server::registerModStorage(ModMetadata *storage) +{ + if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) { + errorstream << "Unable to register same mod storage twice. Storage name: " + << storage->getModName() << std::endl; + return false; + } + + m_mod_storages[storage->getModName()] = storage; + return true; +} + +void Server::unregisterModStorage(const std::string &name) +{ + UNORDERED_MAP::const_iterator it = m_mod_storages.find(name); + if (it != m_mod_storages.end()) { + // Save unconditionaly on unregistration + it->second->save(getModStoragePath()); + m_mod_storages.erase(name); + } +} + void dedicated_server_loop(Server &server, bool &kill) { DSTACK(FUNCTION_NAME); @@ -3546,15 +3569,8 @@ void dedicated_server_loop(Server &server, bool &kill) } server.step(steplen); - if(server.getShutdownRequested() || kill) - { - infostream<<"Dedicated server quitting"<getBool("server_announce")) - ServerList::sendAnnounce("delete", server.m_bind_addr.getPort()); -#endif + if (server.getShutdownRequested() || kill) break; - } /* Profiler @@ -3568,4 +3584,11 @@ void dedicated_server_loop(Server &server, bool &kill) } } } + + infostream << "Dedicated server quitting" << std::endl; +#if USE_CURL + if (g_settings->getBool("server_announce")) + ServerList::sendAnnounce(ServerList::AA_DELETE, + server.m_bind_addr.getPort()); +#endif }