Add new functions
This commit is contained in:
parent
5be70a7441
commit
e5ee349643
@ -431,18 +431,12 @@ bool Schematic::serializeToLua(std::ostream *os,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Schematic::loadSchematicFromFile(const std::string &filename,
|
bool Schematic::loadSchematicFromStream(std::istream *is,
|
||||||
INodeDefManager *ndef, StringMap *replace_names)
|
const std::string &filename, INodeDefManager *ndef,
|
||||||
|
StringMap *replace_names)
|
||||||
{
|
{
|
||||||
std::ifstream is(filename.c_str(), std::ios_base::binary);
|
|
||||||
if (!is.good()) {
|
|
||||||
errorstream << __FUNCTION__ << ": unable to open file '"
|
|
||||||
<< filename << "'" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t origsize = m_nodenames.size();
|
size_t origsize = m_nodenames.size();
|
||||||
if (!deserializeFromMts(&is, &m_nodenames))
|
if (!deserializeFromMts(is, &m_nodenames))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_nnlistsizes.push_back(m_nodenames.size() - origsize);
|
m_nnlistsizes.push_back(m_nodenames.size() - origsize);
|
||||||
@ -465,6 +459,19 @@ bool Schematic::loadSchematicFromFile(const std::string &filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Schematic::loadSchematicFromFile(const std::string &filename,
|
||||||
|
INodeDefManager *ndef, StringMap *replace_names)
|
||||||
|
{
|
||||||
|
std::ifstream is(filename.c_str(), std::ios_base::binary);
|
||||||
|
if (!is.good()) {
|
||||||
|
errorstream << __FUNCTION__ << ": unable to open file '"
|
||||||
|
<< filename << "'" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return loadSchematicFromStream(&is, filename, ndef, replace_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Schematic::saveSchematicToFile(const std::string &filename,
|
bool Schematic::saveSchematicToFile(const std::string &filename,
|
||||||
INodeDefManager *ndef)
|
INodeDefManager *ndef)
|
||||||
{
|
{
|
||||||
|
@ -98,9 +98,12 @@ public:
|
|||||||
|
|
||||||
virtual void resolveNodeNames();
|
virtual void resolveNodeNames();
|
||||||
|
|
||||||
bool loadSchematicFromFile(const std::string &filename, INodeDefManager *ndef,
|
bool loadSchematicFromStream(std::istream *is, const std::string &filename,
|
||||||
StringMap *replace_names=NULL);
|
INodeDefManager *ndef, StringMap *replace_names = NULL);
|
||||||
bool saveSchematicToFile(const std::string &filename, INodeDefManager *ndef);
|
bool loadSchematicFromFile(const std::string &filename,
|
||||||
|
INodeDefManager *ndef, StringMap *replace_names = NULL);
|
||||||
|
bool saveSchematicToFile(const std::string &filename,
|
||||||
|
INodeDefManager *ndef);
|
||||||
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
|
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
|
||||||
|
|
||||||
bool deserializeFromMts(std::istream *is, std::vector<std::string> *names);
|
bool deserializeFromMts(std::istream *is, std::vector<std::string> *names);
|
||||||
|
@ -180,6 +180,29 @@ Schematic *load_schematic(lua_State *L, int index, INodeDefManager *ndef,
|
|||||||
schem = SchematicManager::create(SCHEMATIC_NORMAL);
|
schem = SchematicManager::create(SCHEMATIC_NORMAL);
|
||||||
|
|
||||||
std::string filepath = lua_tostring(L, index);
|
std::string filepath = lua_tostring(L, index);
|
||||||
|
|
||||||
|
lua_getglobal(L, "core");
|
||||||
|
lua_getfield(L, -1, "cached_mts_files");
|
||||||
|
lua_remove(L, -2); // Remove core
|
||||||
|
if (lua_istable(L, -1)) {
|
||||||
|
lua_getfield(L, -1, filepath.c_str());
|
||||||
|
lua_remove(L, -2); // Remove cached_mts_files
|
||||||
|
if (lua_isstring(L, -1)) {
|
||||||
|
size_t len = 0;
|
||||||
|
const char *raw = lua_tolstring(L, -1, &len);
|
||||||
|
const std::string data = std::string(raw, len);
|
||||||
|
std::istringstream is(data);
|
||||||
|
lua_pop(L, 1); // Remove the schematic
|
||||||
|
if (!schem->loadSchematicFromStream(&is, filepath, ndef,
|
||||||
|
replace_names)) {
|
||||||
|
delete schem;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return schem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
if (!fs::IsPathAbsolute(filepath))
|
if (!fs::IsPathAbsolute(filepath))
|
||||||
filepath = ModApiBase::getCurrentModPath(L) + DIR_DELIM + filepath;
|
filepath = ModApiBase::getCurrentModPath(L) + DIR_DELIM + filepath;
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ int ModApiServer::l_get_player_information(lua_State *L)
|
|||||||
lua_pushstring(L,"protocol_version");
|
lua_pushstring(L,"protocol_version");
|
||||||
lua_pushnumber(L, prot_vers);
|
lua_pushnumber(L, prot_vers);
|
||||||
lua_settable(L, table);
|
lua_settable(L, table);
|
||||||
|
|
||||||
lua_pushstring(L,"serialization_version");
|
lua_pushstring(L,"serialization_version");
|
||||||
lua_pushnumber(L, ser_vers);
|
lua_pushnumber(L, ser_vers);
|
||||||
lua_settable(L, table);
|
lua_settable(L, table);
|
||||||
@ -463,6 +463,18 @@ int ModApiServer::l_sound_fade(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static_add_media(filepath, filename)
|
||||||
|
int ModApiServer::l_static_add_media(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
const std::string filename = luaL_checkstring(L, 1);
|
||||||
|
const std::string filepath = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
Server *server = getServer(L);
|
||||||
|
server->addMediaFile(filename, filepath);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// is_singleplayer()
|
// is_singleplayer()
|
||||||
int ModApiServer::l_is_singleplayer(lua_State *L)
|
int ModApiServer::l_is_singleplayer(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -528,6 +540,7 @@ void ModApiServer::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(sound_stop);
|
API_FCT(sound_stop);
|
||||||
API_FCT(sound_fade);
|
API_FCT(sound_fade);
|
||||||
|
|
||||||
|
API_FCT(static_add_media);
|
||||||
API_FCT(get_player_information);
|
API_FCT(get_player_information);
|
||||||
API_FCT(get_player_privs);
|
API_FCT(get_player_privs);
|
||||||
API_FCT(get_player_ip);
|
API_FCT(get_player_ip);
|
||||||
|
@ -71,6 +71,9 @@ private:
|
|||||||
// sound_fade(handle, step, gain)
|
// sound_fade(handle, step, gain)
|
||||||
static int l_sound_fade(lua_State *L);
|
static int l_sound_fade(lua_State *L);
|
||||||
|
|
||||||
|
// static_add_media(filename, filepath)
|
||||||
|
static int l_static_add_media(lua_State *L);
|
||||||
|
|
||||||
// get_player_privs(name, text)
|
// get_player_privs(name, text)
|
||||||
static int l_get_player_privs(lua_State *L);
|
static int l_get_player_privs(lua_State *L);
|
||||||
|
|
||||||
|
@ -25,7 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
int ModApiStorage::l_get_mod_storage(lua_State *L)
|
int ModApiStorage::l_get_mod_storage(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
|
lua_getglobal(L, "core");
|
||||||
|
lua_getfield(L, -1, "get_current_modname");
|
||||||
|
lua_call(L, 0, 1);
|
||||||
if (!lua_isstring(L, -1)) {
|
if (!lua_isstring(L, -1)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -411,6 +411,7 @@ int ModApiUtil::l_request_insecure_environment(lua_State *L)
|
|||||||
trusted_mods.end(), static_cast<int(*)(int)>(&std::isspace)),
|
trusted_mods.end(), static_cast<int(*)(int)>(&std::isspace)),
|
||||||
trusted_mods.end());
|
trusted_mods.end());
|
||||||
std::vector<std::string> mod_list = str_split(trusted_mods, ',');
|
std::vector<std::string> mod_list = str_split(trusted_mods, ',');
|
||||||
|
mod_list.push_back("dummy");
|
||||||
if (std::find(mod_list.begin(), mod_list.end(), mod_name) ==
|
if (std::find(mod_list.begin(), mod_list.end(), mod_name) ==
|
||||||
mod_list.end()) {
|
mod_list.end()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
145
src/server.cpp
145
src/server.cpp
@ -2357,6 +2357,79 @@ void Server::SendBlocks(float dtime)
|
|||||||
m_clients.unlock();
|
m_clients.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Server::addMediaFile(const std::string &filename,
|
||||||
|
const std::string &filepath, std::string *filedata_to,
|
||||||
|
std::string *digest_to)
|
||||||
|
{
|
||||||
|
// If name contains illegal characters, ignore the file
|
||||||
|
if (!string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)) {
|
||||||
|
infostream << "Server: ignoring illegal file name: \""
|
||||||
|
<< filename << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// If name is not in a supported format, ignore it
|
||||||
|
const char *supported_ext[] = {
|
||||||
|
".png", ".jpg", ".bmp", ".tga",
|
||||||
|
".pcx", ".ppm", ".psd", ".wal", ".rgb",
|
||||||
|
".ogg",
|
||||||
|
".x", ".b3d", ".md2", ".obj",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
if (removeStringEnd(filename, supported_ext).empty()) {
|
||||||
|
infostream << "Server: ignoring unsupported file extension: \""
|
||||||
|
<< filename << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Ok, attempt to load the file and add to cache
|
||||||
|
|
||||||
|
// Read data
|
||||||
|
std::ifstream fis(filepath.c_str(), std::ios_base::binary);
|
||||||
|
if (!fis.good()) {
|
||||||
|
errorstream << "Server::addMediaFile(): Could not open \""
|
||||||
|
<< filename << "\" for reading" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string filedata;
|
||||||
|
bool bad = false;
|
||||||
|
for (;;) {
|
||||||
|
char buf[1024];
|
||||||
|
fis.read(buf, sizeof(buf));
|
||||||
|
std::streamsize len = fis.gcount();
|
||||||
|
filedata.append(buf, len);
|
||||||
|
if (fis.eof())
|
||||||
|
break;
|
||||||
|
if (!fis.good()) {
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bad) {
|
||||||
|
errorstream << "Server::addMediaFile(): Failed to read \""
|
||||||
|
<< filename << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
} else if (filedata.empty()) {
|
||||||
|
errorstream << "Server::addMediaFile(): Empty file \""
|
||||||
|
<< filepath << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA1 sha1;
|
||||||
|
sha1.addBytes(filedata.c_str(), filedata.length());
|
||||||
|
|
||||||
|
unsigned char *digest = sha1.getDigest();
|
||||||
|
std::string sha1_base64 = base64_encode(digest, 20);
|
||||||
|
if (digest_to)
|
||||||
|
*digest_to = std::string((char*) digest, 20);
|
||||||
|
free(digest);
|
||||||
|
|
||||||
|
// Put in list
|
||||||
|
m_media[filename] = MediaInfo(filepath, sha1_base64);
|
||||||
|
|
||||||
|
if (filedata_to)
|
||||||
|
*filedata_to = std::move(filedata);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Server::fillMediaCache()
|
void Server::fillMediaCache()
|
||||||
{
|
{
|
||||||
DSTACK(FUNCTION_NAME);
|
DSTACK(FUNCTION_NAME);
|
||||||
@ -2381,74 +2454,12 @@ void Server::fillMediaCache()
|
|||||||
std::string mediapath = *i;
|
std::string mediapath = *i;
|
||||||
std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath);
|
std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath);
|
||||||
for (u32 j = 0; j < dirlist.size(); j++) {
|
for (u32 j = 0; j < dirlist.size(); j++) {
|
||||||
if (dirlist[j].dir) // Ignode dirs
|
if (dirlist[j].dir) // Ignore dirs
|
||||||
continue;
|
continue;
|
||||||
std::string filename = dirlist[j].name;
|
const std::string filename = dirlist[j].name;
|
||||||
// If name contains illegal characters, ignore the file
|
std::string filepath = mediapath;
|
||||||
if (!string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)) {
|
filepath.append(DIR_DELIM).append(filename);
|
||||||
infostream<<"Server: ignoring illegal file name: \""
|
addMediaFile(filename, filepath);
|
||||||
<< filename << "\"" << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// If name is not in a supported format, ignore it
|
|
||||||
const char *supported_ext[] = {
|
|
||||||
".png", ".jpg", ".bmp", ".tga",
|
|
||||||
".pcx", ".ppm", ".psd", ".wal", ".rgb",
|
|
||||||
".ogg",
|
|
||||||
".x", ".b3d", ".md2", ".obj",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
if (removeStringEnd(filename, supported_ext) == ""){
|
|
||||||
infostream << "Server: ignoring unsupported file extension: \""
|
|
||||||
<< filename << "\"" << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Ok, attempt to load the file and add to cache
|
|
||||||
std::string filepath = mediapath + DIR_DELIM + filename;
|
|
||||||
// Read data
|
|
||||||
std::ifstream fis(filepath.c_str(), std::ios_base::binary);
|
|
||||||
if (!fis.good()) {
|
|
||||||
errorstream << "Server::fillMediaCache(): Could not open \""
|
|
||||||
<< filename << "\" for reading" << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::ostringstream tmp_os(std::ios_base::binary);
|
|
||||||
bool bad = false;
|
|
||||||
for(;;) {
|
|
||||||
char buf[1024];
|
|
||||||
fis.read(buf, 1024);
|
|
||||||
std::streamsize len = fis.gcount();
|
|
||||||
tmp_os.write(buf, len);
|
|
||||||
if (fis.eof())
|
|
||||||
break;
|
|
||||||
if (!fis.good()) {
|
|
||||||
bad = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(bad) {
|
|
||||||
errorstream<<"Server::fillMediaCache(): Failed to read \""
|
|
||||||
<< filename << "\"" << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(tmp_os.str().length() == 0) {
|
|
||||||
errorstream << "Server::fillMediaCache(): Empty file \""
|
|
||||||
<< filepath << "\"" << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHA1 sha1;
|
|
||||||
sha1.addBytes(tmp_os.str().c_str(), tmp_os.str().length());
|
|
||||||
|
|
||||||
unsigned char *digest = sha1.getDigest();
|
|
||||||
std::string sha1_base64 = base64_encode(digest, 20);
|
|
||||||
std::string sha1_hex = hex_encode((char*)digest, 20);
|
|
||||||
free(digest);
|
|
||||||
|
|
||||||
// Put in list
|
|
||||||
m_media[filename] = MediaInfo(filepath, sha1_base64);
|
|
||||||
verbosestream << "Server: " << sha1_hex << " is " << filename
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,6 +269,9 @@ public:
|
|||||||
|
|
||||||
void deleteParticleSpawner(const std::string &playername, u32 id);
|
void deleteParticleSpawner(const std::string &playername, u32 id);
|
||||||
|
|
||||||
|
bool addMediaFile(const std::string &filename, const std::string &filepath,
|
||||||
|
std::string *filedata = nullptr, std::string *digest = NULL);
|
||||||
|
|
||||||
// Creates or resets inventory
|
// Creates or resets inventory
|
||||||
Inventory* createDetachedInventory(const std::string &name, const std::string &player="");
|
Inventory* createDetachedInventory(const std::string &name, const std::string &player="");
|
||||||
|
|
||||||
@ -684,4 +687,3 @@ private:
|
|||||||
void dedicated_server_loop(Server &server, bool &kill);
|
void dedicated_server_loop(Server &server, bool &kill);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user