From e34d28af9f4b779b7a137f0e4017e499266e1931 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Wed, 28 Apr 2021 10:22:13 +0200 Subject: [PATCH] refacto: rendering engine singleton removal step 1 (filesystem) Make the RenderingEngine filesystem member non accessible from everywhere This permits also to determine that some lua code has directly a logic to extract zip file. Move this logic inside client, it's not the lua stack role to perform a such complex operation Found also another irrlicht <1.8 compat code to remove --- src/client/client.cpp | 84 +++++++++++++++++++++++++++---- src/client/client.h | 6 +++ src/client/game.cpp | 2 +- src/client/renderingengine.h | 5 +- src/script/lua_api/l_mainmenu.cpp | 73 +-------------------------- 5 files changed, 84 insertions(+), 86 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index 5db0b8f5d..d7e69f349 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -97,6 +97,7 @@ Client::Client( NodeDefManager *nodedef, ISoundManager *sound, MtEventManager *event, + RenderingEngine *rendering_engine, bool ipv6, GameUI *game_ui ): @@ -106,6 +107,7 @@ Client::Client( m_nodedef(nodedef), m_sound(sound), m_event(event), + m_rendering_engine(rendering_engine), m_mesh_update_thread(this), m_env( new ClientMap(this, control, 666), @@ -660,8 +662,8 @@ bool Client::loadMedia(const std::string &data, const std::string &filename, TRACESTREAM(<< "Client: Attempting to load image " << "file \"" << filename << "\"" << std::endl); - io::IFileSystem *irrfs = RenderingEngine::get_filesystem(); - video::IVideoDriver *vdrv = RenderingEngine::get_video_driver(); + io::IFileSystem *irrfs = m_rendering_engine->get_filesystem(); + video::IVideoDriver *vdrv = m_rendering_engine->get_video_driver(); io::IReadFile *rfile = irrfs->createMemoryReadFile( data.c_str(), data.size(), "_tempreadfile"); @@ -728,6 +730,72 @@ bool Client::loadMedia(const std::string &data, const std::string &filename, return false; } +bool Client::extractZipFile(const char *filename, const std::string &destination) +{ + auto fs = m_rendering_engine->get_filesystem(); + + if (!fs->addFileArchive(filename, false, false, io::EFAT_ZIP)) { + return false; + } + + sanity_check(fs->getFileArchiveCount() > 0); + + /**********************************************************************/ + /* WARNING this is not threadsafe!! */ + /**********************************************************************/ + io::IFileArchive* opened_zip = fs->getFileArchive(fs->getFileArchiveCount() - 1); + + const io::IFileList* files_in_zip = opened_zip->getFileList(); + + unsigned int number_of_files = files_in_zip->getFileCount(); + + for (unsigned int i=0; i < number_of_files; i++) { + std::string fullpath = destination; + fullpath += DIR_DELIM; + fullpath += files_in_zip->getFullFileName(i).c_str(); + std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath); + + if (!files_in_zip->isDirectory(i)) { + if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) { + fs->removeFileArchive(fs->getFileArchiveCount()-1); + return false; + } + + io::IReadFile* toread = opened_zip->createAndOpenFile(i); + + FILE *targetfile = fopen(fullpath.c_str(),"wb"); + + if (targetfile == NULL) { + fs->removeFileArchive(fs->getFileArchiveCount()-1); + return false; + } + + char read_buffer[1024]; + long total_read = 0; + + while (total_read < toread->getSize()) { + + unsigned int bytes_read = + toread->read(read_buffer,sizeof(read_buffer)); + if ((bytes_read == 0 ) || + (fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read)) + { + fclose(targetfile); + fs->removeFileArchive(fs->getFileArchiveCount() - 1); + return false; + } + total_read += bytes_read; + } + + fclose(targetfile); + } + + } + + fs->removeFileArchive(fs->getFileArchiveCount() - 1); + return true; +} + // Virtual methods from con::PeerHandler void Client::peerAdded(con::Peer *peer) { @@ -1910,23 +1978,17 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename, bool cache) // Create the mesh, remove it from cache and return it // This allows unique vertex colors and other properties for each instance -#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8 - io::IReadFile *rfile = RenderingEngine::get_filesystem()->createMemoryReadFile( + io::IReadFile *rfile = m_rendering_engine->get_filesystem()->createMemoryReadFile( data.c_str(), data.size(), filename.c_str()); -#else - Buffer data_rw(data.c_str(), data.size()); // Const-incorrect Irrlicht - io::IReadFile *rfile = RenderingEngine::get_filesystem()->createMemoryReadFile( - *data_rw, data_rw.getSize(), filename.c_str()); -#endif FATAL_ERROR_IF(!rfile, "Could not create/open RAM file"); - scene::IAnimatedMesh *mesh = RenderingEngine::get_scene_manager()->getMesh(rfile); + scene::IAnimatedMesh *mesh = m_rendering_engine->get_scene_manager()->getMesh(rfile); rfile->drop(); if (!mesh) return nullptr; mesh->grab(); if (!cache) - RenderingEngine::get_mesh_cache()->removeMesh(mesh); + m_rendering_engine->get_mesh_cache()->removeMesh(mesh); return mesh; } diff --git a/src/client/client.h b/src/client/client.h index 2dba1506e..bcb7d6b09 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -45,6 +45,7 @@ struct ClientEvent; struct MeshMakeData; struct ChatMessage; class MapBlockMesh; +class RenderingEngine; class IWritableTextureSource; class IWritableShaderSource; class IWritableItemDefManager; @@ -123,6 +124,7 @@ public: NodeDefManager *nodedef, ISoundManager *sound, MtEventManager *event, + RenderingEngine *rendering_engine, bool ipv6, GameUI *game_ui ); @@ -379,6 +381,9 @@ public: // Insert a media file appropriately into the appropriate manager bool loadMedia(const std::string &data, const std::string &filename, bool from_media_push = false); + + bool extractZipFile(const char *filename, const std::string &destination); + // Send a request for conventional media transfer void request_media(const std::vector &file_requests); @@ -469,6 +474,7 @@ private: NodeDefManager *m_nodedef; ISoundManager *m_sound; MtEventManager *m_event; + RenderingEngine *m_rendering_engine; MeshUpdateThread m_mesh_update_thread; diff --git a/src/client/game.cpp b/src/client/game.cpp index b092b95e2..612072136 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1465,7 +1465,7 @@ bool Game::connectToServer(const GameStartData &start_data, start_data.password, start_data.address, *draw_control, texture_src, shader_src, itemdef_manager, nodedef_manager, sound, eventmgr, - connect_address.isIPv6(), m_game_ui.get()); + RenderingEngine::get_instance(), connect_address.isIPv6(), m_game_ui.get()); client->m_simple_singleplayer_mode = simple_singleplayer_mode; diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h index 34cc60630..5807421ef 100644 --- a/src/client/renderingengine.h +++ b/src/client/renderingengine.h @@ -59,10 +59,9 @@ public: static RenderingEngine *get_instance() { return s_singleton; } - static io::IFileSystem *get_filesystem() + io::IFileSystem *get_filesystem() { - sanity_check(s_singleton && s_singleton->m_device); - return s_singleton->m_device->getFileSystem(); + return m_device->getFileSystem(); } static video::IVideoDriver *get_video_driver() diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 6488cd0fc..1e8dea909 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -34,9 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverlist.h" #include "mapgen/mapgen.h" #include "settings.h" - -#include -#include +#include "client/client.h" #include "client/renderingengine.h" #include "network/networkprotocol.h" @@ -630,74 +628,7 @@ int ModApiMainMenu::l_extract_zip(lua_State *L) if (ModApiMainMenu::mayModifyPath(absolute_destination)) { fs::CreateAllDirs(absolute_destination); - - io::IFileSystem *fs = RenderingEngine::get_filesystem(); - - if (!fs->addFileArchive(zipfile, false, false, io::EFAT_ZIP)) { - lua_pushboolean(L,false); - return 1; - } - - sanity_check(fs->getFileArchiveCount() > 0); - - /**********************************************************************/ - /* WARNING this is not threadsafe!! */ - /**********************************************************************/ - io::IFileArchive* opened_zip = - fs->getFileArchive(fs->getFileArchiveCount()-1); - - const io::IFileList* files_in_zip = opened_zip->getFileList(); - - unsigned int number_of_files = files_in_zip->getFileCount(); - - for (unsigned int i=0; i < number_of_files; i++) { - std::string fullpath = destination; - fullpath += DIR_DELIM; - fullpath += files_in_zip->getFullFileName(i).c_str(); - std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath); - - if (!files_in_zip->isDirectory(i)) { - if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) { - fs->removeFileArchive(fs->getFileArchiveCount()-1); - lua_pushboolean(L,false); - return 1; - } - - io::IReadFile* toread = opened_zip->createAndOpenFile(i); - - FILE *targetfile = fopen(fullpath.c_str(),"wb"); - - if (targetfile == NULL) { - fs->removeFileArchive(fs->getFileArchiveCount()-1); - lua_pushboolean(L,false); - return 1; - } - - char read_buffer[1024]; - long total_read = 0; - - while (total_read < toread->getSize()) { - - unsigned int bytes_read = - toread->read(read_buffer,sizeof(read_buffer)); - if ((bytes_read == 0 ) || - (fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read)) - { - fclose(targetfile); - fs->removeFileArchive(fs->getFileArchiveCount()-1); - lua_pushboolean(L,false); - return 1; - } - total_read += bytes_read; - } - - fclose(targetfile); - } - - } - - fs->removeFileArchive(fs->getFileArchiveCount()-1); - lua_pushboolean(L,true); + lua_pushboolean(L, getClient(L)->extractZipFile(zipfile, destination)); return 1; }