From 308bb69eefdfb2ff3b893c124ccf0321d99a1bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Blot?= Date: Mon, 11 Dec 2017 17:33:44 +0100 Subject: [PATCH] CSM fixes: load mods after flavours & add flavour to block mod loading (#6738) * CSM fixes: load mods after flavours & add flavour to block mod loading * Don't permit to load mods twice * Prepare builtin integrity global algorithm * Add missing doc & use a nicer byteflag for LOAD_CLIENT_MODS flavour * flag typo fix * Invert CSM_FL_LOOKUP_NODES & CSM_FL_LOAD_CLIENT_MODS ids --- builtin/settingtypes.txt | 5 +-- minetest.conf.example | 6 ++-- src/client.cpp | 54 +++++++++++++++++++---------- src/client.h | 8 ++--- src/defaultsettings.cpp | 2 +- src/game.cpp | 5 ++- src/network/clientpackethandler.cpp | 4 +++ src/network/networkprotocol.h | 3 +- 8 files changed, 55 insertions(+), 32 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index fc628c88f..695c0b1d6 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -1121,12 +1121,13 @@ server_side_occlusion_culling (Server side occlusion culling) bool true # Restricts the access of certain client-side functions on servers # Combine these byteflags below to restrict more client-side features: -# LOOKUP_NODES_LIMIT: 1 (limits get_node call client-side to csm_flavour_noderange_limit) +# LOAD_CLIENT_MODS: 1 (disable client mods loading) # CHAT_MESSAGES: 2 (disable send_chat_message call client-side) # READ_ITEMDEFS: 4 (disable get_item_def call client-side) # READ_NODEDEFS: 8 (disable get_node_def call client-side) +# LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to csm_flavour_noderange_limit) # type: int -csm_flavour_limits (Client side modding flavour limits) int 3 +csm_flavour_limits (Client side modding flavour limits) int 18 # If the CSM flavour for node range is enabled, get_node is limited to # this many nodes from the player. diff --git a/minetest.conf.example b/minetest.conf.example index 9ca6efb05..357d677f4 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -1346,13 +1346,13 @@ # Restricts the access of certain client-side functions on servers # Combine these byteflags below to restrict more client-side features: -# LOOKUP_NODES_LIMIT: 1 (limits get_node call client-side to csm_flavour_noderange_limit) +# LOAD_CLIENT_MODS: 1 (disable client mods loading) # CHAT_MESSAGES: 2 (disable send_chat_message call client-side) # READ_ITEMDEFS: 4 (disable get_item_def call client-side) # READ_NODEDEFS: 8 (disable get_node_def call client-side) # type: int -# type: int -# csm_flavour_limits = 3 +# LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to csm_flavour_noderange_limit) +# csm_flavour_limits = 18 # If the CSM flavour for node range is enabled, get_node is limited to # this many nodes from the player. diff --git a/src/client.cpp b/src/client.cpp index c04bf055a..6e29607ca 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -113,18 +113,38 @@ Client::Client( m_script->setEnv(&m_env); } -void Client::loadMods() +void Client::loadBuiltin() { // Load builtin scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); - // If modding is not enabled, don't load mods, just builtin - if (!m_modding_enabled) { + m_script->loadModFromMemory(BUILTIN_MOD_NAME); +} + +void Client::loadMods() +{ + // Don't permit to load mods twice + if (m_mods_loaded) { return; } + + // If modding is not enabled or flavour disable it, don't load mods, just builtin + if (!m_modding_enabled) { + warningstream << "Client side mods are disabled by configuration." << std::endl; + return; + } + + if (checkCSMFlavourLimit(CSMFlavourLimit::CSM_FL_LOAD_CLIENT_MODS)) { + warningstream << "Client side mods are disabled by server." << std::endl; + // If mods loading is disabled and builtin integrity is wrong, disconnect user. + if (!checkBuiltinIntegrity()) { + // @TODO disconnect user + } + return; + } + ClientModConfiguration modconf(getClientModsLuaPath()); m_mods = modconf.getMods(); - std::vector unsatisfied_mods = modconf.getUnsatisfiedMods(); // complain about mods with unsatisfied dependencies if (!modconf.isConsistent()) { modconf.printUnsatisfiedModsError(); @@ -145,6 +165,18 @@ void Client::loadMods() } scanModIntoMemory(mod.name, mod.path); } + + // Load and run "mod" scripts + for (const ModSpec &mod : m_mods) + m_script->loadModFromMemory(mod.name); + + m_mods_loaded = true; +} + +bool Client::checkBuiltinIntegrity() +{ + // @TODO + return true; } void Client::scanModSubfolder(const std::string &mod_name, const std::string &mod_path, @@ -164,20 +196,6 @@ void Client::scanModSubfolder(const std::string &mod_name, const std::string &mo } } -void Client::initMods() -{ - m_script->loadModFromMemory(BUILTIN_MOD_NAME); - - // If modding is not enabled, don't load mods, just builtin - if (!m_modding_enabled) { - return; - } - - // Load and run "mod" scripts - for (const ModSpec &mod : m_mods) - m_script->loadModFromMemory(mod.name); -} - const std::string &Client::getBuiltinLuaPath() { static const std::string builtin_dir = porting::path_share + DIR_DELIM + "builtin"; diff --git a/src/client.h b/src/client.h index 06c67105f..6093d6a6f 100644 --- a/src/client.h +++ b/src/client.h @@ -140,7 +140,7 @@ public: DISABLE_CLASS_COPY(Client); // Load local mods into memory - void loadMods(); + void loadBuiltin(); void scanModSubfolder(const std::string &mod_name, const std::string &mod_path, std::string mod_subpath); inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path) @@ -148,9 +148,6 @@ public: scanModSubfolder(mod_name, mod_path, ""); } - // Initizle the mods - void initMods(); - /* request all threads managed by client to be stopped */ @@ -433,6 +430,8 @@ public: ModChannel *getModChannel(const std::string &channel); private: + void loadMods(); + bool checkBuiltinIntegrity(); // Virtual methods from con::PeerHandler void peerAdded(con::Peer *peer); @@ -536,6 +535,7 @@ private: std::queue m_client_event_queue; bool m_itemdef_received = false; bool m_nodedef_received = false; + bool m_mods_loaded = false; ClientMediaDownloader *m_media_downloader; // time_of_day speed approximation for old protocol diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index cc113c6f6..d4dbb5481 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -329,7 +329,7 @@ void set_default_settings(Settings *settings) settings->setDefault("max_block_send_distance", "9"); settings->setDefault("block_send_optimize_distance", "4"); settings->setDefault("server_side_occlusion_culling", "true"); - settings->setDefault("csm_flavour_limits", "3"); + settings->setDefault("csm_flavour_limits", "18"); settings->setDefault("csm_flavour_noderange_limit", "8"); settings->setDefault("max_clearobjects_extra_loaded_blocks", "4096"); settings->setDefault("time_speed", "72"); diff --git a/src/game.cpp b/src/game.cpp index fca9c5e68..ee2b19933 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2049,7 +2049,7 @@ bool Game::initGui() // Make sure the size of the recent messages buffer is right chat_backend->applySettings(); - + // Chat backend and console gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(), -1, chat_backend, client, &g_menumgr); @@ -2146,8 +2146,7 @@ bool Game::connectToServer(const std::string &playername, fps_control.last_time = RenderingEngine::get_timer_time(); - client->loadMods(); - client->initMods(); + client->loadBuiltin(); while (RenderingEngine::run()) { diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 5de99418e..0ec46049e 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1326,6 +1326,10 @@ void Client::handleCommand_SrpBytesSandB(NetworkPacket* pkt) void Client::handleCommand_CSMFlavourLimits(NetworkPacket *pkt) { *pkt >> m_csm_flavour_limits >> m_csm_noderange_limit; + + // Now we have flavours, load mods if it's enabled + // Note: this should be moved after mods receptions from server instead + loadMods(); } /* diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index fe68f39b2..1f10822e1 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -921,10 +921,11 @@ enum PlayerListModifer: u8 enum CSMFlavourLimit : u64 { CSM_FL_NONE = 0x00000000, - CSM_FL_LOOKUP_NODES = 0x00000001, // Limit node lookups + CSM_FL_LOAD_CLIENT_MODS = 0x00000001, // Disable mods provided by clients CSM_FL_CHAT_MESSAGES = 0x00000002, // Disable chat message sending from CSM CSM_FL_READ_ITEMDEFS = 0x00000004, // Disable itemdef lookups CSM_FL_READ_NODEDEFS = 0x00000008, // Disable nodedef lookups + CSM_FL_LOOKUP_NODES = 0x00000010, // Limit node lookups CSM_FL_ALL = 0xFFFFFFFF, };