Map deletion button

This commit is contained in:
Perttu Ahola 2011-01-26 00:40:33 +02:00
parent d3a6a12bae
commit 035345f13d
5 changed files with 157 additions and 9 deletions

View File

@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "filesys.h" #include "filesys.h"
#include <iostream> #include <iostream>
#include <string.h>
namespace fs namespace fs
{ {
@ -130,12 +131,35 @@ bool PathExists(std::string path)
return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES); 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 #else // POSIX
#include <sys/types.h> #include <sys/types.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h>
std::vector<DirListNode> GetDirListing(std::string pathstring) std::vector<DirListNode> GetDirListing(std::string pathstring)
{ {
@ -184,7 +208,70 @@ bool PathExists(std::string path)
return (stat(path.c_str(),&st) == 0); 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 #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 } // namespace fs

View File

@ -40,6 +40,12 @@ bool CreateDir(std::string path);
bool PathExists(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 }//fs
#endif #endif

View File

@ -177,6 +177,12 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
rect = rect + v2s32(size.X/2-180/2, size.Y/2-30/2 + 100); rect = rect + v2s32(size.X/2-180/2, size.Y/2-30/2 + 100);
Environment->addButton(rect, this, 257, L"Start Game / Connect"); 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() void GUIMainMenu::drawMenu()
@ -252,10 +258,16 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
{ {
switch(event.GUIEvent.Caller->getID()) switch(event.GUIEvent.Caller->getID())
{ {
case 257: case 257: // Start game
acceptInput(); acceptInput();
quitMenu(); quitMenu();
break; 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) if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)

View File

@ -29,11 +29,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
struct MainMenuData struct MainMenuData
{ {
MainMenuData():
creative_mode(false),
delete_map(false)
{}
// These are in the native format of the gui elements // These are in the native format of the gui elements
std::wstring address; std::wstring address;
std::wstring port; std::wstring port;
std::wstring name; std::wstring name;
bool creative_mode; bool creative_mode;
// If map deletion is requested, this is set to true
bool delete_map;
}; };
class GUIMainMenu : public GUIModalMenu class GUIMainMenu : public GUIModalMenu

View File

@ -153,8 +153,10 @@ TODO: Optimize day/night mesh updating somehow
meshbuffers? It should go quite fast. meshbuffers? It should go quite fast.
- This is not easy; There'd need to be a buffer somewhere - This is not easy; There'd need to be a buffer somewhere
that would contain the night and day lighting values. 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 gets used
- That is >500 vertices - That is >500 vertices
- This is not easy; all the MapBlocks close to the player would - 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: 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: Server:
------- -------
@ -260,10 +266,15 @@ FEATURE: The map could be generated procedually:
- How about relocating minerals, too? Coal and gold in - How about relocating minerals, too? Coal and gold in
downstream sand and gravel would be kind of cool downstream sand and gravel would be kind of cool
- This would need a better way of handling minerals, mainly - 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 - Simulate rock falling from cliffs when water has removed
enough solid rock from the bottom 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 TODO: Change AttributeList to split the area into smaller sections so
that searching won't be as heavy. that searching won't be as heavy.
@ -308,6 +319,7 @@ Doing now:
#pragma comment(lib, "Irrlicht.lib") #pragma comment(lib, "Irrlicht.lib")
//#pragma comment(lib, "jthread.lib") //#pragma comment(lib, "jthread.lib")
#pragma comment(lib, "zlibwapi.lib") #pragma comment(lib, "zlibwapi.lib")
#pragma comment(lib, "Shell32.lib")
// This would get rid of the console window // This would get rid of the console window
//#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") //#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif #endif
@ -1270,9 +1282,12 @@ int main(int argc, char *argv[])
porting::initializePaths(); porting::initializePaths();
// Create user data directory // Create user data directory
fs::CreateDir(porting::path_userdata); fs::CreateDir(porting::path_userdata);
// C-style stuff initialization
initializeMaterialProperties(); initializeMaterialProperties();
init_mapnode();
// Debug handler
BEGIN_DEBUG_EXCEPTION_HANDLER BEGIN_DEBUG_EXCEPTION_HANDLER
// Print startup message // Print startup message
@ -1550,7 +1565,7 @@ int main(int argc, char *argv[])
*/ */
init_content_inventory_texture_paths(); init_content_inventory_texture_paths();
init_tile_textures(); //init_tile_textures();
/* /*
GUI stuff 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(;;) for(;;)
{ {
// Cursor can be non-visible when coming from the game // 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; dstream<<"Dropping main menu"<<std::endl;
menu->drop(); 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); playername = wide_to_narrow(menudata.name);
address = wide_to_narrow(menudata.address); address = wide_to_narrow(menudata.address);
@ -2386,8 +2410,20 @@ int main(int argc, char *argv[])
static float dig_time = 0.0; static float dig_time = 0.0;
static u16 dig_index = 0; static u16 dig_index = 0;
// Visualize selection
hilightboxes.push_back(nodefacebox); 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);
// Handle digging
if(g_input->getLeftReleased()) if(g_input->getLeftReleased())
{ {
@ -2473,6 +2509,7 @@ int main(int argc, char *argv[])
if(dig_index < CRACK_ANIMATION_LENGTH) if(dig_index < CRACK_ANIMATION_LENGTH)
{ {
//TimeTaker timer("client.setTempMod");
//dstream<<"dig_index="<<dig_index<<std::endl; //dstream<<"dig_index="<<dig_index<<std::endl;
client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index)); client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index));
} }