1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
8 /** @file newgrf_config.cpp Finding NewGRFs and configuring them. */
9 
10 #include "stdafx.h"
11 #include "debug.h"
12 #include "3rdparty/md5/md5.h"
13 #include "newgrf.h"
14 #include "network/network_func.h"
15 #include "gfx_func.h"
16 #include "newgrf_text.h"
17 #include "window_func.h"
18 #include "progress.h"
19 #include "video/video_driver.hpp"
20 #include "string_func.h"
21 #include "strings_func.h"
22 #include "textfile_gui.h"
23 #include "thread.h"
24 #include "newgrf_config.h"
25 #include "newgrf_text.h"
26 
27 #include "fileio_func.h"
28 #include "fios.h"
29 
30 #include "safeguards.h"
31 
32 
33 /**
34  * Create a new GRFConfig.
35  * @param filename Set the filename of this GRFConfig to filename. The argument
36  *   is copied so the original string isn't needed after the constructor.
37  */
GRFConfig(const char * filename)38 GRFConfig::GRFConfig(const char *filename) :
39 	num_valid_params(lengthof(param))
40 {
41 	if (filename != nullptr) this->filename = stredup(filename);
42 }
43 
44 /**
45  * Create a new GRFConfig that is a deep copy of an existing config.
46  * @param config The GRFConfig object to make a copy of.
47  */
GRFConfig(const GRFConfig & config)48 GRFConfig::GRFConfig(const GRFConfig &config) :
49 	ZeroedMemoryAllocator(),
50 	ident(config.ident),
51 	name(config.name),
52 	info(config.info),
53 	url(config.url),
54 	version(config.version),
55 	min_loadable_version(config.min_loadable_version),
56 	flags(config.flags & ~(1 << GCF_COPY)),
57 	status(config.status),
58 	grf_bugs(config.grf_bugs),
59 	num_params(config.num_params),
60 	num_valid_params(config.num_valid_params),
61 	palette(config.palette),
62 	has_param_defaults(config.has_param_defaults)
63 {
64 	MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum));
65 	MemCpyT<uint32>(this->param, config.param, lengthof(this->param));
66 	if (config.filename != nullptr) this->filename = stredup(config.filename);
67 	if (config.error != nullptr) this->error = new GRFError(*config.error);
68 	for (uint i = 0; i < config.param_info.size(); i++) {
69 		if (config.param_info[i] == nullptr) {
70 			this->param_info.push_back(nullptr);
71 		} else {
72 			this->param_info.push_back(new GRFParameterInfo(*config.param_info[i]));
73 		}
74 	}
75 }
76 
77 /** Cleanup a GRFConfig object. */
~GRFConfig()78 GRFConfig::~GRFConfig()
79 {
80 	/* GCF_COPY as in NOT stredupped/alloced the filename */
81 	if (!HasBit(this->flags, GCF_COPY)) {
82 		free(this->filename);
83 		delete this->error;
84 	}
85 
86 	for (uint i = 0; i < this->param_info.size(); i++) delete this->param_info[i];
87 }
88 
89 /**
90  * Copy the parameter information from the \a src config.
91  * @param src Source config.
92  */
CopyParams(const GRFConfig & src)93 void GRFConfig::CopyParams(const GRFConfig &src)
94 {
95 	this->num_params = src.num_params;
96 	this->num_valid_params = src.num_valid_params;
97 	MemCpyT<uint32>(this->param, src.param, lengthof(this->param));
98 }
99 
100 /**
101  * Get the name of this grf. In case the name isn't known
102  * the filename is returned.
103  * @return The name of filename of this grf.
104  */
GetName() const105 const char *GRFConfig::GetName() const
106 {
107 	const char *name = GetGRFStringFromGRFText(this->name);
108 	return StrEmpty(name) ? this->filename : name;
109 }
110 
111 /**
112  * Get the grf info.
113  * @return A string with a description of this grf.
114  */
GetDescription() const115 const char *GRFConfig::GetDescription() const
116 {
117 	return GetGRFStringFromGRFText(this->info);
118 }
119 
120 /**
121  * Get the grf url.
122  * @return A string with an url of this grf.
123  */
GetURL() const124 const char *GRFConfig::GetURL() const
125 {
126 	return GetGRFStringFromGRFText(this->url);
127 }
128 
129 /** Set the default value for all parameters as specified by action14. */
SetParameterDefaults()130 void GRFConfig::SetParameterDefaults()
131 {
132 	this->num_params = 0;
133 	MemSetT<uint32>(this->param, 0, lengthof(this->param));
134 
135 	if (!this->has_param_defaults) return;
136 
137 	for (uint i = 0; i < this->param_info.size(); i++) {
138 		if (this->param_info[i] == nullptr) continue;
139 		this->param_info[i]->SetValue(this, this->param_info[i]->def_value);
140 	}
141 }
142 
143 /**
144  * Set the palette of this GRFConfig to something suitable.
145  * That is either the setting coming from the NewGRF or
146  * the globally used palette.
147  */
SetSuitablePalette()148 void GRFConfig::SetSuitablePalette()
149 {
150 	PaletteType pal;
151 	switch (this->palette & GRFP_GRF_MASK) {
152 		case GRFP_GRF_DOS:     pal = PAL_DOS;      break;
153 		case GRFP_GRF_WINDOWS: pal = PAL_WINDOWS;  break;
154 		default:               pal = _settings_client.gui.newgrf_default_palette == 1 ? PAL_WINDOWS : PAL_DOS; break;
155 	}
156 	SB(this->palette, GRFP_USE_BIT, 1, pal == PAL_WINDOWS ? GRFP_USE_WINDOWS : GRFP_USE_DOS);
157 }
158 
159 /**
160  * Finalize Action 14 info after file scan is finished.
161  */
FinalizeParameterInfo()162 void GRFConfig::FinalizeParameterInfo()
163 {
164 	for (GRFParameterInfo *info : this->param_info) {
165 		if (info == nullptr) continue;
166 		info->Finalize();
167 	}
168 }
169 
170 GRFConfig *_all_grfs;
171 GRFConfig *_grfconfig;
172 GRFConfig *_grfconfig_newgame;
173 GRFConfig *_grfconfig_static;
174 uint _missing_extra_graphics = 0;
175 
176 /**
177  * Construct a new GRFError.
178  * @param severity The severity of this error.
179  * @param message The actual error-string.
180  */
GRFError(StringID severity,StringID message)181 GRFError::GRFError(StringID severity, StringID message) :
182 	message(message),
183 	severity(severity),
184 	param_value()
185 {
186 }
187 
188 /**
189  * Create a new GRFError that is a deep copy of an existing error message.
190  * @param error The GRFError object to make a copy of.
191  */
GRFError(const GRFError & error)192 GRFError::GRFError(const GRFError &error) :
193 	custom_message(error.custom_message),
194 	data(error.data),
195 	message(error.message),
196 	severity(error.severity)
197 {
198 	memcpy(this->param_value, error.param_value, sizeof(this->param_value));
199 }
200 
201 /**
202  * Create a new empty GRFParameterInfo object.
203  * @param nr The newgrf parameter that is changed.
204  */
GRFParameterInfo(uint nr)205 GRFParameterInfo::GRFParameterInfo(uint nr) :
206 	name(),
207 	desc(),
208 	type(PTYPE_UINT_ENUM),
209 	min_value(0),
210 	max_value(UINT32_MAX),
211 	def_value(0),
212 	param_nr(nr),
213 	first_bit(0),
214 	num_bit(32),
215 	value_names(),
216 	complete_labels(false)
217 {}
218 
219 /**
220  * Create a new GRFParameterInfo object that is a deep copy of an existing
221  *   parameter info object.
222  * @param info The GRFParameterInfo object to make a copy of.
223  */
GRFParameterInfo(GRFParameterInfo & info)224 GRFParameterInfo::GRFParameterInfo(GRFParameterInfo &info) :
225 	name(info.name),
226 	desc(info.desc),
227 	type(info.type),
228 	min_value(info.min_value),
229 	max_value(info.max_value),
230 	def_value(info.def_value),
231 	param_nr(info.param_nr),
232 	first_bit(info.first_bit),
233 	num_bit(info.num_bit),
234 	value_names(info.value_names),
235 	complete_labels(info.complete_labels)
236 {
237 }
238 
239 /**
240  * Get the value of this user-changeable parameter from the given config.
241  * @param config The GRFConfig to get the value from.
242  * @return The value of this parameter.
243  */
GetValue(struct GRFConfig * config) const244 uint32 GRFParameterInfo::GetValue(struct GRFConfig *config) const
245 {
246 	/* GB doesn't work correctly with nbits == 32, so handle that case here. */
247 	if (this->num_bit == 32) return config->param[this->param_nr];
248 	return GB(config->param[this->param_nr], this->first_bit, this->num_bit);
249 }
250 
251 /**
252  * Set the value of this user-changeable parameter in the given config.
253  * @param config The GRFConfig to set the value in.
254  * @param value The new value.
255  */
SetValue(struct GRFConfig * config,uint32 value)256 void GRFParameterInfo::SetValue(struct GRFConfig *config, uint32 value)
257 {
258 	/* SB doesn't work correctly with nbits == 32, so handle that case here. */
259 	if (this->num_bit == 32) {
260 		config->param[this->param_nr] = value;
261 	} else {
262 		SB(config->param[this->param_nr], this->first_bit, this->num_bit, value);
263 	}
264 	config->num_params = std::max<uint>(config->num_params, this->param_nr + 1);
265 	SetWindowDirty(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE);
266 }
267 
268 /**
269  * Finalize Action 14 info after file scan is finished.
270  */
Finalize()271 void GRFParameterInfo::Finalize()
272 {
273 	this->complete_labels = true;
274 	for (uint32 value = this->min_value; value <= this->max_value; value++) {
275 		if (!this->value_names.Contains(value)) {
276 			this->complete_labels = false;
277 			break;
278 		}
279 	}
280 }
281 
282 /**
283  * Update the palettes of the graphics from the config file.
284  * Called when changing the default palette in advanced settings.
285  * @param new_value Unused.
286  */
UpdateNewGRFConfigPalette(int32 new_value)287 void UpdateNewGRFConfigPalette(int32 new_value)
288 {
289 	for (GRFConfig *c = _grfconfig_newgame; c != nullptr; c = c->next) c->SetSuitablePalette();
290 	for (GRFConfig *c = _grfconfig_static;  c != nullptr; c = c->next) c->SetSuitablePalette();
291 	for (GRFConfig *c = _all_grfs;          c != nullptr; c = c->next) c->SetSuitablePalette();
292 }
293 
294 /**
295  * Get the data section size of a GRF.
296  * @param f GRF.
297  * @return Size of the data section or SIZE_MAX if the file has no separate data section.
298  */
GRFGetSizeOfDataSection(FILE * f)299 size_t GRFGetSizeOfDataSection(FILE *f)
300 {
301 	extern const byte _grf_cont_v2_sig[];
302 	static const uint header_len = 14;
303 
304 	byte data[header_len];
305 	if (fread(data, 1, header_len, f) == header_len) {
306 		if (data[0] == 0 && data[1] == 0 && MemCmpT(data + 2, _grf_cont_v2_sig, 8) == 0) {
307 			/* Valid container version 2, get data section size. */
308 			size_t offset = ((size_t)data[13] << 24) | ((size_t)data[12] << 16) | ((size_t)data[11] << 8) | (size_t)data[10];
309 			if (offset >= 1 * 1024 * 1024 * 1024) {
310 				Debug(grf, 0, "Unexpectedly large offset for NewGRF");
311 				/* Having more than 1 GiB of data is very implausible. Mostly because then
312 				 * all pools in OpenTTD are flooded already. Or it's just Action C all over.
313 				 * In any case, the offsets to graphics will likely not work either. */
314 				return SIZE_MAX;
315 			}
316 			return header_len + offset;
317 		}
318 	}
319 
320 	return SIZE_MAX;
321 }
322 
323 /**
324  * Calculate the MD5 sum for a GRF, and store it in the config.
325  * @param config GRF to compute.
326  * @param subdir The subdirectory to look in.
327  * @return MD5 sum was successfully computed
328  */
CalcGRFMD5Sum(GRFConfig * config,Subdirectory subdir)329 static bool CalcGRFMD5Sum(GRFConfig *config, Subdirectory subdir)
330 {
331 	FILE *f;
332 	Md5 checksum;
333 	uint8 buffer[1024];
334 	size_t len, size;
335 
336 	/* open the file */
337 	f = FioFOpenFile(config->filename, "rb", subdir, &size);
338 	if (f == nullptr) return false;
339 
340 	long start = ftell(f);
341 	size = std::min(size, GRFGetSizeOfDataSection(f));
342 
343 	if (start < 0 || fseek(f, start, SEEK_SET) < 0) {
344 		FioFCloseFile(f);
345 		return false;
346 	}
347 
348 	/* calculate md5sum */
349 	while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, f)) != 0 && size != 0) {
350 		size -= len;
351 		checksum.Append(buffer, len);
352 	}
353 	checksum.Finish(config->ident.md5sum);
354 
355 	FioFCloseFile(f);
356 
357 	return true;
358 }
359 
360 
361 /**
362  * Find the GRFID of a given grf, and calculate its md5sum.
363  * @param config    grf to fill.
364  * @param is_static grf is static.
365  * @param subdir    the subdirectory to search in.
366  * @return Operation was successfully completed.
367  */
FillGRFDetails(GRFConfig * config,bool is_static,Subdirectory subdir)368 bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir)
369 {
370 	if (!FioCheckFileExists(config->filename, subdir)) {
371 		config->status = GCS_NOT_FOUND;
372 		return false;
373 	}
374 
375 	/* Find and load the Action 8 information */
376 	LoadNewGRFFile(config, GLS_FILESCAN, subdir, true);
377 	config->SetSuitablePalette();
378 	config->FinalizeParameterInfo();
379 
380 	/* Skip if the grfid is 0 (not read) or if it is an internal GRF */
381 	if (config->ident.grfid == 0 || HasBit(config->flags, GCF_SYSTEM)) return false;
382 
383 	if (is_static) {
384 		/* Perform a 'safety scan' for static GRFs */
385 		LoadNewGRFFile(config, GLS_SAFETYSCAN, subdir, true);
386 
387 		/* GCF_UNSAFE is set if GLS_SAFETYSCAN finds unsafe actions */
388 		if (HasBit(config->flags, GCF_UNSAFE)) return false;
389 	}
390 
391 	return CalcGRFMD5Sum(config, subdir);
392 }
393 
394 
395 /**
396  * Clear a GRF Config list, freeing all nodes.
397  * @param config Start of the list.
398  * @post \a config is set to \c nullptr.
399  */
ClearGRFConfigList(GRFConfig ** config)400 void ClearGRFConfigList(GRFConfig **config)
401 {
402 	GRFConfig *c, *next;
403 	for (c = *config; c != nullptr; c = next) {
404 		next = c->next;
405 		delete c;
406 	}
407 	*config = nullptr;
408 }
409 
410 
411 /**
412  * Copy a GRF Config list
413  * @param dst pointer to destination list
414  * @param src pointer to source list values
415  * @param init_only the copied GRF will be processed up to GLS_INIT
416  * @return pointer to the last value added to the destination list
417  */
CopyGRFConfigList(GRFConfig ** dst,const GRFConfig * src,bool init_only)418 GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only)
419 {
420 	/* Clear destination as it will be overwritten */
421 	ClearGRFConfigList(dst);
422 	for (; src != nullptr; src = src->next) {
423 		GRFConfig *c = new GRFConfig(*src);
424 
425 		ClrBit(c->flags, GCF_INIT_ONLY);
426 		if (init_only) SetBit(c->flags, GCF_INIT_ONLY);
427 
428 		*dst = c;
429 		dst = &c->next;
430 	}
431 
432 	return dst;
433 }
434 
435 /**
436  * Removes duplicates from lists of GRFConfigs. These duplicates
437  * are introduced when the _grfconfig_static GRFs are appended
438  * to the _grfconfig on a newgame or savegame. As the parameters
439  * of the static GRFs could be different that the parameters of
440  * the ones used non-statically. This can result in desyncs in
441  * multiplayers, so the duplicate static GRFs have to be removed.
442  *
443  * This function _assumes_ that all static GRFs are placed after
444  * the non-static GRFs.
445  *
446  * @param list the list to remove the duplicates from
447  */
RemoveDuplicatesFromGRFConfigList(GRFConfig * list)448 static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list)
449 {
450 	GRFConfig *prev;
451 	GRFConfig *cur;
452 
453 	if (list == nullptr) return;
454 
455 	for (prev = list, cur = list->next; cur != nullptr; prev = cur, cur = cur->next) {
456 		if (cur->ident.grfid != list->ident.grfid) continue;
457 
458 		prev->next = cur->next;
459 		delete cur;
460 		cur = prev; // Just go back one so it continues as normal later on
461 	}
462 
463 	RemoveDuplicatesFromGRFConfigList(list->next);
464 }
465 
466 /**
467  * Appends the static GRFs to a list of GRFs
468  * @param dst the head of the list to add to
469  */
AppendStaticGRFConfigs(GRFConfig ** dst)470 void AppendStaticGRFConfigs(GRFConfig **dst)
471 {
472 	GRFConfig **tail = dst;
473 	while (*tail != nullptr) tail = &(*tail)->next;
474 
475 	CopyGRFConfigList(tail, _grfconfig_static, false);
476 	RemoveDuplicatesFromGRFConfigList(*dst);
477 }
478 
479 /**
480  * Appends an element to a list of GRFs
481  * @param dst the head of the list to add to
482  * @param el the new tail to be
483  */
AppendToGRFConfigList(GRFConfig ** dst,GRFConfig * el)484 void AppendToGRFConfigList(GRFConfig **dst, GRFConfig *el)
485 {
486 	GRFConfig **tail = dst;
487 	while (*tail != nullptr) tail = &(*tail)->next;
488 	*tail = el;
489 
490 	RemoveDuplicatesFromGRFConfigList(*dst);
491 }
492 
493 
494 /** Reset the current GRF Config to either blank or newgame settings. */
ResetGRFConfig(bool defaults)495 void ResetGRFConfig(bool defaults)
496 {
497 	CopyGRFConfigList(&_grfconfig, _grfconfig_newgame, !defaults);
498 	AppendStaticGRFConfigs(&_grfconfig);
499 }
500 
501 
502 /**
503  * Check if all GRFs in the GRF config from a savegame can be loaded.
504  * @param grfconfig GrfConfig to check
505  * @return will return any of the following 3 values:<br>
506  * <ul>
507  * <li> GLC_ALL_GOOD: No problems occurred, all GRF files were found and loaded
508  * <li> GLC_COMPATIBLE: For one or more GRF's no exact match was found, but a
509  *     compatible GRF with the same grfid was found and used instead
510  * <li> GLC_NOT_FOUND: For one or more GRF's no match was found at all
511  * </ul>
512  */
IsGoodGRFConfigList(GRFConfig * grfconfig)513 GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig)
514 {
515 	GRFListCompatibility res = GLC_ALL_GOOD;
516 
517 	for (GRFConfig *c = grfconfig; c != nullptr; c = c->next) {
518 		const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum);
519 		if (f == nullptr || HasBit(f->flags, GCF_INVALID)) {
520 			char buf[256];
521 
522 			/* If we have not found the exactly matching GRF try to find one with the
523 			 * same grfid, as it most likely is compatible */
524 			f = FindGRFConfig(c->ident.grfid, FGCM_COMPATIBLE, nullptr, c->version);
525 			if (f != nullptr) {
526 				md5sumToString(buf, lastof(buf), c->ident.md5sum);
527 				Debug(grf, 1, "NewGRF {:08X} ({}) not found; checksum {}. Compatibility mode on", BSWAP32(c->ident.grfid), c->filename, buf);
528 				if (!HasBit(c->flags, GCF_COMPATIBLE)) {
529 					/* Preserve original_md5sum after it has been assigned */
530 					SetBit(c->flags, GCF_COMPATIBLE);
531 					memcpy(c->original_md5sum, c->ident.md5sum, sizeof(c->original_md5sum));
532 				}
533 
534 				/* Non-found has precedence over compatibility load */
535 				if (res != GLC_NOT_FOUND) res = GLC_COMPATIBLE;
536 				goto compatible_grf;
537 			}
538 
539 			/* No compatible grf was found, mark it as disabled */
540 			md5sumToString(buf, lastof(buf), c->ident.md5sum);
541 			Debug(grf, 0, "NewGRF {:08X} ({}) not found; checksum {}", BSWAP32(c->ident.grfid), c->filename, buf);
542 
543 			c->status = GCS_NOT_FOUND;
544 			res = GLC_NOT_FOUND;
545 		} else {
546 compatible_grf:
547 			Debug(grf, 1, "Loading GRF {:08X} from {}", BSWAP32(f->ident.grfid), f->filename);
548 			/* The filename could be the filename as in the savegame. As we need
549 			 * to load the GRF here, we need the correct filename, so overwrite that
550 			 * in any case and set the name and info when it is not set already.
551 			 * When the GCF_COPY flag is set, it is certain that the filename is
552 			 * already a local one, so there is no need to replace it. */
553 			if (!HasBit(c->flags, GCF_COPY)) {
554 				free(c->filename);
555 				c->filename = stredup(f->filename);
556 				memcpy(c->ident.md5sum, f->ident.md5sum, sizeof(c->ident.md5sum));
557 				c->name = f->name;
558 				c->info = f->name;
559 				c->error = nullptr;
560 				c->version = f->version;
561 				c->min_loadable_version = f->min_loadable_version;
562 				c->num_valid_params = f->num_valid_params;
563 				c->has_param_defaults = f->has_param_defaults;
564 				for (uint i = 0; i < f->param_info.size(); i++) {
565 					if (f->param_info[i] == nullptr) {
566 						c->param_info.push_back(nullptr);
567 					} else {
568 						c->param_info.push_back(new GRFParameterInfo(*f->param_info[i]));
569 					}
570 				}
571 			}
572 		}
573 	}
574 
575 	return res;
576 }
577 
578 /** Helper for scanning for files with GRF as extension */
579 class GRFFileScanner : FileScanner {
580 	std::chrono::steady_clock::time_point next_update; ///< The next moment we do update the screen.
581 	uint num_scanned; ///< The number of GRFs we have scanned.
582 
583 public:
GRFFileScanner()584 	GRFFileScanner() : num_scanned(0)
585 	{
586 		this->next_update = std::chrono::steady_clock::now();
587 	}
588 
589 	bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename) override;
590 
591 	/** Do the scan for GRFs. */
DoScan()592 	static uint DoScan()
593 	{
594 		GRFFileScanner fs;
595 		int ret = fs.Scan(".grf", NEWGRF_DIR);
596 		/* The number scanned and the number returned may not be the same;
597 		 * duplicate NewGRFs and base sets are ignored in the return value. */
598 		_settings_client.gui.last_newgrf_count = fs.num_scanned;
599 		return ret;
600 	}
601 };
602 
AddFile(const std::string & filename,size_t basepath_length,const std::string & tar_filename)603 bool GRFFileScanner::AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename)
604 {
605 	/* Abort if the user stopped the game during a scan. */
606 	if (_exit_game) return false;
607 
608 	GRFConfig *c = new GRFConfig(filename.c_str() + basepath_length);
609 
610 	bool added = true;
611 	if (FillGRFDetails(c, false)) {
612 		if (_all_grfs == nullptr) {
613 			_all_grfs = c;
614 		} else {
615 			/* Insert file into list at a position determined by its
616 			 * name, so the list is sorted as we go along */
617 			GRFConfig **pd, *d;
618 			bool stop = false;
619 			for (pd = &_all_grfs; (d = *pd) != nullptr; pd = &d->next) {
620 				if (c->ident.grfid == d->ident.grfid && memcmp(c->ident.md5sum, d->ident.md5sum, sizeof(c->ident.md5sum)) == 0) added = false;
621 				/* Because there can be multiple grfs with the same name, make sure we checked all grfs with the same name,
622 				 *  before inserting the entry. So insert a new grf at the end of all grfs with the same name, instead of
623 				 *  just after the first with the same name. Avoids doubles in the list. */
624 				if (strcasecmp(c->GetName(), d->GetName()) <= 0) {
625 					stop = true;
626 				} else if (stop) {
627 					break;
628 				}
629 			}
630 			if (added) {
631 				c->next = d;
632 				*pd = c;
633 			}
634 		}
635 	} else {
636 		added = false;
637 	}
638 
639 	this->num_scanned++;
640 
641 	const char *name = nullptr;
642 	if (c->name != nullptr) name = GetGRFStringFromGRFText(c->name);
643 	if (name == nullptr) name = c->filename;
644 	UpdateNewGRFScanStatus(this->num_scanned, name);
645 	VideoDriver::GetInstance()->GameLoopPause();
646 
647 	if (!added) {
648 		/* File couldn't be opened, or is either not a NewGRF or is a
649 		 * 'system' NewGRF or it's already known, so forget about it. */
650 		delete c;
651 	}
652 
653 	return added;
654 }
655 
656 /**
657  * Simple sorter for GRFS
658  * @param c1 the first GRFConfig *
659  * @param c2 the second GRFConfig *
660  * @return true if the name of first NewGRF is before the name of the second.
661  */
GRFSorter(GRFConfig * const & c1,GRFConfig * const & c2)662 static bool GRFSorter(GRFConfig * const &c1, GRFConfig * const &c2)
663 {
664 	return strnatcmp(c1->GetName(), c2->GetName()) < 0;
665 }
666 
667 /**
668  * Really perform the scan for all NewGRFs.
669  * @param callback The callback to call after the scanning is complete.
670  */
DoScanNewGRFFiles(NewGRFScanCallback * callback)671 void DoScanNewGRFFiles(NewGRFScanCallback *callback)
672 {
673 	ClearGRFConfigList(&_all_grfs);
674 	TarScanner::DoScan(TarScanner::NEWGRF);
675 
676 	Debug(grf, 1, "Scanning for NewGRFs");
677 	uint num = GRFFileScanner::DoScan();
678 
679 	Debug(grf, 1, "Scan complete, found {} files", num);
680 	if (num != 0 && _all_grfs != nullptr) {
681 		/* Sort the linked list using quicksort.
682 		 * For that we first have to make an array, then sort and
683 		 * then remake the linked list. */
684 		std::vector<GRFConfig *> to_sort;
685 
686 		uint i = 0;
687 		for (GRFConfig *p = _all_grfs; p != nullptr; p = p->next, i++) {
688 			to_sort.push_back(p);
689 		}
690 		/* Number of files is not necessarily right */
691 		num = i;
692 
693 		std::sort(to_sort.begin(), to_sort.end(), GRFSorter);
694 
695 		for (i = 1; i < num; i++) {
696 			to_sort[i - 1]->next = to_sort[i];
697 		}
698 		to_sort[num - 1]->next = nullptr;
699 		_all_grfs = to_sort[0];
700 
701 		NetworkAfterNewGRFScan();
702 	}
703 
704 	/* Yes... these are the NewGRF windows */
705 	InvalidateWindowClassesData(WC_SAVELOAD, 0, true);
706 	InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE, GOID_NEWGRF_RESCANNED, true);
707 	if (!_exit_game && callback != nullptr) callback->OnNewGRFsScanned();
708 
709 	CloseWindowByClass(WC_MODAL_PROGRESS);
710 	SetModalProgress(false);
711 	MarkWholeScreenDirty();
712 }
713 
714 /**
715  * Scan for all NewGRFs.
716  * @param callback The callback to call after the scanning is complete.
717  */
ScanNewGRFFiles(NewGRFScanCallback * callback)718 void ScanNewGRFFiles(NewGRFScanCallback *callback)
719 {
720 	/* First set the modal progress. This ensures that it will eventually let go of the paint mutex. */
721 	SetModalProgress(true);
722 	/* Only then can we really start, especially by marking the whole screen dirty. Get those other windows hidden!. */
723 	MarkWholeScreenDirty();
724 
725 	DoScanNewGRFFiles(callback);
726 }
727 
728 /**
729  * Find a NewGRF in the scanned list.
730  * @param grfid GRFID to look for,
731  * @param mode Restrictions for matching grfs
732  * @param md5sum Expected MD5 sum
733  * @param desired_version Requested version
734  * @return The matching grf, if it exists in #_all_grfs, else \c nullptr.
735  */
FindGRFConfig(uint32 grfid,FindGRFConfigMode mode,const uint8 * md5sum,uint32 desired_version)736 const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version)
737 {
738 	assert((mode == FGCM_EXACT) != (md5sum == nullptr));
739 	const GRFConfig *best = nullptr;
740 	for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) {
741 		/* if md5sum is set, we look for an exact match and continue if not found */
742 		if (!c->ident.HasGrfIdentifier(grfid, md5sum)) continue;
743 		/* return it, if the exact same newgrf is found, or if we do not care about finding "the best" */
744 		if (md5sum != nullptr || mode == FGCM_ANY) return c;
745 		/* Skip incompatible stuff, unless explicitly allowed */
746 		if (mode != FGCM_NEWEST && HasBit(c->flags, GCF_INVALID)) continue;
747 		/* check version compatibility */
748 		if (mode == FGCM_COMPATIBLE && (c->version < desired_version || c->min_loadable_version > desired_version)) continue;
749 		/* remember the newest one as "the best" */
750 		if (best == nullptr || c->version > best->version) best = c;
751 	}
752 
753 	return best;
754 }
755 
756 /**
757  * Retrieve a NewGRF from the current config by its grfid.
758  * @param grfid grf to look for.
759  * @param mask  GRFID mask to allow for partial matching.
760  * @return The grf config, if it exists, else \c nullptr.
761  */
GetGRFConfig(uint32 grfid,uint32 mask)762 GRFConfig *GetGRFConfig(uint32 grfid, uint32 mask)
763 {
764 	GRFConfig *c;
765 
766 	for (c = _grfconfig; c != nullptr; c = c->next) {
767 		if ((c->ident.grfid & mask) == (grfid & mask)) return c;
768 	}
769 
770 	return nullptr;
771 }
772 
773 
774 /** Build a string containing space separated parameter values, and terminate */
GRFBuildParamList(char * dst,const GRFConfig * c,const char * last)775 char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last)
776 {
777 	uint i;
778 
779 	/* Return an empty string if there are no parameters */
780 	if (c->num_params == 0) return strecpy(dst, "", last);
781 
782 	for (i = 0; i < c->num_params; i++) {
783 		if (i > 0) dst = strecpy(dst, " ", last);
784 		dst += seprintf(dst, last, "%d", c->param[i]);
785 	}
786 	return dst;
787 }
788 
789 /**
790  * Search a textfile file next to this NewGRF.
791  * @param type The type of the textfile to search for.
792  * @return The filename for the textfile, \c nullptr otherwise.
793  */
GetTextfile(TextfileType type) const794 const char *GRFConfig::GetTextfile(TextfileType type) const
795 {
796 	return ::GetTextfile(type, NEWGRF_DIR, this->filename);
797 }
798