Fixed deleting installed addons.
NOTE: it is still NOT safe to use this, esp. now that there is code to remove a directory :) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7282 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
0bbcfc2361
commit
a4db783f7e
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "addons/network_http.hpp"
|
#include "addons/network_http.hpp"
|
||||||
#include "addons/zip.hpp"
|
#include "addons/zip.hpp"
|
||||||
|
#include "graphics/irr_driver.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "io/xml_node.hpp"
|
#include "io/xml_node.hpp"
|
||||||
#include "karts/kart_properties_manager.hpp"
|
#include "karts/kart_properties_manager.hpp"
|
||||||
@ -65,8 +66,6 @@ void AddonsManager::initOnline()
|
|||||||
int download_state = 0;
|
int download_state = 0;
|
||||||
m_download_state = download_state;
|
m_download_state = download_state;
|
||||||
|
|
||||||
// FIXME: It is _very_ dirty to save the list as a locale file
|
|
||||||
// since we have a function to load it directly in a string.
|
|
||||||
if(UserConfigParams::m_verbosity>=3)
|
if(UserConfigParams::m_verbosity>=3)
|
||||||
printf("[addons] Addons manager downloading list\n");
|
printf("[addons] Addons manager downloading list\n");
|
||||||
if(!network_http->downloadFileSynchron("list"))
|
if(!network_http->downloadFileSynchron("list"))
|
||||||
@ -171,7 +170,7 @@ int AddonsManager::getAddonIndex(const std::string &id) const
|
|||||||
void AddonsManager::install(const Addon &addon)
|
void AddonsManager::install(const Addon &addon)
|
||||||
{
|
{
|
||||||
bool success=true;
|
bool success=true;
|
||||||
std::string id = StringUtils::toLowerCase(addon.getName());
|
const std::string &id = addon.getId();
|
||||||
file_manager->checkAndCreateDirForAddons(id, addon.getType()+ "s/");
|
file_manager->checkAndCreateDirForAddons(id, addon.getType()+ "s/");
|
||||||
|
|
||||||
//extract the zip in the addons folder called like the addons name
|
//extract the zip in the addons folder called like the addons name
|
||||||
@ -197,6 +196,17 @@ void AddonsManager::install(const Addon &addon)
|
|||||||
m_addons_list[index].setInstalled(true);
|
m_addons_list[index].setInstalled(true);
|
||||||
|
|
||||||
m_str_state = "Reloading kart list...";
|
m_str_state = "Reloading kart list...";
|
||||||
|
if(addon.getType()=="kart")
|
||||||
|
{
|
||||||
|
// We have to remove the mesh of the kart since otherwise it remains
|
||||||
|
// cashed, and will therefore be found again when reloading the karts.
|
||||||
|
// This is important on one hand since we reload all karts (this
|
||||||
|
// function is easily available) and existing karts will not reload
|
||||||
|
// their meshes.
|
||||||
|
const KartProperties *prop = kart_properties_manager->getKart(addon.getId());
|
||||||
|
const KartModel &model = prop->getMasterKartModel();
|
||||||
|
irr_driver->removeMesh(model.getModel());
|
||||||
|
}
|
||||||
saveInstalled();
|
saveInstalled();
|
||||||
} // install
|
} // install
|
||||||
|
|
||||||
@ -238,11 +248,11 @@ void AddonsManager::uninstall(const Addon &addon)
|
|||||||
m_addons_list[index].setInstalled(false);
|
m_addons_list[index].setInstalled(false);
|
||||||
|
|
||||||
//write the xml file with the informations about installed karts
|
//write the xml file with the informations about installed karts
|
||||||
std::string dest_file = file_manager->getAddonsDir() + "/"
|
std::string name=addon.getType()+"s/"+addon.getId();
|
||||||
+ addon.getType()+ "s/" + addon.getName()+ "/";
|
std::string dest_file = file_manager->getAddonsFile(name);
|
||||||
|
|
||||||
//remove the addons directory
|
//remove the addons directory
|
||||||
file_manager->removeDirectory(dest_file.c_str());
|
file_manager->removeDirectory(dest_file);
|
||||||
saveInstalled();
|
saveInstalled();
|
||||||
|
|
||||||
} // uninstall
|
} // uninstall
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# ifndef __CYGWIN__
|
# ifndef __CYGWIN__
|
||||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||||
// Some portabilty defines
|
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
@ -56,6 +56,7 @@
|
|||||||
#include "irrlicht.h"
|
#include "irrlicht.h"
|
||||||
#include "btBulletDynamicsCommon.h"
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
|
||||||
|
#include "config/user_config.hpp"
|
||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
#include "graphics/material_manager.hpp"
|
#include "graphics/material_manager.hpp"
|
||||||
#include "karts/kart_properties_manager.hpp"
|
#include "karts/kart_properties_manager.hpp"
|
||||||
@ -495,6 +496,7 @@ void FileManager::checkAndCreateConfigDir()
|
|||||||
return;
|
return;
|
||||||
} // checkAndCreateConfigDir
|
} // checkAndCreateConfigDir
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
#ifdef ADDONS_MANAGER
|
#ifdef ADDONS_MANAGER
|
||||||
void FileManager::checkAndCreateAddonsDir()
|
void FileManager::checkAndCreateAddonsDir()
|
||||||
{
|
{
|
||||||
@ -543,16 +545,17 @@ void FileManager::checkAndCreateAddonsDir()
|
|||||||
m_addons_dir.c_str());
|
m_addons_dir.c_str());
|
||||||
m_config_dir = ".";
|
m_config_dir = ".";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!checkAndCreateDirectory(m_addons_dir + "/icons/"))
|
||||||
{
|
{
|
||||||
//we hope that there will be no problem since we created the other dir
|
fprintf(stderr, "Failed to create add-ons icon dir at '%s'\n",
|
||||||
if (!checkAndCreateDirectory(m_addons_dir + "/data/"))
|
(m_addons_dir + "/icons/").c_str());
|
||||||
{
|
}
|
||||||
fprintf(stderr, "Failed to create add-ons data dir at '%s'\n",
|
if (!checkAndCreateDirectory(m_addons_dir + "/tmp/"))
|
||||||
(m_addons_dir + "/data/").c_str());
|
{
|
||||||
}
|
fprintf(stderr, "Failed to create add-ons tmp dir at '%s'\n",
|
||||||
|
(m_addons_dir + "/tmp/").c_str());
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
} // checkAndCreateAddonsDir
|
} // checkAndCreateAddonsDir
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -620,6 +623,18 @@ std::string FileManager::getChallengeFile(const std::string &fname) const
|
|||||||
return getConfigDir()+"/"+fname;
|
return getConfigDir()+"/"+fname;
|
||||||
} // getChallengeFile
|
} // getChallengeFile
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns true if the given name is a directory.
|
||||||
|
* \param path File name to test.
|
||||||
|
*/
|
||||||
|
bool FileManager::isDirectory(const std::string &path) const
|
||||||
|
{
|
||||||
|
struct stat mystat;
|
||||||
|
|
||||||
|
if(stat(path.c_str(), &mystat) < 0) return false;
|
||||||
|
return S_ISDIR(mystat.st_mode);
|
||||||
|
} // isDirectory
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void FileManager::listFiles(std::set<std::string>& result,
|
void FileManager::listFiles(std::set<std::string>& result,
|
||||||
const std::string& dir, bool is_full_path,
|
const std::string& dir, bool is_full_path,
|
||||||
@ -634,10 +649,7 @@ void FileManager::listFiles(std::set<std::string>& result,
|
|||||||
#endif
|
#endif
|
||||||
//printf("******* Path : %s \n", path.c_str());
|
//printf("******* Path : %s \n", path.c_str());
|
||||||
|
|
||||||
struct stat mystat;
|
if(!isDirectory(path)) return;
|
||||||
|
|
||||||
if(stat(path.c_str(), &mystat) < 0) return;
|
|
||||||
if(! S_ISDIR(mystat.st_mode)) return;
|
|
||||||
|
|
||||||
io::path previous_cwd = m_file_system->getWorkingDirectory();
|
io::path previous_cwd = m_file_system->getWorkingDirectory();
|
||||||
|
|
||||||
@ -675,72 +687,41 @@ void FileManager::checkAndCreateDirForAddons(std::string addons_name,
|
|||||||
} // checkAndCreateDirForAddons
|
} // checkAndCreateDirForAddons
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
bool FileManager::removeDirectory(char const *name)
|
/** Removes a directory (including all files contained). The function could
|
||||||
|
* easily recursively delete further subdirectories, but this is commented
|
||||||
|
* out atm (to limit the amount of damage in case of a bug).
|
||||||
|
* \param name Directory name to remove.
|
||||||
|
*/
|
||||||
|
bool FileManager::removeDirectory(const std::string &name)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
std::set<std::string> files;
|
||||||
// DIR etc. do not exist like this in windows,
|
listFiles(files, name, /*is full path*/ true);
|
||||||
// file system specific calls should be moved into
|
for(std::set<std::string>::iterator i=files.begin(); i!=files.end(); i++)
|
||||||
// the file manager!!
|
|
||||||
|
|
||||||
DIR *directory;
|
|
||||||
struct dirent *entry;
|
|
||||||
struct stat file_stat;
|
|
||||||
|
|
||||||
char buffer[1024] = {0};
|
|
||||||
|
|
||||||
directory = opendir(name);
|
|
||||||
if ( directory == NULL )
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "cannot open directory %s\n", name);
|
if((*i)=="." || (*i)=="..") continue;
|
||||||
return false;
|
if(UserConfigParams::m_verbosity>=3)
|
||||||
}
|
printf("Deleting directory '%s'.\n", (*i).c_str());
|
||||||
|
std::string full_path=name+"/"+*i;
|
||||||
while ((entry = readdir(directory)) != NULL)
|
if(isDirectory(full_path))
|
||||||
{
|
|
||||||
|
|
||||||
/*this condition handles if it is the current directory (.) or the
|
|
||||||
parent directory (..), these names work only on unix-based I think*/
|
|
||||||
if (strcmp(entry->d_name, ".") == 0 ||
|
|
||||||
strcmp(entry->d_name, "..") == 0)
|
|
||||||
{
|
{
|
||||||
continue;
|
// This should not be necessary (since this function is only
|
||||||
|
// used to remove addons), and it limits the damage in case
|
||||||
|
// of any bugs - i.e. if name should be "/" or so.
|
||||||
|
// removeDirectory(full_path);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
snprintf(buffer, 1024, "%s/%s", name, entry->d_name);
|
|
||||||
|
|
||||||
stat(buffer, &file_stat);
|
|
||||||
|
|
||||||
if (S_ISREG(file_stat.st_mode))
|
|
||||||
{
|
{
|
||||||
remove(buffer);
|
struct stat mystat;
|
||||||
}
|
if(stat(full_path.c_str(), &mystat) < 0) return false;
|
||||||
else if (S_ISDIR(file_stat.st_mode))
|
if( S_ISREG(mystat.st_mode))
|
||||||
{
|
remove(full_path.c_str());
|
||||||
this->removeDirectory(buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(directory);
|
#ifdef WIN32
|
||||||
|
return ::RemoveDirectory(name.c_str())==TRUE;
|
||||||
remove(name);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
::RemoveDirectory(name);
|
return remove(name.c_str());
|
||||||
return true;
|
|
||||||
#if 0
|
|
||||||
SHFILEOPSTRUCT sh;
|
|
||||||
sh.hwnd = NULL;
|
|
||||||
sh.wFunc = FO_DELETE;
|
|
||||||
sh.pFrom = repertoire;
|
|
||||||
sh.pTo = NULL;
|
|
||||||
sh.fFlags = FOF_NOCONFIRMATION|FOF_SILENT;
|
|
||||||
sh.fAnyOperationsAborted = FALSE;
|
|
||||||
sh.lpszProgressTitle = NULL;
|
|
||||||
sh.hNameMappings = NULL;
|
|
||||||
|
|
||||||
return (SHFileOperation(&sh)==0);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
} // remove directory
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -70,6 +70,7 @@ private:
|
|||||||
void checkAndCreateConfigDir();
|
void checkAndCreateConfigDir();
|
||||||
#ifdef ADDONS_MANAGER
|
#ifdef ADDONS_MANAGER
|
||||||
void checkAndCreateAddonsDir();
|
void checkAndCreateAddonsDir();
|
||||||
|
bool isDirectory(const std::string &path) const;
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
FileManager(char *argv[]);
|
FileManager(char *argv[]);
|
||||||
@ -86,7 +87,7 @@ public:
|
|||||||
std::string getAddonsFile(const std::string &name);
|
std::string getAddonsFile(const std::string &name);
|
||||||
void checkAndCreateDirForAddons(std::string addons_name,
|
void checkAndCreateDirForAddons(std::string addons_name,
|
||||||
std::string addons_type);
|
std::string addons_type);
|
||||||
bool removeDirectory(char const *name);
|
bool removeDirectory(const std::string &name);
|
||||||
#endif
|
#endif
|
||||||
std::string getDataDir () const;
|
std::string getDataDir () const;
|
||||||
std::string getTranslationDir() const;
|
std::string getTranslationDir() const;
|
||||||
|
@ -167,7 +167,6 @@ void AddonsLoading::onUpdate(float delta)
|
|||||||
{
|
{
|
||||||
printf("Download finished.\n");
|
printf("Download finished.\n");
|
||||||
endInstall();
|
endInstall();
|
||||||
dismiss();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,5 +222,6 @@ void AddonsLoading::endInstall()
|
|||||||
// The list of the addon screen needs to be updated to correctly
|
// The list of the addon screen needs to be updated to correctly
|
||||||
// display the newly (un)installed addon.
|
// display the newly (un)installed addon.
|
||||||
AddonsScreen::getInstance()->loadList();
|
AddonsScreen::getInstance()->loadList();
|
||||||
|
dismiss();
|
||||||
} // endInstall
|
} // endInstall
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user