diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/filesys.cpp | 87 | ||||
-rw-r--r-- | src/filesys.h | 6 | ||||
-rw-r--r-- | src/guiMainMenu.cpp | 14 | ||||
-rw-r--r-- | src/guiMainMenu.h | 6 | ||||
-rw-r--r-- | src/main.cpp | 53 |
5 files changed, 157 insertions, 9 deletions
diff --git a/src/filesys.cpp b/src/filesys.cpp index a2d3f9d14..a025ec185 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include <iostream> +#include <string.h> namespace fs { @@ -130,12 +131,35 @@ bool PathExists(std::string path) return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES); } +bool RecursiveDelete(std::string path) +{ + std::cerr<<"Removing \""<<path<<"\""<<std::endl; + + return false; + + // This silly function needs a double-null terminated string... + // Well, we'll just make sure it has at least two, then. + path += "\0\0"; + + SHFILEOPSTRUCT sfo; + sfo.hwnd = NULL; + sfo.wFunc = FO_DELETE; + sfo.pFrom = path.c_str(); + sfo.pTo = NULL; + sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR; + + int r = SHFileOperation(&sfo); + + return (r == 0); +} + #else // POSIX #include <sys/types.h> #include <dirent.h> #include <errno.h> #include <sys/stat.h> +#include <sys/wait.h> std::vector<DirListNode> GetDirListing(std::string pathstring) { @@ -184,7 +208,70 @@ bool PathExists(std::string path) return (stat(path.c_str(),&st) == 0); } +bool RecursiveDelete(std::string path) +{ + /* + Execute the 'rm' command directly, by fork() and execve() + */ + + std::cerr<<"Removing \""<<path<<"\""<<std::endl; + + //return false; + + pid_t child_pid = fork(); + + if(child_pid == 0) + { + // Child + char argv_data[3][10000]; + strcpy(argv_data[0], "/bin/rm"); + strcpy(argv_data[1], "-rf"); + strncpy(argv_data[2], path.c_str(), 10000); + char *argv[4]; + argv[0] = argv_data[0]; + argv[1] = argv_data[1]; + argv[2] = argv_data[2]; + argv[3] = NULL; + + std::cerr<<"Executing '"<<argv[0]<<"' '"<<argv[1]<<"' '" + <<argv[2]<<"'"<<std::endl; + + execv(argv[0], argv); + + // Execv shouldn't return. Failed. + return false; + } + else + { + // Parent + int child_status; + pid_t tpid; + do{ + tpid = wait(&child_status); + //if(tpid != child_pid) process_terminated(tpid); + }while(tpid != child_pid); + return (child_status == 0); + } +} + #endif +bool RecursiveDeleteContent(std::string path) +{ + std::cerr<<"Removing content of \""<<path<<"\""<<std::endl; + std::vector<DirListNode> list = GetDirListing(path); + for(unsigned int i=0; i<list.size(); i++) + { + std::string childpath = path+"/"+list[i].name; + bool r = RecursiveDelete(childpath); + if(r == false) + { + std::cerr<<"Removing \""<<childpath<<"\" failed"<<std::endl; + return false; + } + } + return true; +} + } // namespace fs diff --git a/src/filesys.h b/src/filesys.h index 6dbc426a5..e46b17b0d 100644 --- a/src/filesys.h +++ b/src/filesys.h @@ -40,6 +40,12 @@ bool CreateDir(std::string path); bool PathExists(std::string path); +// Only pass full paths to this one. True on success. +bool RecursiveDelete(std::string path); + +// Only pass full paths to this one. True on success. +bool RecursiveDeleteContent(std::string path); + }//fs #endif diff --git a/src/guiMainMenu.cpp b/src/guiMainMenu.cpp index 84435b5f3..2d02c0295 100644 --- a/src/guiMainMenu.cpp +++ b/src/guiMainMenu.cpp @@ -177,6 +177,12 @@ void GUIMainMenu::regenerateGui(v2u32 screensize) rect = rect + v2s32(size.X/2-180/2, size.Y/2-30/2 + 100); Environment->addButton(rect, this, 257, L"Start Game / Connect"); } + // Map delete button + { + core::rect<s32> rect(0, 0, 130, 30); + rect = rect + v2s32(size.X/2-130/2+200, size.Y/2-30/2 + 100); + Environment->addButton(rect, this, 260, L"Delete map"); + } } void GUIMainMenu::drawMenu() @@ -252,10 +258,16 @@ bool GUIMainMenu::OnEvent(const SEvent& event) { switch(event.GUIEvent.Caller->getID()) { - case 257: + case 257: // Start game acceptInput(); quitMenu(); break; + case 260: // Delete map + // Don't accept input data, just set deletion request + m_data->delete_map = true; + m_accepted = true; + quitMenu(); + break; } } if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER) diff --git a/src/guiMainMenu.h b/src/guiMainMenu.h index 8060f511d..010d0bf6d 100644 --- a/src/guiMainMenu.h +++ b/src/guiMainMenu.h @@ -29,11 +29,17 @@ with this program; if not, write to the Free Software Foundation, Inc., struct MainMenuData { + MainMenuData(): + creative_mode(false), + delete_map(false) + {} // These are in the native format of the gui elements std::wstring address; std::wstring port; std::wstring name; bool creative_mode; + // If map deletion is requested, this is set to true + bool delete_map; }; class GUIMainMenu : public GUIModalMenu diff --git a/src/main.cpp b/src/main.cpp index 171f1538a..da1b88d4a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -153,8 +153,10 @@ TODO: Optimize day/night mesh updating somehow meshbuffers? It should go quite fast.
- This is not easy; There'd need to be a buffer somewhere
that would contain the night and day lighting values.
+ - Actually if FastFaces would be stored, they could
+ hold both values
-TODO: Combine MapBlock's face caches to so big pieces that VBO
+FEATURE: Combine MapBlock's face caches to so big pieces that VBO
gets used
- That is >500 vertices
- This is not easy; all the MapBlocks close to the player would
@@ -181,6 +183,10 @@ TODO: Untie client network operations from framerate TODO: Make morning and evening shorter
+TODO: Don't update all meshes always on single node changes, but
+ check which ones should be updated
+ - implement Map::updateNodeMeshes()
+
Server:
-------
@@ -260,10 +266,15 @@ FEATURE: The map could be generated procedually: - How about relocating minerals, too? Coal and gold in
downstream sand and gravel would be kind of cool
- This would need a better way of handling minerals, mainly
- to have mineral content as a separate field
+ to have mineral content as a separate field. the first
+ parameter field is free for this.
- Simulate rock falling from cliffs when water has removed
enough solid rock from the bottom
+TODO: Mineral and ground material properties
+ - This way mineral ground toughness can be calculated with just
+ some formula, as well as tool strengths
+
TODO: Change AttributeList to split the area into smaller sections so
that searching won't be as heavy.
@@ -308,6 +319,7 @@ Doing now: #pragma comment(lib, "Irrlicht.lib")
//#pragma comment(lib, "jthread.lib")
#pragma comment(lib, "zlibwapi.lib")
+#pragma comment(lib, "Shell32.lib")
// This would get rid of the console window
//#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
@@ -1270,9 +1282,12 @@ int main(int argc, char *argv[]) porting::initializePaths();
// Create user data directory
fs::CreateDir(porting::path_userdata);
-
+
+ // C-style stuff initialization
initializeMaterialProperties();
+ init_mapnode();
+ // Debug handler
BEGIN_DEBUG_EXCEPTION_HANDLER
// Print startup message
@@ -1550,7 +1565,7 @@ int main(int argc, char *argv[]) */
init_content_inventory_texture_paths();
- init_tile_textures();
+ //init_tile_textures();
/*
GUI stuff
@@ -1608,10 +1623,10 @@ int main(int argc, char *argv[]) {
/*
- Out-of-game menu loop
+ Out-of-game menu loop.
+
+ Loop quits when menu returns proper parameters.
*/
-
- // Wait for proper parameters
for(;;)
{
// Cursor can be non-visible when coming from the game
@@ -1671,6 +1686,15 @@ int main(int argc, char *argv[]) dstream<<"Dropping main menu"<<std::endl;
menu->drop();
+
+ // Delete map if requested
+ if(menudata.delete_map)
+ {
+ bool r = fs::RecursiveDeleteContent(map_dir);
+ if(r == false)
+ error_message = L"Delete failed";
+ continue;
+ }
playername = wide_to_narrow(menudata.name);
address = wide_to_narrow(menudata.address);
@@ -2386,8 +2410,20 @@ int main(int argc, char *argv[]) static float dig_time = 0.0;
static u16 dig_index = 0;
+
+ // Visualize selection
+
+ const float d = 0.502;
+ core::aabbox3d<f32> nodebox(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
+ v3f nodepos_f = intToFloat(nodepos);
+ //v3f nodepos_f(nodepos.X*BS, nodepos.Y*BS, nodepos.Z*BS);
+ nodebox.MinEdge += nodepos_f;
+ nodebox.MaxEdge += nodepos_f;
+ hilightboxes.push_back(nodebox);
+
+ //hilightboxes.push_back(nodefacebox);
- hilightboxes.push_back(nodefacebox);
+ // Handle digging
if(g_input->getLeftReleased())
{
@@ -2473,6 +2509,7 @@ int main(int argc, char *argv[]) if(dig_index < CRACK_ANIMATION_LENGTH)
{
+ //TimeTaker timer("client.setTempMod");
//dstream<<"dig_index="<<dig_index<<std::endl;
client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index));
}
|