diff --git a/readme.txt b/readme.txt --- a/readme.txt +++ b/readme.txt @@ -253,6 +253,9 @@ The required 3rd party files listed in t as well as other non-compulsory extensions (NewGRFs, AI, heightmaps, scenarios) can be placed in a few different locations: 1. The current working directory (from where you started OpenTTD) + For non-Windows operating systems OpenTTD will not scan for files in this + directory if it is your personal directory, i.e. "~/", or when it is the + root directory, i.e. "/". 2. Your personal directory Windows: C:\My Documents (95, 98, ME) C:\Documents and Settings\\My Documents\OpenTTD (2000, XP) diff --git a/src/fileio.cpp b/src/fileio.cpp --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -44,7 +44,7 @@ struct Fio { FILE *handles[MAX_FILE_SLOTS]; ///< array of file handles we can have open byte buffer_start[FIO_BUFFER_SIZE]; ///< local buffer when read from file const char *filenames[MAX_FILE_SLOTS]; ///< array of filenames we (should) have open - char *shortnames[MAX_FILE_SLOTS];///< array of short names for spriteloader's use + char *shortnames[MAX_FILE_SLOTS]; ///< array of short names for spriteloader's use #if defined(LIMITED_FDS) uint open_handles; ///< current amount of open handles uint usage_count[MAX_FILE_SLOTS]; ///< count how many times this file has been opened @@ -53,6 +53,9 @@ struct Fio { static Fio _fio; +/** Whether the working directory should be scanned. */ +static bool _do_scan_working_directory = true; + /* Get current position in file */ size_t FioGetPos() { @@ -876,6 +879,33 @@ void ChangeWorkingDirectory(const char * } /** + * Whether we should scan the working directory. + * It should not be scanned if it's the root or + * the home directory as in both cases a big data + * directory can cause huge amounts of unrelated + * files scanned. Furthermore there are nearly no + * use cases for the home/root directory to have + * OpenTTD directories. + * @return true if it should be scanned. + */ +bool DoScanWorkingDirectory() +{ + /* No working directory, so nothing to do. */ + if (_searchpaths[SP_WORKING_DIR] == NULL) return false; + + /* Working directory is root, so do nothing. */ + if (strcmp(_searchpaths[SP_WORKING_DIR], PATHSEP) == 0) return false; + + /* No personal/home directory, so the working directory won't be that. */ + if (_searchpaths[SP_PERSONAL_DIR] == NULL) return true; + + char tmp[MAX_PATH]; + snprintf(tmp, lengthof(tmp), "%s%s", _searchpaths[SP_WORKING_DIR], PERSONAL_DIR); + AppendPathSeparator(tmp, MAX_PATH); + return strcmp(tmp, _searchpaths[SP_PERSONAL_DIR]) != 0; +} + +/** * Determine the base (personal dir and game data dir) paths * @param exe the path to the executable */ @@ -920,6 +950,8 @@ void DetermineBasePaths(const char *exe) _searchpaths[SP_WORKING_DIR] = strdup(tmp); #endif + _do_scan_working_directory = DoScanWorkingDirectory(); + /* Change the working directory to that one of the executable */ ChangeWorkingDirectory(exe); if (getcwd(tmp, MAX_PATH) == NULL) *tmp = '\0'; @@ -960,7 +992,10 @@ void DeterminePaths(const char *exe) DetermineBasePaths(exe); Searchpath sp; - FOR_ALL_SEARCHPATHS(sp) DEBUG(misc, 4, "%s added as search path", _searchpaths[sp]); + FOR_ALL_SEARCHPATHS(sp) { + if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue; + DEBUG(misc, 4, "%s added as search path", _searchpaths[sp]); + } if (_config_file != NULL) { _personal_dir = strdup(_config_file); @@ -1178,6 +1213,9 @@ uint FileScanner::Scan(const char *exten uint num = 0; FOR_ALL_SEARCHPATHS(sp) { + /* Don't search in the working directory */ + if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue; + FioAppendDirectory(path, MAX_PATH, sp, sd); num += ScanPath(this, extension, path, strlen(path), recursive); }