(svn r9560) -Codechange: add support for multiple 'base' directories for newgrf searching.
authorrubidium
Wed, 04 Apr 2007 12:03:10 +0000
changeset 6920 ee15b916f758
parent 6919 339210ecccd3
child 6921 1771ee81a39a
(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
src/network/network_udp.cpp
src/newgrf.cpp
src/newgrf_config.cpp
src/newgrf_config.h
src/win32.cpp
--- a/src/fileio.cpp	Wed Apr 04 04:08:47 2007 +0000
+++ b/src/fileio.cpp	Wed Apr 04 12:03:10 2007 +0000
@@ -170,7 +170,7 @@
 	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 *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 @@
 #if defined(SECOND_DATA_DIR)
 	_paths.second_data_dir = MallocT<char>(MAX_PATH);
 	ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH);
+#else
+	_paths.second_data_dir = NULL;
 #endif
 
 #if defined(USE_HOMEDIR)
--- a/src/network/network_udp.cpp	Wed Apr 04 04:08:47 2007 +0000
+++ b/src/network/network_udp.cpp	Wed Apr 04 12:03:10 2007 +0000
@@ -391,12 +391,13 @@
 		/* 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);
 }
--- a/src/newgrf.cpp	Wed Apr 04 04:08:47 2007 +0000
+++ b/src/newgrf.cpp	Wed Apr 04 12:03:10 2007 +0000
@@ -4305,7 +4305,7 @@
 
 	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 @@
 
 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 @@
 			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);
--- a/src/newgrf_config.cpp	Wed Apr 04 04:08:47 2007 +0000
+++ b/src/newgrf_config.cpp	Wed Apr 04 12:03:10 2007 +0000
@@ -35,14 +35,12 @@
 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 @@
 /* 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 @@
 	/* 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 @@
 	for (; src != NULL; src = src->next) {
 		GRFConfig *c = CallocT<GRFConfig>(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<GRFError>(1);
 			memcpy(c->error, src->error, sizeof(GRFError));
 		}
@@ -255,7 +255,9 @@
 			 * 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 @@
 	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 @@
 
 		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<GRFConfig>(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 @@
 					 * 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;
+					}
 				}
+			} else {
+				added = false;
+			}
 
-				num++;
-			} else {
+			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 @@
 	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);
 }
 
--- a/src/newgrf_config.h	Wed Apr 04 04:08:47 2007 +0000
+++ b/src/newgrf_config.h	Wed Apr 04 12:03:10 2007 +0000
@@ -45,6 +45,7 @@
 
 struct GRFConfig : public GRFIdentifier {
 	char *filename;
+	char *full_path;
 	char *name;
 	char *info;
 	GRFError *error;
--- a/src/win32.cpp	Wed Apr 04 04:08:47 2007 +0000
+++ b/src/win32.cpp	Wed Apr 04 12:03:10 2007 +0000
@@ -946,6 +946,7 @@
 void DetermineBasePaths(const char *exe)
 {
 	_paths.personal_dir = _paths.game_data_dir = MallocT<char>(MAX_PATH);
+	_paths.second_data_dir = NULL;
 #if defined(UNICODE)
 	TCHAR path[MAX_PATH];
 	GetCurrentDirectory(MAX_PATH - 1, path);