Skip to content

Commit 82a2e02

Browse files
committedNov 9, 2019
Load client mods into memory before execution.
Preperation for server-sent CSM which will eventually need this.
1 parent 5ab546f commit 82a2e02

File tree

4 files changed

+46
-24
lines changed

4 files changed

+46
-24
lines changed
 

‎src/client/client.cpp

+24-11
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,30 @@ void Client::scanModSubfolder(const std::string &mod_name, const std::string &mo
200200
std::string full_path = mod_path + DIR_DELIM + mod_subpath;
201201
std::vector<fs::DirListNode> mod = fs::GetDirListing(full_path);
202202
for (const fs::DirListNode &j : mod) {
203-
std::string filename = j.name;
204203
if (j.dir) {
205-
scanModSubfolder(mod_name, mod_path, mod_subpath
206-
+ filename + DIR_DELIM);
204+
scanModSubfolder(mod_name, mod_path, mod_subpath + j.name + DIR_DELIM);
207205
continue;
208206
}
209-
std::replace( mod_subpath.begin(), mod_subpath.end(), DIR_DELIM_CHAR, '/');
210-
m_mod_files[mod_name + ":" + mod_subpath + filename] = full_path + filename;
207+
std::replace(mod_subpath.begin(), mod_subpath.end(), DIR_DELIM_CHAR, '/');
208+
209+
std::string real_path = full_path + j.name;
210+
std::string vfs_path = mod_name + ":" + mod_subpath + j.name;
211+
infostream << "Client::scanModSubfolder(): Loading \"" << real_path
212+
<< "\" as \"" << vfs_path << "\"." << std::endl;
213+
214+
std::ifstream is(real_path, std::ios::binary | std::ios::ate);
215+
if(!is.good()) {
216+
errorstream << "Client::scanModSubfolder(): Can't read file \""
217+
<< real_path << "\"." << std::endl;
218+
continue;
219+
}
220+
auto size = is.tellg();
221+
std::string contents(size, '\0');
222+
is.seekg(0);
223+
is.read(&contents[0], size);
224+
225+
infostream << " size: " << size << " bytes" << std::endl;
226+
m_mod_vfs.emplace(vfs_path, contents);
211227
}
212228
}
213229

@@ -1866,12 +1882,9 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename, bool cache)
18661882

18671883
const std::string* Client::getModFile(const std::string &filename)
18681884
{
1869-
StringMap::const_iterator it = m_mod_files.find(filename);
1870-
if (it == m_mod_files.end()) {
1871-
errorstream << "Client::getModFile(): File not found: \"" << filename
1872-
<< "\"" << std::endl;
1873-
return NULL;
1874-
}
1885+
StringMap::const_iterator it = m_mod_vfs.find(filename);
1886+
if (it == m_mod_vfs.end())
1887+
return nullptr;
18751888
return &it->second;
18761889
}
18771890

‎src/client/client.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,6 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
576576
// Storage for mesh data for creating multiple instances of the same mesh
577577
StringMap m_mesh_data;
578578

579-
StringMap m_mod_files;
580-
581579
// own state
582580
LocalClientState m_state;
583581

@@ -588,11 +586,13 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
588586
IntervalLimiter m_localdb_save_interval;
589587
u16 m_cache_save_interval;
590588

589+
// Client modding
591590
ClientScripting *m_script = nullptr;
592591
bool m_modding_enabled;
593592
std::unordered_map<std::string, ModMetadata *> m_mod_storages;
594593
float m_mod_storage_save_timer = 10.0f;
595594
std::vector<ModSpec> m_mods;
595+
StringMap m_mod_vfs;
596596

597597
bool m_shutdown = false;
598598

‎src/script/cpp_api/s_base.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -197,18 +197,22 @@ void ScriptApiBase::loadModFromMemory(const std::string &mod_name)
197197
{
198198
ModNameStorer mod_name_storer(getStack(), mod_name);
199199

200-
const std::string *init_filename = getClient()->getModFile(mod_name + ":init.lua");
201-
const std::string display_filename = mod_name + ":init.lua";
202-
if(init_filename == NULL)
203-
throw ModError("Mod:\"" + mod_name + "\" lacks init.lua");
200+
sanity_check(m_type == ScriptingType::Client);
204201

205-
verbosestream << "Loading and running script " << display_filename << std::endl;
202+
const std::string init_filename = mod_name + ":init.lua";
203+
const std::string chunk_name = "@" + init_filename;
204+
205+
const std::string *contents = getClient()->getModFile(init_filename);
206+
if (!contents)
207+
throw ModError("Mod \"" + mod_name + "\" lacks init.lua");
208+
209+
verbosestream << "Loading and running script " << chunk_name << std::endl;
206210

207211
lua_State *L = getStack();
208212

209213
int error_handler = PUSH_ERROR_HANDLER(L);
210214

211-
bool ok = ScriptApiSecurity::safeLoadFile(L, init_filename->c_str(), display_filename.c_str());
215+
bool ok = ScriptApiSecurity::safeLoadString(L, *contents, chunk_name.c_str());
212216
if (ok)
213217
ok = !lua_pcall(L, 0, 0, error_handler);
214218
if (!ok) {

‎src/script/cpp_api/s_security.cpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -627,23 +627,28 @@ int ScriptApiSecurity::sl_g_loadfile(lua_State *L)
627627
ScriptApiBase *script = (ScriptApiBase *) lua_touserdata(L, -1);
628628
lua_pop(L, 1);
629629

630+
// Client implementation
630631
if (script->getType() == ScriptingType::Client) {
631-
std::string display_path = readParam<std::string>(L, 1);
632-
const std::string *path = script->getClient()->getModFile(display_path);
633-
if (!path) {
634-
std::string error_msg = "Coudln't find script called:" + display_path;
632+
std::string path = readParam<std::string>(L, 1);
633+
const std::string *contents = script->getClient()->getModFile(path);
634+
if (!contents) {
635+
std::string error_msg = "Coudln't find script called: " + path;
635636
lua_pushnil(L);
636637
lua_pushstring(L, error_msg.c_str());
637638
return 2;
638639
}
639-
if (!safeLoadFile(L, path->c_str(), display_path.c_str())) {
640+
641+
std::string chunk_name = "@" + path;
642+
if (!safeLoadString(L, *contents, chunk_name.c_str())) {
640643
lua_pushnil(L);
641644
lua_insert(L, -2);
642645
return 2;
643646
}
644647
return 1;
645648
}
646649
#endif
650+
651+
// Server implementation
647652
const char *path = NULL;
648653
if (lua_isstring(L, 1)) {
649654
path = lua_tostring(L, 1);

0 commit comments

Comments
 (0)