forked from Mirrorlandia_minetest/minetest
Map deletion button
This commit is contained in:
parent
d3a6a12bae
commit
035345f13d
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
51
src/main.cpp
51
src/main.cpp
@ -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
|
||||||
@ -1271,8 +1283,11 @@ int main(int argc, char *argv[])
|
|||||||
// 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.
|
||||||
*/
|
|
||||||
|
|
||||||
// Wait for proper parameters
|
Loop quits when menu returns proper parameters.
|
||||||
|
*/
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
// Cursor can be non-visible when coming from the game
|
// Cursor can be non-visible when coming from the game
|
||||||
@ -1672,6 +1687,15 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
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);
|
||||||
port = stoi(wide_to_narrow(menudata.port));
|
port = stoi(wide_to_narrow(menudata.port));
|
||||||
@ -2387,7 +2411,19 @@ 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;
|
||||||
|
|
||||||
hilightboxes.push_back(nodefacebox);
|
// 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);
|
||||||
|
|
||||||
|
// 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));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user