From db915888459efb46775299c84e0a78ffa23e6076 Mon Sep 17 00:00:00 2001 From: rubidium Date: Wed, 4 Apr 2007 12:03:10 +0000 Subject: [PATCH] (svn r9560) -Codechange: add support for multiple 'base' directories for newgrf searching. -Codechange: do not add duplicate files to the newgrf list. --- src/fileio.cpp | 12 ++++++--- src/network/network_udp.cpp | 11 +++++---- src/newgrf.cpp | 6 ++--- src/newgrf_config.cpp | 49 +++++++++++++++++++++++-------------- src/newgrf_config.h | 1 + src/win32.cpp | 1 + 6 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/fileio.cpp b/src/fileio.cpp index 8ab41b31a1..3a5a023222 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -170,7 +170,7 @@ void FioOpenFile(int slot, const char *filename) FioFreeHandle(); #endif /* LIMITED_FDS */ f = FioFOpenFile(filename); - if (f == NULL) error("Cannot open file '%s%s'", _paths.data_dir, filename); + if (f == NULL) error("Cannot open file '%s'", filename); FioCloseFile(slot); // if file was opened before, close it _fio.handles[slot] = f; @@ -206,12 +206,16 @@ FILE *FioFOpenFile(const char *filename) FILE *f; char buf[MAX_PATH]; - snprintf(buf, lengthof(buf), "%s%s", _paths.data_dir, filename); + if (strrchr(filename, PATHSEPCHAR) == NULL) { + snprintf(buf, lengthof(buf), "%s%s", _paths.data_dir, filename); + } else { + ttd_strlcpy(buf, filename, lengthof(buf)); + } f = fopen(buf, "rb"); #if !defined(WIN32) if (f == NULL) { - strtolower(buf + strlen(_paths.data_dir) - 1); + strtolower(strrchr(buf, PATHSEPCHAR)); f = fopen(buf, "rb"); #if defined SECOND_DATA_DIR @@ -308,6 +312,8 @@ void DetermineBasePaths(const char *exe) #if defined(SECOND_DATA_DIR) _paths.second_data_dir = MallocT(MAX_PATH); ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH); +#else + _paths.second_data_dir = NULL; #endif #if defined(USE_HOMEDIR) diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 063a1aef22..4031f2f6eb 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -391,12 +391,13 @@ void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFCo /* Don't know the GRF, so mark game incompatible and the (possibly) * already resolved name for this GRF (another server has sent the * name of the GRF already */ - config->name = FindUnknownGRFName(config->grfid, config->md5sum, true); - config->status = GCS_NOT_FOUND; + config->name = FindUnknownGRFName(config->grfid, config->md5sum, true); + config->status = GCS_NOT_FOUND; } else { - config->filename = f->filename; - config->name = f->name; - config->info = f->info; + config->filename = f->filename; + config->full_path = f->full_path; + config->name = f->name; + config->info = f->info; } SETBIT(config->flags, GCF_COPY); } diff --git a/src/newgrf.cpp b/src/newgrf.cpp index d83634188d..a2dd255cb8 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4305,7 +4305,7 @@ static void InitNewGRFFile(const GRFConfig *config, int sprite_offset) if (newfile == NULL) error ("Out of memory"); - newfile->filename = strdup(config->filename); + newfile->filename = strdup(config->full_path); newfile->sprite_offset = sprite_offset; /* Copy the initial parameter list */ @@ -4583,7 +4583,7 @@ static void DecodeSpecialSprite(uint num, GrfLoadingStage stage) void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage) { - const char *filename = config->filename; + const char *filename = config->full_path; uint16 num; /* A .grf file is activated only if it was active when the game was @@ -4699,7 +4699,7 @@ void LoadNewGRF(uint load_index, uint file_index) if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue; /* @todo usererror() */ - if (!FioCheckFileExists(c->filename)) error("NewGRF file is missing '%s'", c->filename); + if (!FileExists(c->full_path)) error("NewGRF file is missing '%s'", c->filename); if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid); LoadNewGRFFile(c, slot++, stage); diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index 44ffbf8ce0..60563ba35a 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -35,14 +35,12 @@ GRFConfig *_grfconfig_static; static bool CalcGRFMD5Sum(GRFConfig *config) { FILE *f; - char filename[MAX_PATH]; md5_state_t md5state; md5_byte_t buffer[1024]; size_t len; /* open the file */ - snprintf(filename, lengthof(filename), "%s%s", _paths.data_dir, config->filename); - f = fopen(filename, "rb"); + f = fopen(config->full_path, "rb"); if (f == NULL) return false; /* calculate md5sum */ @@ -61,7 +59,7 @@ static bool CalcGRFMD5Sum(GRFConfig *config) /* Find the GRFID and calculate the md5sum */ bool FillGRFDetails(GRFConfig *config, bool is_static) { - if (!FioCheckFileExists(config->filename)) { + if (!FileExists(config->full_path)) { config->status = GCS_NOT_FOUND; return false; } @@ -91,6 +89,7 @@ void ClearGRFConfig(GRFConfig **config) /* GCF_COPY as in NOT strdupped/alloced the filename, name and info */ if (!HASBIT((*config)->flags, GCF_COPY)) { free((*config)->filename); + free((*config)->full_path); free((*config)->name); free((*config)->info); free((*config)->error); @@ -123,10 +122,11 @@ GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src) for (; src != NULL; src = src->next) { GRFConfig *c = CallocT(1); *c = *src; - if (src->filename != NULL) c->filename = strdup(src->filename); - if (src->name != NULL) c->name = strdup(src->name); - if (src->info != NULL) c->info = strdup(src->info); - if (src->error != NULL) { + if (src->filename != NULL) c->filename = strdup(src->filename); + if (src->full_path != NULL) c->full_path = strdup(src->full_path); + if (src->name != NULL) c->name = strdup(src->name); + if (src->info != NULL) c->info = strdup(src->info); + if (src->error != NULL) { c->error = CallocT(1); memcpy(c->error, src->error, sizeof(GRFError)); } @@ -255,7 +255,9 @@ compatible_grf: * already a local one, so there is no need to replace it. */ if (!HASBIT(c->flags, GCF_COPY)) { free(c->filename); + free(c->full_path); c->filename = strdup(f->filename); + c->full_path = strdup(f->full_path); memcpy(c->md5sum, f->md5sum, sizeof(c->md5sum)); if (c->name == NULL && f->name != NULL) c->name = strdup(f->name); if (c->info == NULL && f->info != NULL) c->info = strdup(f->info); @@ -278,7 +280,7 @@ static uint ScanPath(const char *path) struct dirent *dirent; DIR *dir; - if ((dir = ttd_opendir(path)) == NULL) return 0; + if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0; while ((dirent = readdir(dir)) != NULL) { const char *d_name = FS2OTTD(dirent->d_name); @@ -286,24 +288,26 @@ static uint ScanPath(const char *path) if (!FiosIsValidFile(path, dirent, &sb)) continue; - snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, d_name); + snprintf(filename, lengthof(filename), "%s%s", path, d_name); if (sb.st_mode & S_IFDIR) { /* Directory */ if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue; + AppendPathSeparator(filename, lengthof(filename)); num += ScanPath(filename); } else if (sb.st_mode & S_IFREG) { /* File */ char *ext = strrchr(filename, '.'); - char *file = filename + strlen(_paths.data_dir) + 1; // Crop base path /* If no extension or extension isn't .grf, skip the file */ if (ext == NULL) continue; if (strcasecmp(ext, ".grf") != 0) continue; GRFConfig *c = CallocT(1); - c->filename = strdup(file); + c->full_path = strdup(filename); + c->filename = strdup(strrchr(filename, PATHSEPCHAR) + 1); + bool added = true; if (FillGRFDetails(c, false)) { if (_all_grfs == NULL) { _all_grfs = c; @@ -312,20 +316,28 @@ static uint ScanPath(const char *path) * name, so the list is sorted as we go along */ GRFConfig **pd, *d; for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) { + if (c->grfid == d->grfid && memcmp(c->md5sum, d->md5sum, sizeof(c->md5sum)) == 0) added = false; if (strcasecmp(c->name, d->name) <= 0) break; } - c->next = d; - *pd = c; + if (added) { + c->next = d; + *pd = c; + } } - - num++; } else { + added = false; + } + + if (!added) { /* File couldn't be opened, or is either not a NewGRF or is a - * 'system' NewGRF, so forget about it. */ + * 'system' NewGRF or it's already known, so forget about it. */ free(c->filename); + free(c->full_path); free(c->name); free(c->info); free(c); + } else { + num++; } } } @@ -344,7 +356,8 @@ void ScanNewGRFFiles() ClearGRFConfigList(&_all_grfs); DEBUG(grf, 1, "Scanning for NewGRFs"); - num = ScanPath(_paths.data_dir); + num = ScanPath(_paths.data_dir); + num += ScanPath(_paths.second_data_dir); DEBUG(grf, 1, "Scan complete, found %d files", num); } diff --git a/src/newgrf_config.h b/src/newgrf_config.h index a3ed63ec5d..491c7ca886 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -45,6 +45,7 @@ struct GRFError { struct GRFConfig : public GRFIdentifier { char *filename; + char *full_path; char *name; char *info; GRFError *error; diff --git a/src/win32.cpp b/src/win32.cpp index 19f465d314..45a3489bc6 100644 --- a/src/win32.cpp +++ b/src/win32.cpp @@ -946,6 +946,7 @@ void GetCurrentDirectoryW(int length, wchar_t *path) void DetermineBasePaths(const char *exe) { _paths.personal_dir = _paths.game_data_dir = MallocT(MAX_PATH); + _paths.second_data_dir = NULL; #if defined(UNICODE) TCHAR path[MAX_PATH]; GetCurrentDirectory(MAX_PATH - 1, path);