From 56d06b6ef86631b531f7d87f4e3a26f04aaf4f1e Mon Sep 17 00:00:00 2001 From: frosch Date: Sat, 15 Jan 2011 21:13:47 +0000 Subject: [PATCH] (svn r21814) -Fix/Add: Check GRF version from action 8, and disallow usage of GRFs with versions above 7. --- src/lang/english.txt | 1 + src/newgrf.cpp | 12 +++++++++--- src/newgrf_config.cpp | 4 +++- src/newgrf_config.h | 3 ++- src/newgrf_gui.cpp | 9 +++++---- src/settings.cpp | 4 +++- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 3580753b51..98a2e7ef39 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2425,6 +2425,7 @@ STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Paramete 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 diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 4fb8fa78ed..4a4f552131 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -5313,15 +5313,21 @@ static void SkipIf(ByteReader *buf) /* 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()) { diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index e7be72fabf..aed73655ca 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -444,7 +444,7 @@ GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig) 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 @@ const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 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" */ diff --git a/src/newgrf_config.h b/src/newgrf_config.h index 54d51e05e2..f6c97c42ca 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -25,7 +25,7 @@ enum GCF_Flags { 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 @@ enum FindGRFConfigMode { 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 }; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 913a8ff291..2034ae6abe 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -115,6 +115,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint /* 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 @@ struct NewGRFWindow : public QueryStringBaseWindow { } 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 @@ struct NewGRFWindow : public QueryStringBaseWindow { 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 @@ struct NewGRFWindow : public QueryStringBaseWindow { 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 @@ private: 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 diff --git a/src/settings.cpp b/src/settings.cpp index 1ba1d3b5cf..fde9559904 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1352,7 +1352,7 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati } /* 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 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati 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"; }