diff --git a/share/builtin/client_lua/client_lua.cpp b/share/builtin/client_lua/client_lua.cpp index fb5097d..4f07786 100644 --- a/share/builtin/client_lua/client_lua.cpp +++ b/share/builtin/client_lua/client_lua.cpp @@ -79,8 +79,9 @@ struct Module: public interface::Module std::string file_content((std::istreambuf_iterator(f)), std::istreambuf_iterator()); + const ss_ &public_file_name = module_name+"/"+n.name; client_file::access(m_server, [&](client_file::Interface * i){ - i->add_file_content(file_name, file_content); + i->add_file_content(public_file_name, file_content); }); } } diff --git a/share/client/init.lua b/share/client/init.lua index 34f0d26..e380a29 100644 --- a/share/client/init.lua +++ b/share/client/init.lua @@ -36,3 +36,17 @@ function buildat:send_packet(name, data) __buildat_send_packet(name, data) end +function buildat:run_script_file(name) + local content = __buildat_get_file_content(name) + if not content then + return false + end + log:info("buildat:run_script_file("..name.."): #content="..#content) + local script, err = loadstring(content) + if not script then + log:error("Failed to load script: "+err) + return false + end + script() +end + diff --git a/src/client/app.cpp b/src/client/app.cpp index 17ca2b0..1d2d8cf 100644 --- a/src/client/app.cpp +++ b/src/client/app.cpp @@ -340,9 +340,13 @@ struct CApp: public Polycode::EventHandler, public App CApp *self = (CApp*)lua_touserdata(L, -1); lua_pop(L, 1); - self->m_state->send_packet(name, data); - - return 0; + try{ + self->m_state->send_packet(name, data); + return 0; + } catch(std::exception &e){ + log_w(MODULE, "Exception in send_packet: %s", e.what()); + return 0; + } } // get_file_content(name: string) @@ -356,9 +360,14 @@ struct CApp: public Polycode::EventHandler, public App CApp *self = (CApp*)lua_touserdata(L, -1); lua_pop(L, 1); - ss_ content = self->m_state->get_file_content(name); - lua_pushlstring(L, content.c_str(), content.size()); - return 1; + try{ + ss_ content = self->m_state->get_file_content(name); + lua_pushlstring(L, content.c_str(), content.size()); + return 1; + } catch(std::exception &e){ + log_w(MODULE, "Exception in get_file_content: %s", e.what()); + return 0; + } } }; diff --git a/src/client/state.cpp b/src/client/state.cpp index 5b55efb..e9d442e 100644 --- a/src/client/state.cpp +++ b/src/client/state.cpp @@ -25,6 +25,7 @@ struct CState: public State interface::PacketStream m_packet_stream; sp_ m_app; ss_ m_cache_path; + sm_ m_file_hashes; // name -> hash CState(sp_ app): m_socket(interface::createTCPSocket()), @@ -65,8 +66,26 @@ struct CState: public State ss_ get_file_content(const ss_ &name) { - // TODO - return "Rullatortilla"; + auto it = m_file_hashes.find(name); + if(it == m_file_hashes.end()) + throw Exception(ss_()+"hash of file not found: \""+name+"\""); + const ss_ &file_hash = it->second; + ss_ file_hash_hex = interface::sha1::hex(file_hash); + ss_ path = m_cache_path+"/"+file_hash_hex; + std::ifstream f(path); + if(!f.good()) + throw Exception(ss_()+"Could not open file: "+path); + std::string file_content((std::istreambuf_iterator(f)), + std::istreambuf_iterator()); + ss_ file_hash2 = interface::sha1::calculate(file_content); + if(file_hash != file_hash2){ + log_e(MODULE, "Opened file differs in hash: \"%s\": " + "requested %s, actual %s", cs(name), + cs(interface::sha1::hex(file_hash)), + cs(interface::sha1::hex(file_hash2))); + throw Exception(ss_()+"Invalid file content: "+path); + } + return file_content; } void read_socket() @@ -113,6 +132,7 @@ struct CState: public State ar(file_name); ar(file_hash); } + m_file_hashes[file_name] = file_hash; ss_ file_hash_hex = interface::sha1::hex(file_hash); // Check if we already have this file ss_ path = m_cache_path+"/"+file_hash_hex; diff --git a/test/testmodules/test1/test1.cpp b/test/testmodules/test1/test1.cpp index 45a6921..fb118bc 100644 --- a/test/testmodules/test1/test1.cpp +++ b/test/testmodules/test1/test1.cpp @@ -82,7 +82,7 @@ struct Module: public interface::Module log_v(MODULE, "on_files_sent(): recipient=%zu", event.recipient); network::access(m_server, [&](network::Interface * inetwork){ inetwork->send(event.recipient, "core:run_script", - "__buildat_run_script_file(\"test1/init.lua\")"); + "buildat:run_script_file(\"test1/init.lua\")"); }); }