From 4ccd8a67864ebc5b46b005cd021d7b1807f66a4c Mon Sep 17 00:00:00 2001 From: rubidium Date: Thu, 19 Jun 2008 10:20:45 +0000 Subject: (svn r13576) -Codechange: disable static NewGRFs when non-static NewGRFs query them in the context of network games. This makes it impossible for static NewGRFs to disable non-static NewGRFs and 'bad' things happening because the non-static NewGRF doesn't know about the static NewGRF. --- src/lang/english.txt | 1 + src/newgrf.cpp | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index e01c4dc35..bc9e36279 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3165,6 +3165,7 @@ STR_NEWGRF_ERROR_LOAD_AFTER :{STRING} must b STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{STRING} requires OpenTTD version {STRING} or better. STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :the GRF file it was designed to translate STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Too many NewGRFs are loaded. +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {STRING} as static NewGRF with {STRING} could cause desyncs. STR_NEWGRF_ADD :{BLACK}Add STR_NEWGRF_ADD_TIP :{BLACK}Add a NewGRF file to the list diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 1ce7a2832..f1fe64635 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -46,6 +46,7 @@ #include "road_func.h" #include "player_base.h" #include "settings_type.h" +#include "network/network.h" #include "map_func.h" #include @@ -3800,6 +3801,29 @@ static void CfgApply(byte *buf, size_t len) } } +/** + * Disable a static NewGRF when it is influencing another (non-static) + * NewGRF as this could cause desyncs. + * + * We could just tell the NewGRF querying that the file doesn't exist, + * but that might give unwanted results. Disabling the NewGRF gives the + * best result as no NewGRF author can complain about that. + * @param c the NewGRF to disable. + */ +static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c) +{ + if (c->error != NULL) { + free(c->error->custom_message); + free(c->error->data); + free(c->error); + } + c->status = GCS_DISABLED; + c->error = CallocT(1); + c->error->data = strdup(_cur_grfconfig->name); + c->error->severity = STR_NEWGRF_ERROR_MSG_FATAL; + c->error->message = STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC; +} + /* Action 0x07 */ /* Action 0x09 */ static void SkipIf(byte *buf, size_t len) @@ -3853,7 +3877,12 @@ static void SkipIf(byte *buf, size_t len) if (param == 0x88 && condtype != 0x0B && condtype != 0x0C) { /* GRF ID checks */ - const GRFConfig *c = GetGRFConfig(cond_val); + GRFConfig *c = GetGRFConfig(cond_val); + + if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && c->status != GCS_DISABLED && _networking) { + DisableStaticNewGRFInfluencingNonStaticNewGRFs(c); + c = NULL; + } if (condtype != 10 && c == NULL) { grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val)); @@ -4455,7 +4484,12 @@ static void ParamSet(byte *buf, size_t len) } else { /* Read another GRF File's parameter */ const GRFFile *file = GetFileByGRFID(data); - if (file == NULL || src1 >= file->param_end) { + GRFConfig *c = GetGRFConfig(data); + if (c != NULL && HasBit(c->status, GCF_STATIC) && !HasBit(_cur_grfconfig->status, GCF_STATIC) && _networking) { + /* Disable the read GRF if it is a static NewGRF. */ + DisableStaticNewGRFInfluencingNonStaticNewGRFs(c); + src1 = 0; + } else if (file == NULL || src1 >= file->param_end || (c != NULL && c->status == GCS_DISABLED)) { src1 = 0; } else { src1 = file->param[src1]; -- cgit v1.2.3-54-g00ecf