src/newgrf_config.cpp
branchgamebalance
changeset 9908 0fa543611bbe
parent 9906 6f41b8713b65
child 9909 dce9a6923bb7
equal deleted inserted replaced
9907:3b068c3a1c74 9908:0fa543611bbe
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 /** @file newgfr_config.cpp */
     3 /** @file newgrf_config.cpp */
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "functions.h"
     7 #include "functions.h"
     8 #include "macros.h"
     8 #include "macros.h"
    33 
    33 
    34 /* Calculate the MD5 Sum for a GRF */
    34 /* Calculate the MD5 Sum for a GRF */
    35 static bool CalcGRFMD5Sum(GRFConfig *config)
    35 static bool CalcGRFMD5Sum(GRFConfig *config)
    36 {
    36 {
    37 	FILE *f;
    37 	FILE *f;
    38 	char filename[MAX_PATH];
       
    39 	md5_state_t md5state;
    38 	md5_state_t md5state;
    40 	md5_byte_t buffer[1024];
    39 	md5_byte_t buffer[1024];
    41 	size_t len;
    40 	size_t len;
    42 
    41 
    43 	/* open the file */
    42 	/* open the file */
    44 	snprintf(filename, lengthof(filename), "%s%s", _paths.data_dir, config->filename);
    43 	f = fopen(config->full_path, "rb");
    45 	f = fopen(filename, "rb");
       
    46 	if (f == NULL) return false;
    44 	if (f == NULL) return false;
    47 
    45 
    48 	/* calculate md5sum */
    46 	/* calculate md5sum */
    49 	md5_init(&md5state);
    47 	md5_init(&md5state);
    50 	while ((len = fread(buffer, 1, sizeof(buffer), f)) != 0) {
    48 	while ((len = fread(buffer, 1, sizeof(buffer), f)) != 0) {
    59 
    57 
    60 
    58 
    61 /* Find the GRFID and calculate the md5sum */
    59 /* Find the GRFID and calculate the md5sum */
    62 bool FillGRFDetails(GRFConfig *config, bool is_static)
    60 bool FillGRFDetails(GRFConfig *config, bool is_static)
    63 {
    61 {
    64 	if (!FioCheckFileExists(config->filename)) {
    62 	if (!FileExists(config->full_path)) {
    65 		config->status = GCS_NOT_FOUND;
    63 		config->status = GCS_NOT_FOUND;
    66 		return false;
    64 		return false;
       
    65 	}
       
    66 
       
    67 	if (config->filename == NULL) {
       
    68 		config->filename = strdup(strrchr(config->full_path, PATHSEPCHAR) + 1);
    67 	}
    69 	}
    68 
    70 
    69 	/* Find and load the Action 8 information */
    71 	/* Find and load the Action 8 information */
    70 	/* 62 is the last file slot before sample.cat.
    72 	/* 62 is the last file slot before sample.cat.
    71 	 * Should perhaps be some "don't care" value */
    73 	 * Should perhaps be some "don't care" value */
    89 void ClearGRFConfig(GRFConfig **config)
    91 void ClearGRFConfig(GRFConfig **config)
    90 {
    92 {
    91 	/* GCF_COPY as in NOT strdupped/alloced the filename, name and info */
    93 	/* GCF_COPY as in NOT strdupped/alloced the filename, name and info */
    92 	if (!HASBIT((*config)->flags, GCF_COPY)) {
    94 	if (!HASBIT((*config)->flags, GCF_COPY)) {
    93 		free((*config)->filename);
    95 		free((*config)->filename);
       
    96 		free((*config)->full_path);
    94 		free((*config)->name);
    97 		free((*config)->name);
    95 		free((*config)->info);
    98 		free((*config)->info);
    96 		free((*config)->error);
    99 		free((*config)->error);
    97 	}
   100 	}
    98 	free(*config);
   101 	free(*config);
   121 	/* Clear destination as it will be overwritten */
   124 	/* Clear destination as it will be overwritten */
   122 	ClearGRFConfigList(dst);
   125 	ClearGRFConfigList(dst);
   123 	for (; src != NULL; src = src->next) {
   126 	for (; src != NULL; src = src->next) {
   124 		GRFConfig *c = CallocT<GRFConfig>(1);
   127 		GRFConfig *c = CallocT<GRFConfig>(1);
   125 		*c = *src;
   128 		*c = *src;
   126 		if (src->filename != NULL) c->filename = strdup(src->filename);
   129 		if (src->filename  != NULL) c->filename  = strdup(src->filename);
   127 		if (src->name     != NULL) c->name     = strdup(src->name);
   130 		if (src->full_path != NULL) c->full_path = strdup(src->full_path);
   128 		if (src->info     != NULL) c->info     = strdup(src->info);
   131 		if (src->name      != NULL) c->name      = strdup(src->name);
   129 		if (src->error    != NULL) {
   132 		if (src->info      != NULL) c->info      = strdup(src->info);
       
   133 		if (src->error     != NULL) {
   130 			c->error = CallocT<GRFError>(1);
   134 			c->error = CallocT<GRFError>(1);
   131 			memcpy(c->error, src->error, sizeof(GRFError));
   135 			memcpy(c->error, src->error, sizeof(GRFError));
   132 		}
   136 		}
   133 
   137 
   134 		*dst = c;
   138 		*dst = c;
   253 			 * in any case and set the name and info when it is not set already.
   257 			 * in any case and set the name and info when it is not set already.
   254 			 * When the GCF_COPY flag is set, it is certain that the filename is
   258 			 * When the GCF_COPY flag is set, it is certain that the filename is
   255 			 * already a local one, so there is no need to replace it. */
   259 			 * already a local one, so there is no need to replace it. */
   256 			if (!HASBIT(c->flags, GCF_COPY)) {
   260 			if (!HASBIT(c->flags, GCF_COPY)) {
   257 				free(c->filename);
   261 				free(c->filename);
       
   262 				free(c->full_path);
   258 				c->filename = strdup(f->filename);
   263 				c->filename = strdup(f->filename);
       
   264 				c->full_path = strdup(f->full_path);
   259 				memcpy(c->md5sum, f->md5sum, sizeof(c->md5sum));
   265 				memcpy(c->md5sum, f->md5sum, sizeof(c->md5sum));
   260 				if (c->name == NULL && f->name != NULL) c->name = strdup(f->name);
   266 				if (c->name == NULL && f->name != NULL) c->name = strdup(f->name);
   261 				if (c->info == NULL && f->info != NULL) c->info = strdup(f->info);
   267 				if (c->info == NULL && f->info != NULL) c->info = strdup(f->info);
   262 				c->error = NULL;
   268 				c->error = NULL;
   263 			}
   269 			}
   276 	uint num = 0;
   282 	uint num = 0;
   277 	struct stat sb;
   283 	struct stat sb;
   278 	struct dirent *dirent;
   284 	struct dirent *dirent;
   279 	DIR *dir;
   285 	DIR *dir;
   280 
   286 
   281 	if ((dir = ttd_opendir(path)) == NULL) return 0;
   287 	if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0;
   282 
   288 
   283 	while ((dirent = readdir(dir)) != NULL) {
   289 	while ((dirent = readdir(dir)) != NULL) {
   284 		const char *d_name = FS2OTTD(dirent->d_name);
   290 		const char *d_name = FS2OTTD(dirent->d_name);
   285 		char filename[MAX_PATH];
   291 		char filename[MAX_PATH];
   286 
   292 
   287 		if (!FiosIsValidFile(path, dirent, &sb)) continue;
   293 		if (!FiosIsValidFile(path, dirent, &sb)) continue;
   288 
   294 
   289 		snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, d_name);
   295 		snprintf(filename, lengthof(filename), "%s%s", path, d_name);
   290 
   296 
   291 		if (sb.st_mode & S_IFDIR) {
   297 		if (sb.st_mode & S_IFDIR) {
   292 			/* Directory */
   298 			/* Directory */
   293 			if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
   299 			if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
       
   300 			AppendPathSeparator(filename, lengthof(filename));
   294 			num += ScanPath(filename);
   301 			num += ScanPath(filename);
   295 		} else if (sb.st_mode & S_IFREG) {
   302 		} else if (sb.st_mode & S_IFREG) {
   296 			/* File */
   303 			/* File */
   297 			char *ext = strrchr(filename, '.');
   304 			char *ext = strrchr(filename, '.');
   298 			char *file = filename + strlen(_paths.data_dir) + 1; // Crop base path
       
   299 
   305 
   300 			/* If no extension or extension isn't .grf, skip the file */
   306 			/* If no extension or extension isn't .grf, skip the file */
   301 			if (ext == NULL) continue;
   307 			if (ext == NULL) continue;
   302 			if (strcasecmp(ext, ".grf") != 0) continue;
   308 			if (strcasecmp(ext, ".grf") != 0) continue;
   303 
   309 
   304 			GRFConfig *c = CallocT<GRFConfig>(1);
   310 			GRFConfig *c = CallocT<GRFConfig>(1);
   305 			c->filename = strdup(file);
   311 			c->full_path = strdup(filename);
   306 
   312 
       
   313 			bool added = true;
   307 			if (FillGRFDetails(c, false)) {
   314 			if (FillGRFDetails(c, false)) {
   308 				if (_all_grfs == NULL) {
   315 				if (_all_grfs == NULL) {
   309 					_all_grfs = c;
   316 					_all_grfs = c;
   310 				} else {
   317 				} else {
   311 					/* Insert file into list at a position determined by its
   318 					/* Insert file into list at a position determined by its
   312 					 * name, so the list is sorted as we go along */
   319 					 * name, so the list is sorted as we go along */
   313 					GRFConfig **pd, *d;
   320 					GRFConfig **pd, *d;
   314 					for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) {
   321 					for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) {
       
   322 						if (c->grfid == d->grfid && memcmp(c->md5sum, d->md5sum, sizeof(c->md5sum)) == 0) added = false;
   315 						if (strcasecmp(c->name, d->name) <= 0) break;
   323 						if (strcasecmp(c->name, d->name) <= 0) break;
   316 					}
   324 					}
   317 					c->next = d;
   325 					if (added) {
   318 					*pd = c;
   326 						c->next = d;
       
   327 						*pd = c;
       
   328 					}
   319 				}
   329 				}
   320 
       
   321 				num++;
       
   322 			} else {
   330 			} else {
       
   331 				added = false;
       
   332 			}
       
   333 
       
   334 			if (!added) {
   323 				/* File couldn't be opened, or is either not a NewGRF or is a
   335 				/* File couldn't be opened, or is either not a NewGRF or is a
   324 				 * 'system' NewGRF, so forget about it. */
   336 				 * 'system' NewGRF or it's already known, so forget about it. */
   325 				free(c->filename);
   337 				free(c->filename);
       
   338 				free(c->full_path);
   326 				free(c->name);
   339 				free(c->name);
   327 				free(c->info);
   340 				free(c->info);
   328 				free(c);
   341 				free(c);
       
   342 			} else {
       
   343 				num++;
   329 			}
   344 			}
   330 		}
   345 		}
   331 	}
   346 	}
   332 
   347 
   333 	closedir(dir);
   348 	closedir(dir);
   342 	uint num;
   357 	uint num;
   343 
   358 
   344 	ClearGRFConfigList(&_all_grfs);
   359 	ClearGRFConfigList(&_all_grfs);
   345 
   360 
   346 	DEBUG(grf, 1, "Scanning for NewGRFs");
   361 	DEBUG(grf, 1, "Scanning for NewGRFs");
   347 	num = ScanPath(_paths.data_dir);
   362 	num  = ScanPath(_paths.data_dir);
       
   363 	num += ScanPath(_paths.second_data_dir);
   348 	DEBUG(grf, 1, "Scan complete, found %d files", num);
   364 	DEBUG(grf, 1, "Scan complete, found %d files", num);
   349 }
   365 }
   350 
   366 
   351 
   367 
   352 /* Find a NewGRF in the scanned list, if md5sum is NULL, we don't care about it*/
   368 /* Find a NewGRF in the scanned list, if md5sum is NULL, we don't care about it*/