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 <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

View File

@ -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

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);
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)

View File

@ -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

View File

@ -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
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())
{
@ -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));
}