13 #include "core/alloc_func.hpp" |
13 #include "core/alloc_func.hpp" |
14 #include "string_func.h" |
14 #include "string_func.h" |
15 #include "gamelog.h" |
15 #include "gamelog.h" |
16 #include "network/network_type.h" |
16 #include "network/network_type.h" |
17 |
17 |
18 #include "tar_type.h" |
|
19 #include "fileio.h" |
18 #include "fileio.h" |
20 #include "fios.h" |
19 #include "fios.h" |
21 #include <sys/stat.h> |
|
22 |
20 |
23 |
21 |
24 GRFConfig *_all_grfs; |
22 GRFConfig *_all_grfs; |
25 GRFConfig *_grfconfig; |
23 GRFConfig *_grfconfig; |
26 GRFConfig *_grfconfig_newgame; |
24 GRFConfig *_grfconfig_newgame; |
265 } |
263 } |
266 |
264 |
267 return res; |
265 return res; |
268 } |
266 } |
269 |
267 |
270 static bool ScanPathAddGrf(const char *filename) |
268 /** Helper for scanning for files with GRF as extension */ |
|
269 class GRFFileScanner : FileScanner { |
|
270 public: |
|
271 /* virtual */ bool AddFile(const char *filename, size_t basepath_length); |
|
272 |
|
273 /** Do the scan for GRFs. */ |
|
274 static uint DoScan() |
|
275 { |
|
276 GRFFileScanner fs; |
|
277 return fs.Scan(".grf", DATA_DIR); |
|
278 } |
|
279 }; |
|
280 |
|
281 bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length) |
271 { |
282 { |
272 GRFConfig *c = CallocT<GRFConfig>(1); |
283 GRFConfig *c = CallocT<GRFConfig>(1); |
273 c->filename = strdup(filename); |
284 c->filename = strdup(filename + basepath_length); |
274 |
285 |
275 bool added = true; |
286 bool added = true; |
276 if (FillGRFDetails(c, false)) { |
287 if (FillGRFDetails(c, false)) { |
277 if (_all_grfs == NULL) { |
288 if (_all_grfs == NULL) { |
278 _all_grfs = c; |
289 _all_grfs = c; |
311 } |
322 } |
312 |
323 |
313 return added; |
324 return added; |
314 } |
325 } |
315 |
326 |
316 /* Scan a path for NewGRFs */ |
|
317 static uint ScanPath(const char *path, size_t basepath_length) |
|
318 { |
|
319 extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb); |
|
320 |
|
321 uint num = 0; |
|
322 struct stat sb; |
|
323 struct dirent *dirent; |
|
324 DIR *dir; |
|
325 |
|
326 if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0; |
|
327 |
|
328 while ((dirent = readdir(dir)) != NULL) { |
|
329 const char *d_name = FS2OTTD(dirent->d_name); |
|
330 char filename[MAX_PATH]; |
|
331 |
|
332 if (!FiosIsValidFile(path, dirent, &sb)) continue; |
|
333 |
|
334 snprintf(filename, lengthof(filename), "%s%s", path, d_name); |
|
335 |
|
336 if (sb.st_mode & S_IFDIR) { |
|
337 /* Directory */ |
|
338 if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue; |
|
339 AppendPathSeparator(filename, lengthof(filename)); |
|
340 num += ScanPath(filename, basepath_length); |
|
341 } else if (sb.st_mode & S_IFREG) { |
|
342 /* File */ |
|
343 char *ext = strrchr(filename, '.'); |
|
344 |
|
345 /* If no extension or extension isn't .grf, skip the file */ |
|
346 if (ext == NULL) continue; |
|
347 if (strcasecmp(ext, ".grf") != 0) continue; |
|
348 |
|
349 if (ScanPathAddGrf(filename + basepath_length)) num++; |
|
350 } |
|
351 } |
|
352 |
|
353 closedir(dir); |
|
354 |
|
355 return num; |
|
356 } |
|
357 |
|
358 static uint ScanTar(TarFileList::iterator tar) |
|
359 { |
|
360 uint num = 0; |
|
361 const char *filename = (*tar).first.c_str(); |
|
362 const char *ext = strrchr(filename, '.'); |
|
363 |
|
364 /* If no extension or extension isn't .grf, skip the file */ |
|
365 if (ext == NULL) return false; |
|
366 if (strcasecmp(ext, ".grf") != 0) return false; |
|
367 |
|
368 if (ScanPathAddGrf(filename)) num++; |
|
369 |
|
370 return num; |
|
371 } |
|
372 |
|
373 /** |
327 /** |
374 * Simple sorter for GRFS |
328 * Simple sorter for GRFS |
375 * @param p1 the first GRFConfig * |
329 * @param p1 the first GRFConfig * |
376 * @param p2 the second GRFConfig * |
330 * @param p2 the second GRFConfig * |
377 * @return the same strcmp would return for the name of the NewGRF. |
331 * @return the same strcmp would return for the name of the NewGRF. |
386 } |
340 } |
387 |
341 |
388 /* Scan for all NewGRFs */ |
342 /* Scan for all NewGRFs */ |
389 void ScanNewGRFFiles() |
343 void ScanNewGRFFiles() |
390 { |
344 { |
391 Searchpath sp; |
|
392 char path[MAX_PATH]; |
|
393 TarFileList::iterator tar; |
|
394 uint num = 0; |
|
395 |
|
396 ClearGRFConfigList(&_all_grfs); |
345 ClearGRFConfigList(&_all_grfs); |
397 |
346 |
398 DEBUG(grf, 1, "Scanning for NewGRFs"); |
347 DEBUG(grf, 1, "Scanning for NewGRFs"); |
399 FOR_ALL_SEARCHPATHS(sp) { |
348 uint num = GRFFileScanner::DoScan(); |
400 FioAppendDirectory(path, MAX_PATH, sp, DATA_DIR); |
|
401 num += ScanPath(path, strlen(path)); |
|
402 } |
|
403 FOR_ALL_TARS(tar) { |
|
404 num += ScanTar(tar); |
|
405 } |
|
406 |
349 |
407 DEBUG(grf, 1, "Scan complete, found %d files", num); |
350 DEBUG(grf, 1, "Scan complete, found %d files", num); |
408 if (num == 0 || _all_grfs == NULL) return; |
351 if (num == 0 || _all_grfs == NULL) return; |
409 |
352 |
410 /* Sort the linked list using quicksort. |
353 /* Sort the linked list using quicksort. |