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:
hikerstk 2011-01-05 21:54:12 +00:00
parent 0bbcfc2361
commit a4db783f7e
4 changed files with 71 additions and 79 deletions

View File

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

View File

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

View File

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

View File

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