std::string getRealName(const char* filename) { const char* dir = PHYSFS_getRealDir(filename); if (dir == 0) { throw Exception("no such path '%s'", filename); } std::string realname = dir; realname += PHYSFS_getDirSeparator(); realname += filename; return realname; }
void AddonManager::install_addon(const AddonId& addon_id) { { // remove addon if it already exists auto it = std::find_if(m_installed_addons.begin(), m_installed_addons.end(), [&addon_id](const std::unique_ptr<Addon>& addon) { return addon->get_id() == addon_id; }); if (it != m_installed_addons.end()) { log_debug << "reinstalling addon " << addon_id << std::endl; if ((*it)->is_enabled()) { disable_addon((*it)->get_id()); } m_installed_addons.erase(it); } else { log_debug << "installing addon " << addon_id << std::endl; } } auto& repository_addon = get_repository_addon(addon_id); std::string install_filename = FileSystem::join(m_addon_directory, repository_addon.get_filename()); m_downloader.download(repository_addon.get_url(), install_filename); MD5 md5 = md5_from_file(install_filename); if (repository_addon.get_md5() != md5.hex_digest()) { if (PHYSFS_delete(install_filename.c_str()) == 0) { log_warning << "PHYSFS_delete failed: " << PHYSFS_getLastError() << std::endl; } throw std::runtime_error("Downloading Add-on failed: MD5 checksums differ"); } else { const char* realdir = PHYSFS_getRealDir(install_filename.c_str()); if (!realdir) { throw std::runtime_error("PHYSFS_getRealDir failed: " + install_filename); } else { add_installed_archive(install_filename, md5.hex_digest()); } } }
bool deleteAll(const char* filePath, bool deleteRoot) { PHYSFS_Stat fileStat; if (PHYSFS_stat(filePath, &fileStat) == 0) { return false; } bool ret = false; if (fileStat.filetype == PHYSFS_FILETYPE_DIRECTORY) { auto paths = PHYSFS_enumerateFiles(filePath); if (paths != nullptr) { auto writeDir = PHYSFS_getWriteDir(); if (writeDir != nullptr) { for (char** path = paths; *path != nullptr; path++) { auto fullPath = std::string(filePath) + '/' + *path; if (PHYSFS_stat(fullPath.c_str(), &fileStat) == 0) { continue; } if (fileStat.filetype == PHYSFS_FILETYPE_DIRECTORY) { deleteAll(fullPath.c_str(), true); } else { auto realDir = PHYSFS_getRealDir(fullPath.c_str()); if (realDir != nullptr) { if (std::strcmp(writeDir, realDir) == 0) { ret = PHYSFS_delete(fullPath.c_str()) != 0; } } } } } PHYSFS_freeList(paths); } if (deleteRoot == true) { ret = PHYSFS_delete(filePath) != 0; } } else { ret = PHYSFS_delete(filePath) != 0; } return ret; }
// All scripts, binary or otherwise are now passed through this routine static bool dataScriptLoad(const char* fileName, void **ppData) { static const bool printHack = false; SCRIPT_CODE** psProg = (SCRIPT_CODE**)ppData; PHYSFS_file* fileHandle; uint8_t *pBuffer; PHYSFS_sint64 fileSize = 0; debug(LOG_WZ, "COMPILING SCRIPT ...%s", GetLastResourceFilename()); fileHandle = PHYSFS_openRead(fileName); debug(LOG_WZ, "Reading...[directory: %s] %s", PHYSFS_getRealDir(fileName), fileName); if (fileHandle == NULL) { return false; } // due to the changes in r2531 we must do this routine a bit different. fileSize = PHYSFS_fileLength(fileHandle); pBuffer = malloc(fileSize * sizeof(char)); if (pBuffer == NULL) { debug(LOG_FATAL, "Fatal memory allocation, couldn't allocate %lld buffer", fileSize); abort(); } PHYSFS_read(fileHandle, pBuffer, 1, fileSize); calcDataHash(pBuffer, fileSize, DATA_SCRIPT); free(pBuffer); PHYSFS_seek(fileHandle, 0); //reset position *psProg = scriptCompile(fileHandle, SCRIPTTYPE); PHYSFS_close(fileHandle); if (!*psProg) // see script.h { debug(LOG_ERROR, "Script %s did not compile", GetLastResourceFilename()); return false; } if (printHack) { cpPrintProgram(*psProg); } return true; }
bool buildMapList() { if (!loadLevFile("gamedesc.lev", mod_campaign, false, NULL)) { return false; } loadLevFile("addon.lev", mod_multiplay, false, NULL); WZ_Maps.clear(); MapFileList realFileNames = listMapFiles(); for (MapFileList::iterator realFileName = realFileNames.begin(); realFileName != realFileNames.end(); ++realFileName) { bool mapmod = false; struct WZmaps CurrentMap; std::string realFilePathAndName = PHYSFS_getRealDir(realFileName->c_str()) + *realFileName; PHYSFS_addToSearchPath(realFilePathAndName.c_str(), PHYSFS_APPEND); char **filelist = PHYSFS_enumerateFiles(""); for (char **file = filelist; *file != NULL; ++file) { std::string checkfile = *file; size_t len = strlen(*file); if (len > 10 && !strcasecmp(*file + (len - 10), ".addon.lev")) // Do not add addon.lev again { loadLevFile(*file, mod_multiplay, true, realFileName->c_str()); } // add support for X player maps using a new name to prevent conflicts. if (len > 13 && !strcasecmp(*file + (len - 13), ".xplayers.lev")) { loadLevFile(*file, mod_multiplay, true, realFileName->c_str()); } } PHYSFS_freeList(filelist); if (PHYSFS_removeFromSearchPath(realFilePathAndName.c_str()) == 0) { debug(LOG_ERROR, "Could not unmount %s, %s", realFilePathAndName.c_str(), PHYSFS_getLastError()); } mapmod = CheckInMap(realFilePathAndName.c_str(), "WZMap", "WZMap"); if (!mapmod) { mapmod = CheckInMap(realFilePathAndName.c_str(), "WZMap", "WZMap/multiplay"); } CurrentMap.MapName = realFileName->c_str(); CurrentMap.isMapMod = mapmod; WZ_Maps.push_back(CurrentMap); } return true; }
bool AddonManager::is_from_old_addon(const std::string& filename) const { std::string real_path = PHYSFS_getRealDir(filename.c_str()); for (auto& addon : m_installed_addons) { if (addon->get_format() == Addon::ORIGINAL && addon->is_enabled() && addon->get_install_filename() == real_path) { return true; } } return false; }
bool Virtual_file_system::query_resolved_path(std::string& resolved_path, const std::string& name) const { const char* resolved = PHYSFS_getRealDir(name.c_str()); if (!resolved) { return false; } resolved_path = std::string(resolved); return true; }
bool deleteFile(const char* filePath) noexcept { auto writeDir = PHYSFS_getWriteDir(); auto realDir = PHYSFS_getRealDir(filePath); if (writeDir != nullptr && realDir != nullptr) { if (strcmp(writeDir, realDir) == 0) { return PHYSFS_delete(filePath) != 0; } } return false; }
std::string ResourceManager::getDataPath(std::string file) { if (doesExist(file)) { std::string path = PHYSFS_getRealDir(file.c_str()); #ifndef _WIN32 return path + "/" + file; #else return path + file; #endif } return ""; }
// Load a script variable values file static bool dataScriptLoadVals(const char* fileName, void **ppData) { bool success; PHYSFS_file* fileHandle; uint8_t *pBuffer; PHYSFS_sint64 fileSize = 0; *ppData = NULL; // don't load anything if a saved game is being loaded if (saveFlag) { return true; } debug(LOG_WZ, "Loading script data %s", GetLastResourceFilename()); fileHandle = PHYSFS_openRead(fileName); debug(LOG_WZ, "Reading...[directory: %s] %s", PHYSFS_getRealDir(fileName), fileName); if (fileHandle == NULL) { return false; } // due to the changes in r2532 we must do this routine a bit different. fileSize = PHYSFS_fileLength(fileHandle); pBuffer = malloc(fileSize * sizeof(char)); if (pBuffer == NULL) { debug(LOG_FATAL, "Fatal memory allocation, couldn't allocate %lld buffer", fileSize); abort(); } PHYSFS_read(fileHandle, pBuffer, 1, fileSize); calcDataHash(pBuffer, fileSize, DATA_SCRIPTVAL); free(pBuffer); PHYSFS_seek(fileHandle, 0); //reset position success = scrvLoad(fileHandle); if (!success) debug(LOG_FATAL, "Script %s did not compile", GetLastResourceFilename()); PHYSFS_close(fileHandle); return success; }
std::string ResourceManager::getPath(const std::string &file) { // get the real path to the file const char* tmp = PHYSFS_getRealDir(file.c_str()); std::string path; // if the file is not in the search path, then its NULL if (tmp) path = std::string(tmp) + "/" + file; // if not found in search path return the default path else path = std::string(PKG_DATADIR) + std::string("data") + "/" + file; return path; }
static bool cdAudio_OpenTrack(const char *filename) { if (!music_initialized) { return false; } debug(LOG_SOUND, "called(%s)", filename); cdAudio_Stop(); if (strncasecmp(filename + strlen(filename) - 4, ".ogg", 4) == 0) { PHYSFS_file *music_file = PHYSFS_openRead(filename); debug(LOG_WZ, "Reading...[directory: %s] %s", PHYSFS_getRealDir(filename), filename); if (music_file == nullptr) { debug(LOG_ERROR, "Failed opening file [directory: %s] %s, with error %s", PHYSFS_getRealDir(filename), filename, WZ_PHYSFS_getLastError()); return false; } cdStream = sound_PlayStreamWithBuf(music_file, music_volume, cdAudio_TrackFinished, filename, bufferSize, buffer_count); if (cdStream == nullptr) { PHYSFS_close(music_file); debug(LOG_ERROR, "Failed creating audio stream for %s", filename); return false; } debug(LOG_SOUND, "successful(%s)", filename); stopping = false; return true; } return false; // unhandled }
void PageEditTeam::lazyLoad() { if(m_loaded) return; m_loaded = true; qDebug("[LAZINESS] PageEditTeam::lazyLoad()"); HatModel * hatsModel = DataManager::instance().hatModel(); for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++) HHHats[i]->setModel(hatsModel); QRegExp pngSuffix("\\.png$"); DataManager & dataMgr = DataManager::instance(); QStringList list; // voicepacks list = dataMgr.entryList("Sounds/voices", QDir::AllDirs | QDir::NoDotAndDotDot); CBVoicepack->addItems(list); QIcon dlcIcon; dlcIcon.addFile(":/res/dlcMarker.png", QSize(), QIcon::Normal, QIcon::On); dlcIcon.addFile(":/res/dlcMarkerSelected.png", QSize(), QIcon::Selected, QIcon::On); QPixmap emptySpace = QPixmap(7, 15); emptySpace.fill(QColor(0, 0, 0, 0)); QIcon notDlcIcon = QIcon(emptySpace); // forts list = dataMgr.entryList("Forts", QDir::Files, QStringList("*L.png")); foreach (QString file, list) { QString fortPath = PHYSFS_getRealDir(QString("Forts/%1").arg(file).toLocal8Bit().data()); QString fort = file.replace(QRegExp("L\\.png$"), ""); bool isDLC = !fortPath.startsWith(datadir->absolutePath()); if (isDLC) { CBFort->addItem(dlcIcon, fort, fort); } else { CBFort->addItem(notDlcIcon, fort, fort); } }
// Load a script variable values file static bool dataScriptLoadVals(const char *fileName, void **ppData) { bool success; PHYSFS_file *fileHandle; uint8_t *pBuffer; PHYSFS_sint64 fileSize = 0; *ppData = nullptr; // don't load anything if a saved game is being loaded if (saveFlag) { return true; } debug(LOG_WZ, "Loading script data %s", GetLastResourceFilename()); fileHandle = PHYSFS_openRead(fileName); debug(LOG_WZ, "Reading...[directory: %s] %s", PHYSFS_getRealDir(fileName), fileName); if (fileHandle == nullptr) { return false; } // due to the changes in r2532 we must do this routine a bit different. fileSize = PHYSFS_fileLength(fileHandle); pBuffer = (uint8_t *)malloc(fileSize * sizeof(uint8_t)); ASSERT_OR_RETURN(false, pBuffer, "Out of memory"); WZ_PHYSFS_readBytes(fileHandle, pBuffer, fileSize); calcDataHash(pBuffer, fileSize, DATA_SCRIPTVAL); free(pBuffer); PHYSFS_seek(fileHandle, 0); //reset position success = scrvLoad(fileHandle); if (!success) { debug(LOG_FATAL, "Script %s did not compile", GetLastResourceFilename()); } PHYSFS_close(fileHandle); return success; }
/* Load an anim file */ static bool dataAnimLoad(const char *fileName, void **ppData) { PHYSFS_file* fileHandle = PHYSFS_openRead(fileName); debug(LOG_WZ, "Reading...[directory: %s] %s", PHYSFS_getRealDir(fileName), fileName); if (fileHandle == NULL) { *ppData = NULL; return false; } *ppData = anim_LoadFromFile(fileHandle); PHYSFS_close(fileHandle); return *ppData != NULL; }
bool physfsFile::prepareWrite() { const char *wdir = PHYSFS_getWriteDir(); if (wdir == NULL) { LOG_MSG("PHYSFS could not fulfill write request: no write directory set."); return false; } //LOG_MSG("Goto write (%s at %i)",pname,PHYSFS_tell(fhandle)); const char *fdir = PHYSFS_getRealDir(pname); PHYSFS_uint64 pos = PHYSFS_tell(fhandle); char *slash = strrchr(pname,'/'); if (slash && slash != pname) { *slash = 0; PHYSFS_mkdir(pname); *slash = '/'; } if (strcmp(fdir,wdir)) { /* we need COW */ //LOG_MSG("COW",pname,PHYSFS_tell(fhandle)); PHYSFS_file *whandle = PHYSFS_openWrite(pname); if (whandle == NULL) { LOG_MSG("PHYSFS copy-on-write failed: %s.",PHYSFS_getLastError()); return false; } char buffer[65536]; PHYSFS_sint64 size; PHYSFS_seek(fhandle, 0); while ((size = PHYSFS_read(fhandle,buffer,1,65536)) > 0) { if (PHYSFS_write(whandle,buffer,1,(PHYSFS_uint32)size) != size) { LOG_MSG("PHYSFS copy-on-write failed: %s.",PHYSFS_getLastError()); PHYSFS_close(whandle); return false; } } PHYSFS_seek(whandle, pos); PHYSFS_close(fhandle); fhandle = whandle; } else { // megayuck - physfs on posix platforms uses O_APPEND. We illegally access the fd directly and clear that flag. //LOG_MSG("noCOW",pname,PHYSFS_tell(fhandle)); PHYSFS_close(fhandle); fhandle = PHYSFS_openAppend(pname); #ifndef WIN32 fcntl(**(int**)fhandle->opaque,F_SETFL,0); #endif PHYSFS_seek(fhandle, pos); } return true; }
void ThemeModel::loadThemes() { beginResetModel(); DataManager & datamgr = DataManager::instance(); QStringList themes = datamgr.entryList("Themes", QDir::AllDirs | QDir::NoDotAndDotDot); m_data.clear(); #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) m_data.reserve(themes.size()); #endif foreach (QString theme, themes) { // themes without icon are supposed to be hidden QString iconpath = QString("physfs://Themes/%1/icon.png").arg(theme); if (!QFile::exists(iconpath)) continue; QMap<int, QVariant> dataset; // detect if theme is dlc QString themeDir = PHYSFS_getRealDir(QString("Themes/%1/icon.png").arg(theme).toLocal8Bit().data()); bool isDLC = !themeDir.startsWith(datadir->absolutePath()); dataset.insert(IsDlcRole, isDLC); // set icon path dataset.insert(IconPathRole, iconpath); // set name dataset.insert(ActualNameRole, theme); // set displayed name dataset.insert(Qt::DisplayRole, (isDLC ? "*" : "") + theme); // load and set preview icon QIcon preview(QString("physfs://Themes/%1/[email protected]").arg(theme)); dataset.insert(Qt::DecorationRole, preview); m_data.append(dataset); }
static int cmd_getrealdir(char *args) { const char *rc; if (*args == '\"') { args++; args[strlen(args) - 1] = '\0'; } /* if */ rc = PHYSFS_getRealDir(args); if (rc) printf("Found at [%s].\n", rc); else printf("Not found.\n"); return(1); } /* cmd_getrealdir */
/* Load an audio config file */ static bool dataAnimCfgLoad(const char *fileName, void **ppData) { bool success; PHYSFS_file* fileHandle = PHYSFS_openRead(fileName); *ppData = NULL; debug(LOG_WZ, "Reading...[directory: %s] %s", PHYSFS_getRealDir(fileName), fileName); if (fileHandle == NULL) { return false; } success = ParseResourceFile(fileHandle); PHYSFS_close(fileHandle); return success; }
int PHYSFSX_getRealPath(const char *stdPath, char *realPath) { const char *realDir = PHYSFS_getRealDir(stdPath); const char *sep = PHYSFS_getDirSeparator(); char *p; if (!realDir) { realDir = PHYSFS_getWriteDir(); if (!realDir) return 0; } strncpy(realPath, realDir, PATH_MAX - 1); if (strlen(realPath) >= strlen(sep)) { p = realPath + strlen(realPath) - strlen(sep); if (strcmp(p, sep)) // no sep at end of realPath strncat(realPath, sep, PATH_MAX - 1 - strlen(realPath)); } if (strlen(stdPath) >= 1) if (*stdPath == '/') stdPath++; while (*stdPath) { if (*stdPath == '/') strncat(realPath, sep, PATH_MAX - 1 - strlen(realPath)); else { if (strlen(realPath) < PATH_MAX - 2) { p = realPath + strlen(realPath); p[0] = *stdPath; p[1] = '\0'; } } stdPath++; } return 1; }
std::string ResourceManager::getPath(const std::string &file) { // get the real path to the file const char* tmp = PHYSFS_getRealDir(file.c_str()); std::string path; // if the file is not in the search path, then its NULL if (tmp) { path = std::string(tmp) + "/" + file; } else { // if not found in search path return the default path path = Client::getPackageDirectory() + "/" + file; } return path; }
// Read shader into text buffer static char *readShaderBuf(const char *name) { PHYSFS_file *fp; int filesize; char *buffer; fp = PHYSFS_openRead(name); debug(LOG_3D, "Reading...[directory: %s] %s", PHYSFS_getRealDir(name), name); ASSERT_OR_RETURN(0, fp != NULL, "Could not open %s", name); filesize = PHYSFS_fileLength(fp); buffer = (char *)malloc(filesize + 1); if (buffer) { PHYSFS_read(fp, buffer, 1, filesize); buffer[filesize] = '\0'; } PHYSFS_close(fp); return buffer; }
QStringList DataManager::entryList( const QString & subDirectory, QDir::Filters filters, const QStringList & nameFilters, bool withDLC ) const { QDir tmpDir(QString("physfs://%1").arg(subDirectory)); QStringList result = tmpDir.entryList(nameFilters, filters); // sort case-insensitive QMap<QString, QString> sortedFileNames; QString absolutePath = datadir->absolutePath().toLocal8Bit().data(); foreach ( QString fn, result) { // Filter out DLC entries if desired QString realDir = PHYSFS_getRealDir(QString(subDirectory + "/" + fn).toLocal8Bit().data()); if(withDLC || realDir == absolutePath) sortedFileNames.insert(fn.toLower(), fn); }
vsString vsFile::GetFullFilename(const vsString &filename_in) { #if TARGET_OS_IPHONE vsString filename = filename_in; // find the slash, if any. int pos = filename.rfind("/"); if ( pos != vsString::npos ) { filename.erase(0,pos+1); } vsString result = vsFormatString("./%s",filename.c_str()); return result; #else vsString filename(filename_in); vsString dir = PHYSFS_getRealDir( filename.c_str() ); return dir + "/" + filename; #endif }
std::vector<std::string> geDirList(const std::string_view path, const std::string_view rootPath) { std::vector<std::string> vecDirs; auto dirs = PHYSFS_enumerateFiles(path.data()); if (dirs != nullptr) { PHYSFS_Stat fileStat; for (char** dir = dirs; *dir != nullptr; dir++) { if (PHYSFS_stat(*dir, &fileStat) == 0) { continue; } if (fileStat.filetype != PHYSFS_FILETYPE_DIRECTORY) { continue; } if (**dir == '.') { continue; } if (rootPath.empty() == false) { auto realDir = PHYSFS_getRealDir(*dir); if (realDir != nullptr) { if (rootPath != realDir) { continue; } } } vecDirs.push_back(*dir); } PHYSFS_freeList(dirs); } return vecDirs; }
void Sound::playMusic(const std::string& name) { getConfig()->playSongName = name; if(!audioOpen) return; musicFile = name; if(getConfig()->musicEnabled) { if(currentMusic) { Mix_FreeMusic(currentMusic); currentMusic = 0; } if(musicFile == "") return; // transform filename... because the music commands in SDL_Mixer don't // support reading callbacks to read from physfs directly std::string filename = "music/"; filename += name; const char* dir = PHYSFS_getRealDir(filename.c_str()); if(dir == 0) { std::cerr << "Warning couldn't find music file '" << name << "'.\n"; return; } filename = dir; filename += "/music/"; filename += name; currentMusic = Mix_LoadMUS(filename.c_str()); if(currentMusic == 0) { std::cerr << "Couldn't load music file '" << filename << "': " << SDL_GetError() << "\n"; return; } Mix_PlayMusic(currentMusic, -1); } }
/* Load a string resource file */ bool strresLoad(STR_RES* psRes, const char* fileName) { bool retval; lexerinput_t input; input.type = LEXINPUT_PHYSFS; input.input.physfsfile = PHYSFS_openRead(fileName); debug(LOG_WZ, "Reading...[directory %s] %s", PHYSFS_getRealDir(fileName), fileName); if (!input.input.physfsfile) { debug(LOG_ERROR, "strresLoadFile: PHYSFS_openRead(\"%s\") failed with error: %s\n", fileName, PHYSFS_getLastError()); return false; } strres_set_extra(&input); retval = (strres_parse(psRes) == 0); strres_lex_destroy(); PHYSFS_close(input.input.physfsfile); return retval; }
void AddonManager::add_installed_archive(const std::string& archive, const std::string& md5) { const char* realdir = PHYSFS_getRealDir(archive.c_str()); if (!realdir) { log_warning << "PHYSFS_getRealDir() failed for " << archive << ": " << PHYSFS_getLastError() << std::endl; } else { std::string os_path = FileSystem::join(realdir, archive); PHYSFS_mount(os_path.c_str(), NULL, 0); std::string nfo_filename = scan_for_info(os_path); if (nfo_filename.empty()) { log_warning << "Couldn't find .nfo file for " << os_path << std::endl; } else { try { std::unique_ptr<Addon> addon = Addon::parse(nfo_filename); addon->set_install_filename(os_path, md5); m_installed_addons.push_back(std::move(addon)); } catch (const std::runtime_error& e) { log_warning << "Could not load add-on info for " << archive << ": " << e.what() << std::endl; } } PHYSFS_unmount(os_path.c_str()); } }
/******************************** * EntityCompiler_TemporaryFile * Copy a file to temporary file for compiling on external compiler @ filename: @ origdir: @ fname: - returns complete file path */ gchar * EntityCompiler_TemporaryFile( gchar * filename, gboolean * remove ) { const gchar * tmpl = "mXXXXXX.p"; const gchar * dir = NULL; gchar * filepath = NULL; gboolean is_package_entity = FALSE; dir = PHYSFS_getRealDir(filename); if ( dir == NULL ) is_package_entity = TRUE; else if ( !g_file_test(dir, G_FILE_TEST_IS_DIR) || g_str_has_suffix(dir, ".package") ) is_package_entity = TRUE; if ( mokoiUsingPackage && is_package_entity ) { gint fd = g_file_open_tmp( tmpl, &filepath, NULL ); if ( fd == -1 ) { g_warning("EntityCompiler: Can not create a temp file for %s\n", filename); return NULL; } else { gchar * content = NULL; gsize length = 0; Meg_file_get_contents(filename, &content, &length, NULL); write(fd, content, length); close(fd); } } return filepath; }
bool buildMapList() { if (!loadLevFile("gamedesc.lev", mod_campaign, false, NULL)) { return false; } loadLevFile("addon.lev", mod_multiplay, false, NULL); MapFileList realFileNames = listMapFiles(); for (MapFileList::iterator realFileName = realFileNames.begin(); realFileName != realFileNames.end(); ++realFileName) { std::string realFilePathAndName = PHYSFS_getRealDir(realFileName->c_str()) + *realFileName; PHYSFS_addToSearchPath(realFilePathAndName.c_str(), PHYSFS_APPEND); char **filelist = PHYSFS_enumerateFiles(""); for (char **file = filelist; *file != NULL; ++file) { size_t len = strlen(*file); if (len > 10 && !strcasecmp(*file + (len - 10), ".addon.lev")) // Do not add addon.lev again { loadLevFile(*file, mod_multiplay, true, realFileName->c_str()); } // add support for X player maps using a new name to prevent conflicts. if (len > 13 && !strcasecmp(*file + (len - 13), ".xplayers.lev")) { loadLevFile(*file, mod_multiplay, true, realFileName->c_str()); } } PHYSFS_freeList(filelist); PHYSFS_removeFromSearchPath(realFilePathAndName.c_str()); } return true; }