changeset 17077:5a60038ce980 draft

(svn r21814) -Fix/Add: Check GRF version from action 8, and disallow usage of GRFs with versions above 7.
author frosch <frosch@openttd.org>
date Sat, 15 Jan 2011 21:13:47 +0000
parents 37b1c0eebb05
children 5bfb50c7bacd
files src/lang/english.txt src/newgrf.cpp src/newgrf_config.cpp src/newgrf_config.h src/newgrf_gui.cpp src/settings.cpp
diffstat 6 files changed, 23 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -2425,6 +2425,7 @@
 STR_NEWGRF_SETTINGS_NO_INFO                                     :{BLACK}No information available
 STR_NEWGRF_SETTINGS_NOT_FOUND                                   :{RED}Matching file not found
 STR_NEWGRF_SETTINGS_DISABLED                                    :{RED}Disabled
+STR_NEWGRF_SETTINGS_INCOMPATIBLE                                :{RED}Incompatible with this version of OpenTTD
 
 STR_NEWGRF_SETTINGS_PARAMETER_QUERY                             :{BLACK}Enter NewGRF parameters
 
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -5313,15 +5313,21 @@
 /* Action 0x08 (GLS_FILESCAN) */
 static void ScanInfo(ByteReader *buf)
 {
-	buf->ReadByte();
-	uint32 grfid  = buf->ReadDWord();
+	uint8 grf_version = buf->ReadByte();
+	uint32 grfid      = buf->ReadDWord();
+	const char *name  = buf->ReadString();
 
 	_cur_grfconfig->ident.grfid = grfid;
 
+	/* TODO We are incompatible to grf_version < 2 as well, but due to broken GRFs out there, we accept these till the next stable */
+	if (/*grf_version < 2 || */grf_version > 7) {
+		SetBit(_cur_grfconfig->flags, GCF_INVALID);
+		DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur_grfconfig->filename, name, BSWAP32(grfid), grf_version);
+	}
+
 	/* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
 	if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
 
-	const char *name = buf->ReadString();
 	AddGRFTextToList(&_cur_grfconfig->name, 0x7F, grfid, name);
 
 	if (buf->HasData()) {
--- a/src/newgrf_config.cpp
+++ b/src/newgrf_config.cpp
@@ -444,7 +444,7 @@
 
 	for (GRFConfig *c = grfconfig; c != NULL; c = c->next) {
 		const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum);
-		if (f == NULL) {
+		if (f == NULL || HasBit(f->flags, GCF_INVALID)) {
 			char buf[256];
 
 			/* If we have not found the exactly matching GRF try to find one with the
@@ -630,6 +630,8 @@
 		if (!c->ident.HasGrfIdentifier(grfid, md5sum)) continue;
 		/* return it, if the exact same newgrf is found, or if we do not care about finding "the best" */
 		if (md5sum != NULL || mode == FGCM_ANY) return c;
+		/* Skip incompatible stuff, unless explicitly allowed */
+		if (mode != FGCM_NEWEST && HasBit(c->flags, GCF_INVALID)) continue;
 		/* check version compatibility */
 		if (mode == FGCM_COMPATIBLE && (c->version < desired_version || c->min_loadable_version > desired_version)) continue;
 		/* remember the newest one as "the best" */
--- a/src/newgrf_config.h
+++ b/src/newgrf_config.h
@@ -25,7 +25,7 @@
 	GCF_COPY,       ///< The data is copied from a grf in _all_grfs
 	GCF_INIT_ONLY,  ///< GRF file is processed up to GLS_INIT
 	GCF_RESERVED,   ///< GRF file passed GLS_RESERVE stage
-
+	GCF_INVALID,    ///< GRF is unusable with this version of OpenTTD
 };
 
 /** Status of GRF */
@@ -170,6 +170,7 @@
 	FGCM_EXACT,       ///< Only find Grfs matching md5sum
 	FGCM_COMPATIBLE,  ///< Find best compatible Grf wrt. desired_version
 	FGCM_NEWEST,      ///< Find newest Grf
+	FGCM_NEWEST_VALID,///< Find newest Grf, ignoring Grfs with GCF_INVALID set
 	FGCM_ANY,         ///< Use first found
 };
 
--- a/src/newgrf_gui.cpp
+++ b/src/newgrf_gui.cpp
@@ -115,6 +115,7 @@
 	/* Show flags */
 	if (c->status == GCS_NOT_FOUND)       y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_NOT_FOUND);
 	if (c->status == GCS_DISABLED)        y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_DISABLED);
+	if (HasBit(c->flags, GCF_INVALID))    y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_INCOMPATIBLE);
 	if (HasBit(c->flags, GCF_COMPATIBLE)) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_COMPATIBLE_LOADED);
 
 	/* Draw GRF info if it exists */
@@ -888,7 +889,7 @@
 			}
 
 			case SNGRFS_ADD: {
-				if (this->avail_sel == NULL || !this->editable) break;
+				if (this->avail_sel == NULL || !this->editable || HasBit(this->avail_sel->flags, GCF_INVALID)) break;
 
 				GRFConfig **list;
 				/* Find last entry in the list, checking for duplicate grfid on the way */
@@ -1047,7 +1048,7 @@
 					if (c->status != GCS_NOT_FOUND && !compatible) continue;
 
 					const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, compatible ? c->original_md5sum : c->ident.md5sum);
-					if (f == NULL) continue;
+					if (f == NULL || HasBit(f->flags, GCF_INVALID)) continue;
 
 					*l = new GRFConfig(*f);
 					(*l)->next = c->next;
@@ -1084,7 +1085,7 @@
 			SNGRFS_TOGGLE_PALETTE,
 			WIDGET_LIST_END
 		);
-		this->SetWidgetDisabledState(SNGRFS_ADD, !this->editable || this->avail_sel == NULL);
+		this->SetWidgetDisabledState(SNGRFS_ADD, !this->editable || this->avail_sel == NULL || HasBit(this->avail_sel->flags, GCF_INVALID));
 
 		bool disable_all = this->active_sel == NULL || !this->editable;
 		this->SetWidgetsDisabledState(disable_all,
@@ -1233,7 +1234,7 @@
 			if (_settings_client.gui.newgrf_show_old_versions) {
 				*this->avails.Append() = c;
 			} else {
-				const GRFConfig *best = FindGRFConfig(c->ident.grfid, FGCM_NEWEST);
+				const GRFConfig *best = FindGRFConfig(c->ident.grfid, HasBit(c->flags, GCF_INVALID) ? FGCM_NEWEST : FGCM_NEWEST_VALID);
 				/*
 				 * If the best version is 0, then all NewGRF with this GRF ID
 				 * have version 0, so for backward compatability reasons we
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -1352,7 +1352,7 @@
 		}
 
 		/* Check if item is valid */
-		if (!FillGRFDetails(c, is_static)) {
+		if (!FillGRFDetails(c, is_static) || HasBit(c->flags, GCF_INVALID)) {
 			const char *msg;
 
 			if (c->status == GCS_NOT_FOUND) {
@@ -1361,6 +1361,8 @@
 				msg = "unsafe for static use";
 			} else if (HasBit(c->flags, GCF_SYSTEM)) {
 				msg = "system NewGRF";
+			} else if (HasBit(c->flags, GCF_INVALID)) {
+				msg = "incompatible to this version of OpenTTD";
 			} else {
 				msg = "unknown";
 			}