#include "scriptapi.h"
#include "nodedef.h"
#include "tooldef.h"
-#include "content_tool.h" // For content_tool_init
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
return checksum;
}
+struct ModSpec
+{
+ std::string name;
+ std::string path;
+
+ ModSpec(const std::string &name_="", const std::string path_=""):
+ name(name_),
+ path(path_)
+ {}
+};
+
+static core::list<ModSpec> getMods(core::list<std::string> &modspaths)
+{
+ core::list<ModSpec> mods;
+ for(core::list<std::string>::Iterator i = modspaths.begin();
+ i != modspaths.end(); i++){
+ std::string modspath = *i;
+ std::vector<fs::DirListNode> dirlist = fs::GetDirListing(modspath);
+ for(u32 j=0; j<dirlist.size(); j++){
+ if(!dirlist[j].dir)
+ continue;
+ std::string modname = dirlist[j].name;
+ std::string modpath = modspath + DIR_DELIM + modname;
+ mods.push_back(ModSpec(modname, modpath));
+ }
+ }
+ return mods;
+}
+
/*
Server
*/
infostream<<"m_nodemgr="<<m_nodemgr<<std::endl;
- // Initialize default tool definitions
- content_tool_init(m_toolmgr);
-
// Initialize default node definitions
content_mapnode_init(NULL, m_nodemgr);
+
+ // Add default global mod path
+ m_modspaths.push_back(porting::path_data + DIR_DELIM + "mods");
// Initialize scripting
// Export API
scriptapi_export(m_lua, this);
// Load and run scripts
- std::string defaultscript = porting::path_data + DIR_DELIM
- + "scripts" + DIR_DELIM + "default.lua";
- bool success = script_load(m_lua, defaultscript.c_str());
- if(!success){
- errorstream<<"Server: Failed to load and run "
- <<defaultscript<<std::endl;
- assert(0);
+ core::list<ModSpec> mods = getMods(m_modspaths);
+ for(core::list<ModSpec>::Iterator i = mods.begin();
+ i != mods.end(); i++){
+ ModSpec mod = *i;
+ infostream<<"Server: Loading mod \""<<mod.name<<"\""<<std::endl;
+ std::string scriptpath = mod.path + DIR_DELIM + "init.lua";
+ bool success = script_load(m_lua, scriptpath.c_str());
+ if(!success){
+ errorstream<<"Server: Failed to load and run "
+ <<scriptpath<<std::endl;
+ assert(0);
+ }
}
// Initialize Environment
/*
Send some initialization data
*/
+
+ // Send textures
+ SendTextures(peer_id);
+
+ // Send tool definitions
+ SendToolDef(m_con, peer_id, m_toolmgr);
// Send player info to all players
SendPlayerInfos();
con.Send(peer_id, 0, data, true);
}
+void Server::SendToolDef(con::Connection &con, u16 peer_id,
+ IToolDefManager *tooldef)
+{
+ DSTACK(__FUNCTION_NAME);
+ std::ostringstream os(std::ios_base::binary);
+
+ /*
+ u16 command
+ u32 length of the next item
+ serialized ToolDefManager
+ */
+ writeU16(os, TOCLIENT_TOOLDEF);
+ std::ostringstream tmp_os(std::ios::binary);
+ tooldef->serialize(tmp_os);
+ os<<serializeLongString(tmp_os.str());
+
+ // Make data buffer
+ std::string s = os.str();
+ SharedBuffer<u8> data((u8*)s.c_str(), s.size());
+ // Send as reliable
+ con.Send(peer_id, 0, data, true);
+}
+
/*
Non-static send methods
*/
}
}
+struct SendableTexture
+{
+ std::string name;
+ std::string path;
+ std::string data;
+
+ SendableTexture(const std::string &name_="", const std::string path_="",
+ const std::string &data_=""):
+ name(name_),
+ path(path_),
+ data(data_)
+ {}
+};
+
+void Server::SendTextures(u16 peer_id)
+{
+ DSTACK(__FUNCTION_NAME);
+
+ infostream<<"Server::SendTextures(): Sending textures to client"<<std::endl;
+
+ /* Read textures */
+
+ core::list<SendableTexture> textures;
+ core::list<ModSpec> mods = getMods(m_modspaths);
+ for(core::list<ModSpec>::Iterator i = mods.begin();
+ i != mods.end(); i++){
+ ModSpec mod = *i;
+ std::string texturepath = mod.path + DIR_DELIM + "textures";
+ std::vector<fs::DirListNode> dirlist = fs::GetDirListing(texturepath);
+ for(u32 j=0; j<dirlist.size(); j++){
+ if(dirlist[j].dir) // Ignode dirs
+ continue;
+ std::string tname = dirlist[j].name;
+ std::string tpath = texturepath + DIR_DELIM + tname;
+ // Read data
+ std::ifstream fis(tpath.c_str(), std::ios_base::binary);
+ if(fis.good() == false){
+ errorstream<<"Server::SendTextures(): Could not open \""
+ <<tname<<"\" 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::SendTextures(): Failed to read \""
+ <<tname<<"\""<<std::endl;
+ continue;
+ }
+ errorstream<<"Server::SendTextures(): Loaded \""
+ <<tname<<"\""<<std::endl;
+ // Put in list
+ textures.push_back(SendableTexture(tname, tpath, tmp_os.str()));
+ }
+ }
+
+ /* Create and send packet */
+
+ /*
+ u16 command
+ u32 number of textures
+ for each texture {
+ u16 length of name
+ string name
+ u32 length of data
+ data
+ }
+ */
+ std::ostringstream os(std::ios_base::binary);
+
+ writeU16(os, TOCLIENT_TEXTURES);
+ writeU32(os, textures.size());
+
+ for(core::list<SendableTexture>::Iterator i = textures.begin();
+ i != textures.end(); i++){
+ os<<serializeString(i->name);
+ os<<serializeLongString(i->data);
+ }
+
+ // Make data buffer
+ std::string s = os.str();
+ infostream<<"Server::SendTextures(): number of textures: "
+ <<textures.size()<<", data size: "<<s.size()<<std::endl;
+ SharedBuffer<u8> data((u8*)s.c_str(), s.size());
+ // Send as reliable
+ m_con.Send(peer_id, 0, data, true);
+}
+
/*
Something random
*/
return NULL;
}
+IWritableToolDefManager* Server::getWritableToolDefManager()
+{
+ return m_toolmgr;
+}
+IWritableNodeDefManager* Server::getWritableNodeDefManager()
+{
+ return m_nodemgr;
+}
+
v3f findSpawnPos(ServerMap &map)
{
//return v3f(50,50,50)*BS;