diff --git a/builtin/client/death_formspec.lua b/builtin/client/death_formspec.lua new file mode 100644 index 000000000..e755ac5c1 --- /dev/null +++ b/builtin/client/death_formspec.lua @@ -0,0 +1,16 @@ +-- CSM death formspec. Only used when clientside modding is enabled, otherwise +-- handled by the engine. + +core.register_on_death(function() + core.display_chat_message("You died.") + local formspec = "size[11,5.5]bgcolor[#320000b4;true]" .. + "label[4.85,1.35;" .. fgettext("You died") .. + "]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]" + core.show_formspec("bultin:death", formspec) +end) + +core.register_on_formspec_input(function(formname, fields) + if formname == "bultin:death" then + core.send_respawn() + end +end) diff --git a/builtin/client/init.lua b/builtin/client/init.lua index 22256f6f7..9633a7c71 100644 --- a/builtin/client/init.lua +++ b/builtin/client/init.lua @@ -8,16 +8,4 @@ dofile(commonpath .. "after.lua") dofile(commonpath .. "chatcommands.lua") dofile(clientpath .. "chatcommands.lua") dofile(commonpath .. "vector.lua") - -core.register_on_death(function() - core.display_chat_message("You died.") - local formspec = "size[11,5.5]bgcolor[#320000b4;true]" .. - "label[4.85,1.35;" .. fgettext("You died.") .. "]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]" - core.show_formspec("bultin:death", formspec) -end) - -core.register_on_formspec_input(function(formname, fields) - if formname == "bultin:death" then - core.send_respawn() - end -end) +dofile(clientpath .. "death_formspec.lua") diff --git a/src/client.cpp b/src/client.cpp index 378efd5fe..17ee3a10a 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -110,36 +110,37 @@ Client::Client( m_cache_save_interval = g_settings->getU16("server_map_save_interval"); m_modding_enabled = g_settings->getBool("enable_client_modding"); - m_script = new ClientScripting(this); - m_env.setScript(m_script); - m_script->setEnv(&m_env); -} - -void Client::loadBuiltin() -{ - // Load builtin - scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); - - m_script->loadModFromMemory(BUILTIN_MOD_NAME); + // Only create the client script environment if client modding is enabled + if (m_modding_enabled) { + m_script = new ClientScripting(this); + m_env.setScript(m_script); + m_script->setEnv(&m_env); + } } void Client::loadMods() { - // Don't permit to load mods twice + // Don't load mods twice if (m_mods_loaded) { return; } - // If modding is not enabled or CSM restrictions disable it - // don't load CSM mods, only builtin + // If client modding is not enabled, don't load client-provided CSM mods or + // builtin. if (!m_modding_enabled) { warningstream << "Client side mods are disabled by configuration." << std::endl; return; } + // Load builtin + scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); + m_script->loadModFromMemory(BUILTIN_MOD_NAME); + + // If the server has disabled client-provided CSM mod loading, don't load + // client-provided CSM mods. Builtin is loaded so needs verfying. if (checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_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 builtin integrity is wrong, disconnect user if (!checkBuiltinIntegrity()) { // @TODO disconnect user } @@ -227,8 +228,8 @@ const ModSpec* Client::getModSpec(const std::string &modname) const void Client::Stop() { m_shutdown = true; - // Don't disable this part when modding is disabled, it's used in builtin - m_script->on_shutdown(); + if (m_modding_enabled) + m_script->on_shutdown(); //request all client managed threads to stop m_mesh_update_thread.stop(); // Save local server map @@ -237,7 +238,8 @@ void Client::Stop() m_localdb->endSave(); } - delete m_script; + if (m_modding_enabled) + delete m_script; } bool Client::isShutdown() @@ -1491,10 +1493,9 @@ void Client::typeChatMessage(const std::wstring &message) if (message.empty()) return; - // If message was ate by script API, don't send it to server - if (m_script->on_sending_message(wide_to_utf8(message))) { + // If message was consumed by script API, don't send it to server + if (m_modding_enabled && m_script->on_sending_message(wide_to_utf8(message))) return; - } // Send to others sendChatMessage(message); diff --git a/src/client.h b/src/client.h index 423db870a..68a832d8e 100644 --- a/src/client.h +++ b/src/client.h @@ -141,7 +141,6 @@ public: DISABLE_CLASS_COPY(Client); // Load local mods into memory - 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) @@ -400,6 +399,7 @@ public: ClientScripting *getScript() { return m_script; } const bool moddingEnabled() const { return m_modding_enabled; } + const bool modsLoaded() const { return m_mods_loaded; } void pushToEventQueue(ClientEvent *event); diff --git a/src/clientenvironment.cpp b/src/clientenvironment.cpp index a81d0dd8f..e2f24aaa3 100644 --- a/src/clientenvironment.cpp +++ b/src/clientenvironment.cpp @@ -233,14 +233,14 @@ void ClientEnvironment::step(float dtime) u8 damage = (u8)MYMIN(damage_f + 0.5, 255); if (damage != 0) { damageLocalPlayer(damage, true); - m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_FALLING_DAMAGE)); + m_client->getEventManager()->put( + new SimpleTriggerEvent(MtEvent::PLAYER_FALLING_DAMAGE)); } } } - if (m_client->moddingEnabled()) { + if (m_client->modsLoaded()) m_script->environment_step(dtime); - } // Update lighting on local player (used for wield item) u32 day_night_ratio = getDayNightRatio(); diff --git a/src/game.cpp b/src/game.cpp index 1cb9a1650..6cf6723e9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -177,8 +177,13 @@ struct LocalFormspecHandler : public TextDest } } - // Don't disable this part when modding is disabled, it's used in builtin - if (m_client && m_client->getScript()) + if (m_formname == "MT_DEATH_SCREEN") { + assert(m_client != 0); + m_client->sendRespawn(); + return; + } + + if (m_client && m_client->moddingEnabled()) m_client->getScript()->on_formspec_input(m_formname, fields); } @@ -775,6 +780,7 @@ private: bool disable_camera_update = false; }; + void showDeathFormspec(); void showPauseMenu(); // ClientEvent handlers @@ -1496,8 +1502,6 @@ bool Game::connectToServer(const std::string &playername, fps_control.last_time = RenderingEngine::get_timer_time(); - client->loadBuiltin(); - while (RenderingEngine::run()) { limitFps(&fps_control, &dtime); @@ -1882,7 +1886,10 @@ void Game::processKeyInput() } else if (wasKeyDown(KeyType::CMD)) { openConsole(0.2, L"/"); } else if (wasKeyDown(KeyType::CMD_LOCAL)) { - openConsole(0.2, L"."); + if (client->moddingEnabled()) + openConsole(0.2, L"."); + else + m_game_ui->showStatusText(wgettext("CSM is disabled")); } else if (wasKeyDown(KeyType::CONSOLE)) { openConsole(core::clamp(g_settings->getFloat("console_height"), 0.1f, 1.0f)); } else if (wasKeyDown(KeyType::FREEMOVE)) { @@ -2532,12 +2539,15 @@ void Game::handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientati void Game::handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam) { - // This should be enabled for death formspec in builtin - client->getScript()->on_death(); - - LocalPlayer *player = client->getEnv().getLocalPlayer(); + // If CSM enabled, deathscreen is handled by CSM code in + // builtin/client/init.lua + if (client->moddingEnabled()) + client->getScript()->on_death(); + else + showDeathFormspec(); /* Handle visualization */ + LocalPlayer *player = client->getEnv().getLocalPlayer(); runData.damage_flash = 0; player->hurt_tilt_timer = 0; player->hurt_tilt_strength = 0; @@ -4006,6 +4016,27 @@ void Game::extendedResourceCleanup() << " (note: irrlicht doesn't support removing renderers)" << std::endl; } +void Game::showDeathFormspec() +{ + static std::string formspec = + std::string(FORMSPEC_VERSION_STRING) + + SIZE_TAG + "bgcolor[#320000b4;true]" + "label[4.85,1.35;" + gettext("You died") + "]" + "button_exit[4,3;3,0.5;btn_respawn;" + gettext("Respawn") + "]" + ; + + /* Create menu */ + /* Note: FormspecFormSource and LocalFormspecHandler * + * are deleted by guiFormSpecMenu */ + FormspecFormSource *fs_src = new FormspecFormSource(formspec); + LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client); + + GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src, + txt_dst, client->getFormspecPrepend()); + current_formspec->setFocus("btn_respawn"); +} + #define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name()) void Game::showPauseMenu() { diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 5a62fec3d..1899b496e 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -384,12 +384,12 @@ void Client::handleCommand_ChatMessage(NetworkPacket *pkt) chatMessage->type = (ChatMessageType) message_type; // @TODO send this to CSM using ChatMessage object - if (!moddingEnabled() || !m_script->on_receiving_message( + if (moddingEnabled() && m_script->on_receiving_message( wide_to_utf8(chatMessage->message))) { - pushToChatQueue(chatMessage); - } else { - // Message was consumed by CSM and should not handled by client, destroying + // Message was consumed by CSM and should not be handled by client delete chatMessage; + } else { + pushToChatQueue(chatMessage); } }