OpenTTD Source 20260108-master-g8ba1860eaa
fios.cpp
Go to the documentation of this file.
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "stdafx.h"
11#include "3rdparty/md5/md5.h"
13#include "fileio_func.h"
14#include "fios.h"
16#include "screenshot.h"
17#include "string_func.h"
18#include "strings_func.h"
19#include "tar_type.h"
20#include <sys/stat.h>
21#include <charconv>
22#include <filesystem>
23
24#include "table/strings.h"
25
26#include "safeguards.h"
27
28/* Variables to display file lists */
29static std::string *_fios_path = nullptr;
30SortingBits _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING;
31
32/* OS-specific functions are taken from their respective files (win32/unix .c) */
33extern bool FiosIsRoot(const std::string &path);
34extern bool FiosIsHiddenFile(const std::filesystem::path &path);
35extern void FiosGetDrives(FileList &file_list);
36
37/* get the name of an oldstyle savegame */
38extern std::string GetOldSaveGameName(std::string_view file);
39
45bool FiosItem::operator< (const FiosItem &other) const
46{
47 int r = false;
48
49 if ((_savegame_sort_order & SORT_BY_NAME) == 0 && (*this).mtime != other.mtime) {
50 r = ClampTo<int32_t>(this->mtime - other.mtime);
51 } else {
52 r = StrNaturalCompare(this->title.GetDecodedString(), other.title.GetDecodedString());
53 }
54 if (r == 0) return false;
55 return (_savegame_sort_order & SORT_DESCENDING) ? r > 0 : r < 0;
56}
57
64void FileList::BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop, bool show_dirs)
65{
66 this->clear();
67
68 assert(fop == SLO_LOAD || fop == SLO_SAVE);
69 switch (abstract_filetype) {
70 case FT_NONE:
71 break;
72
73 case FT_SAVEGAME:
74 FiosGetSavegameList(fop, show_dirs, *this);
75 break;
76
77 case FT_SCENARIO:
78 FiosGetScenarioList(fop, show_dirs, *this);
79 break;
80
81 case FT_HEIGHTMAP:
82 FiosGetHeightmapList(fop, show_dirs, *this);
83 break;
84
85 case FT_TOWN_DATA:
86 FiosGetTownDataList(fop, show_dirs, *this);
87 break;
88
89 default:
90 NOT_REACHED();
91 }
92}
93
100const FiosItem *FileList::FindItem(std::string_view file)
101{
102 for (const auto &it : *this) {
103 const FiosItem *item = &it;
104 if (file == item->name) return item;
105 if (file == item->title.GetDecodedString()) return item;
106 }
107
108 /* If no name matches, try to parse it as number */
109 StringConsumer consumer{file};
110 auto number = consumer.TryReadIntegerBase<int>(10);
111 if (number.has_value() && !consumer.AnyBytesLeft() && IsInsideMM(*number, 0, this->size())) return &this->at(*number);
112
113 /* As a last effort assume it is an OpenTTD savegame and
114 * that the ".sav" part was not given. */
115 std::string long_file(file);
116 long_file += ".sav";
117 for (const auto &it : *this) {
118 const FiosItem *item = &it;
119 if (long_file == item->name) return item;
120 if (long_file == item->title.GetDecodedString()) return item;
121 }
122
123 return nullptr;
124}
125
130{
131 return *_fios_path;
132}
133
139bool FiosBrowseTo(const FiosItem *item)
140{
141 switch (item->type.detailed) {
142 case DFT_FIOS_DRIVE:
143#if defined(_WIN32)
144 assert(_fios_path != nullptr);
145 *_fios_path = std::string{ item->name, 0, 1 } + ":" PATHSEP;
146#endif
147 break;
148
149 case DFT_INVALID:
150 break;
151
152 case DFT_FIOS_PARENT: {
153 assert(_fios_path != nullptr);
154 auto s = _fios_path->find_last_of(PATHSEPCHAR);
155 if (s != std::string::npos && s != 0) {
156 _fios_path->erase(s); // Remove last path separator character, so we can go up one level.
157 }
158
159 s = _fios_path->find_last_of(PATHSEPCHAR);
160 if (s != std::string::npos) {
161 _fios_path->erase(s + 1); // go up a directory
162 }
163 break;
164 }
165
166 case DFT_FIOS_DIR:
167 assert(_fios_path != nullptr);
168 *_fios_path += item->name;
169 *_fios_path += PATHSEP;
170 break;
171
172 case DFT_FIOS_DIRECT:
173 assert(_fios_path != nullptr);
174 *_fios_path = item->name;
175 break;
176
177 default:
178 return false;
179 }
180
181 return true;
182}
183
191static std::string FiosMakeFilename(const std::string *path, std::string_view name, std::string_view ext)
192{
193 std::string_view base_path;
194
195 if (path != nullptr) {
196 base_path = *path;
197 /* Remove trailing path separator, if present */
198 if (!base_path.empty() && base_path.back() == PATHSEPCHAR) base_path.remove_suffix(1);
199 }
200
201 /* Don't append the extension if it is already there */
202 auto period = name.find_last_of('.');
203 if (period != std::string_view::npos && StrEqualsIgnoreCase(name.substr(period), ext)) ext = "";
204
205 return fmt::format("{}{}{}{}", base_path, PATHSEP, name, ext);
206}
207
213std::string FiosMakeSavegameName(std::string_view name)
214{
215 std::string_view extension = (_game_mode == GM_EDITOR) ? ".scn" : ".sav";
216
217 return FiosMakeFilename(_fios_path, name, extension);
218}
219
225std::string FiosMakeHeightmapName(std::string_view name)
226{
227 return FiosMakeFilename(_fios_path, name, fmt::format(".{}", GetCurrentScreenshotExtension()));
228}
229
230typedef std::tuple<FiosType, std::string> FiosGetTypeAndNameProc(SaveLoadOperation fop, std::string_view filename, std::string_view ext);
231
237 FiosGetTypeAndNameProc *callback_proc;
239public:
249
250 bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename) override;
251};
252
258bool FiosFileScanner::AddFile(const std::string &filename, size_t, const std::string &)
259{
260 auto sep = filename.rfind('.');
261 if (sep == std::string::npos) return false;
262 std::string ext = filename.substr(sep);
263
264 auto [type, title] = this->callback_proc(this->fop, filename, ext);
265 if (type == FIOS_TYPE_INVALID) return false;
266
267 for (const auto &fios : file_list) {
268 if (filename == fios.name) return false;
269 }
270
271 FiosItem *fios = &file_list.emplace_back();
272
273 std::error_code error_code;
274 auto write_time = std::filesystem::last_write_time(OTTD2FS(filename), error_code);
275 if (error_code) {
276 fios->mtime = 0;
277 } else {
278 fios->mtime = std::chrono::duration_cast<std::chrono::milliseconds>(write_time.time_since_epoch()).count();
279 }
280
281 fios->type = type;
282 fios->name = filename;
283
284 /* If the file doesn't have a title, use its filename */
285 if (title.empty()) {
286 auto ps = filename.rfind(PATHSEPCHAR);
287 fios->title = GetEncodedString(STR_JUST_RAW_STRING, StrMakeValid(filename.substr((ps == std::string::npos ? 0 : ps + 1))));
288 } else {
289 fios->title = GetEncodedString(STR_JUST_RAW_STRING, StrMakeValid(title));
290 };
291
292 return true;
293}
294
295
304static void FiosGetFileList(SaveLoadOperation fop, bool show_dirs, FiosGetTypeAndNameProc *callback_proc, Subdirectory subdir, FileList &file_list)
305{
306 size_t sort_start = 0;
307
308 file_list.clear();
309
310 assert(_fios_path != nullptr);
311
312 if (show_dirs) {
313 /* A parent directory link exists if we are not in the root directory */
314 if (!FiosIsRoot(*_fios_path)) {
315 FiosItem &fios = file_list.emplace_back();
316 fios.type = FIOS_TYPE_PARENT;
317 fios.mtime = 0;
318 fios.name = "..";
319 fios.title = GetEncodedString(STR_SAVELOAD_PARENT_DIRECTORY, ".."sv);
320 sort_start = file_list.size();
321 }
322
323 /* Show subdirectories */
324 std::error_code error_code;
325 for (const auto &dir_entry : std::filesystem::directory_iterator(OTTD2FS(*_fios_path), error_code)) {
326 if (!dir_entry.is_directory()) continue;
327 if (FiosIsHiddenFile(dir_entry) && dir_entry.path().filename() != PERSONAL_DIR) continue;
328
329 FiosItem &fios = file_list.emplace_back();
330 fios.type = FIOS_TYPE_DIR;
331 fios.mtime = 0;
332 fios.name = FS2OTTD(dir_entry.path().filename().native());
333 fios.title = GetEncodedString(STR_SAVELOAD_DIRECTORY, fios.name + PATHSEP);
334 }
335
336 /* Sort the subdirs always by name, ascending, remember user-sorting order */
337 SortingBits order = _savegame_sort_order;
338 _savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING;
339 std::sort(file_list.begin() + sort_start, file_list.end());
340 _savegame_sort_order = order;
341 }
342
343 /* This is where to start sorting for the filenames */
344 sort_start = file_list.size();
345
346 /* Show files */
347 FiosFileScanner scanner(fop, callback_proc, file_list);
348 if (subdir == NO_DIRECTORY) {
349 scanner.Scan({}, *_fios_path, false);
350 } else {
351 scanner.Scan({}, subdir, true, true);
352 }
353
354 std::sort(file_list.begin() + sort_start, file_list.end());
355
356 /* Show drives */
357 FiosGetDrives(file_list);
358}
359
367static std::string GetFileTitle(std::string_view file, Subdirectory subdir)
368{
369 std::string filename = fmt::format("{}.title", file);
370 auto f = FioFOpenFile(filename, "r", subdir);
371 if (!f.has_value()) return {};
372
373 char title[80];
374 size_t read = fread(title, 1, lengthof(title), *f);
375
376 assert(read <= lengthof(title));
377 return StrMakeValid(std::string_view{title, read});
378}
379
389std::tuple<FiosType, std::string> FiosGetSavegameListCallback(SaveLoadOperation fop, std::string_view file, std::string_view ext)
390{
391 /* Show savegame files
392 * .SAV OpenTTD saved game
393 * .SS1 Transport Tycoon Deluxe preset game
394 * .SV1 Transport Tycoon Deluxe (Patch) saved game
395 * .SV2 Transport Tycoon Deluxe (Patch) saved 2-player game */
396
397 if (StrEqualsIgnoreCase(ext, ".sav")) {
398 return { FIOS_TYPE_FILE, GetFileTitle(file, SAVE_DIR) };
399 }
400
401 if (fop == SLO_LOAD) {
402 if (StrEqualsIgnoreCase(ext, ".ss1") || StrEqualsIgnoreCase(ext, ".sv1") ||
403 StrEqualsIgnoreCase(ext, ".sv2")) {
404 return { FIOS_TYPE_OLDFILE, GetOldSaveGameName(file) };
405 }
406 }
407
408 return { FIOS_TYPE_INVALID, {} };
409}
410
418void FiosGetSavegameList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
419{
420 static std::optional<std::string> fios_save_path;
421
422 if (!fios_save_path) fios_save_path = FioFindDirectory(SAVE_DIR);
423
424 _fios_path = &(*fios_save_path);
425
426 FiosGetFileList(fop, show_dirs, &FiosGetSavegameListCallback, NO_DIRECTORY, file_list);
427}
428
438std::tuple<FiosType, std::string> FiosGetScenarioListCallback(SaveLoadOperation fop, std::string_view file, std::string_view ext)
439{
440 /* Show scenario files
441 * .SCN OpenTTD style scenario file
442 * .SV0 Transport Tycoon Deluxe (Patch) scenario
443 * .SS0 Transport Tycoon Deluxe preset scenario */
444 if (StrEqualsIgnoreCase(ext, ".scn")) {
445 return { FIOS_TYPE_SCENARIO, GetFileTitle(file, SCENARIO_DIR) };
446
447 }
448
449 if (fop == SLO_LOAD) {
450 if (StrEqualsIgnoreCase(ext, ".sv0") || StrEqualsIgnoreCase(ext, ".ss0")) {
451 return { FIOS_TYPE_OLD_SCENARIO, GetOldSaveGameName(file) };
452 }
453 }
454
455 return { FIOS_TYPE_INVALID, {} };
456}
457
465void FiosGetScenarioList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
466{
467 static std::optional<std::string> fios_scn_path;
468
469 /* Copy the default path on first run or on 'New Game' */
470 if (!fios_scn_path) fios_scn_path = FioFindDirectory(SCENARIO_DIR);
471
472 _fios_path = &(*fios_scn_path);
473
474 std::string base_path = FioFindDirectory(SCENARIO_DIR);
475 Subdirectory subdir = (fop == SLO_LOAD && base_path == *_fios_path) ? SCENARIO_DIR : NO_DIRECTORY;
476 FiosGetFileList(fop, show_dirs, &FiosGetScenarioListCallback, subdir, file_list);
477}
478
479std::tuple<FiosType, std::string> FiosGetHeightmapListCallback(SaveLoadOperation, std::string_view file, std::string_view ext)
480{
481 /* Show heightmap files
482 * .PNG PNG Based heightmap files
483 * .BMP BMP Based heightmap files
484 */
485
486 FiosType type = FIOS_TYPE_INVALID;
487
488#ifdef WITH_PNG
489 if (StrEqualsIgnoreCase(ext, ".png")) type = FIOS_TYPE_PNG;
490#endif /* WITH_PNG */
491
492 if (StrEqualsIgnoreCase(ext, ".bmp")) type = FIOS_TYPE_BMP;
493
494 if (type == FIOS_TYPE_INVALID) return { FIOS_TYPE_INVALID, {} };
495
496 TarFileList::iterator it = _tar_filelist[SCENARIO_DIR].find(file);
497 if (it != _tar_filelist[SCENARIO_DIR].end()) {
498 /* If the file is in a tar and that tar is not in a heightmap
499 * directory we are for sure not supposed to see it.
500 * Examples of this are pngs part of documentation within
501 * collections of NewGRFs or 32 bpp graphics replacement PNGs.
502 */
503 bool match = false;
504 for (Searchpath sp : _valid_searchpaths) {
505 std::string buf = FioGetDirectory(sp, HEIGHTMAP_DIR);
506
507 if (it->second.tar_filename.starts_with(buf)) {
508 match = true;
509 break;
510 }
511 }
512
513 if (!match) return { FIOS_TYPE_INVALID, {} };
514 }
515
516 return { type, GetFileTitle(file, HEIGHTMAP_DIR) };
517}
518
525void FiosGetHeightmapList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
526{
527 static std::optional<std::string> fios_hmap_path;
528
529 if (!fios_hmap_path) fios_hmap_path = FioFindDirectory(HEIGHTMAP_DIR);
530
531 _fios_path = &(*fios_hmap_path);
532
533 std::string base_path = FioFindDirectory(HEIGHTMAP_DIR);
534 Subdirectory subdir = base_path == *_fios_path ? HEIGHTMAP_DIR : NO_DIRECTORY;
535 FiosGetFileList(fop, show_dirs, &FiosGetHeightmapListCallback, subdir, file_list);
536}
537
544static std::tuple<FiosType, std::string> FiosGetTownDataListCallback(SaveLoadOperation fop, std::string_view file, std::string_view ext)
545{
546 if (fop == SLO_LOAD) {
547 if (StrEqualsIgnoreCase(ext, ".json")) {
548 return { FIOS_TYPE_JSON, GetFileTitle(file, SAVE_DIR) };
549 }
550 }
551
552 return { FIOS_TYPE_INVALID, {} };
553}
554
561void FiosGetTownDataList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
562{
563 static std::optional<std::string> fios_town_data_path;
564
565 if (!fios_town_data_path) fios_town_data_path = FioFindDirectory(HEIGHTMAP_DIR);
566
567 _fios_path = &(*fios_town_data_path);
568
569 std::string base_path = FioFindDirectory(HEIGHTMAP_DIR);
570 Subdirectory subdir = base_path == *_fios_path ? HEIGHTMAP_DIR : NO_DIRECTORY;
571 FiosGetFileList(fop, show_dirs, &FiosGetTownDataListCallback, subdir, file_list);
572}
573
578std::string_view FiosGetScreenshotDir()
579{
580 static std::optional<std::string> fios_screenshot_path;
581
582 if (!fios_screenshot_path) fios_screenshot_path = FioFindDirectory(SCREENSHOT_DIR);
583
584 return *fios_screenshot_path;
585}
586
589 uint32_t scenid;
590 MD5Hash md5sum;
591 std::string filename;
592
593 bool operator == (const ScenarioIdentifier &other) const
594 {
595 return this->scenid == other.scenid && this->md5sum == other.md5sum;
596 }
597};
598
602class ScenarioScanner : protected FileScanner, public std::vector<ScenarioIdentifier> {
603 bool scanned;
604public:
607
612 void Scan(bool rescan)
613 {
614 if (this->scanned && !rescan) return;
615
616 this->FileScanner::Scan(".id", SCENARIO_DIR, true, true);
617 this->scanned = true;
618 }
619
620 bool AddFile(const std::string &filename, size_t, const std::string &) override
621 {
622 auto f = FioFOpenFile(filename, "r", SCENARIO_DIR);
623 if (!f.has_value()) return false;
624
626 int fret = fscanf(*f, "%u", &id.scenid);
627 if (fret != 1) return false;
628 id.filename = filename;
629
630 Md5 checksum;
631 uint8_t buffer[1024];
632 size_t len, size;
633
634 /* open the scenario file, but first get the name.
635 * This is safe as we check on extension which
636 * must always exist. */
637 f = FioFOpenFile(filename.substr(0, filename.rfind('.')), "rb", SCENARIO_DIR, &size);
638 if (!f.has_value()) return false;
639
640 /* calculate md5sum */
641 while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, *f)) != 0 && size != 0) {
642 size -= len;
643 checksum.Append(buffer, len);
644 }
645 checksum.Finish(id.md5sum);
646
647 include(*this, id);
648 return true;
649 }
650};
651
654
661std::optional<std::string_view> FindScenario(const ContentInfo &ci, bool md5sum)
662{
663 _scanner.Scan(false);
664
665 for (ScenarioIdentifier &id : _scanner) {
666 if (md5sum ? (id.md5sum == ci.md5sum)
667 : (id.scenid == ci.unique_id)) {
668 return id.filename;
669 }
670 }
671
672 return std::nullopt;
673}
674
681bool HasScenario(const ContentInfo &ci, bool md5sum)
682{
683 return FindScenario(ci, md5sum).has_value();
684}
685
690{
691 _scanner.Scan(true);
692}
693
698FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(prefix), number(-1)
699{
700 static std::optional<std::string> _autosave_path;
701 if (!_autosave_path) _autosave_path = FioFindDirectory(AUTOSAVE_DIR);
702
703 static std::string _prefix;
704
705 /* Callback for FiosFileScanner. */
706 static FiosGetTypeAndNameProc *const proc = [](SaveLoadOperation, std::string_view file, std::string_view ext) {
707 if (StrEqualsIgnoreCase(ext, ".sav") && file.starts_with(_prefix)) return std::tuple(FIOS_TYPE_FILE, std::string{});
708 return std::tuple(FIOS_TYPE_INVALID, std::string{});
709 };
710
711 /* Prefix to check in the callback. */
712 _prefix = *_autosave_path + this->prefix;
713
714 /* Get the save list. */
715 FileList list;
716 FiosFileScanner scanner(SLO_SAVE, proc, list);
717 scanner.Scan(".sav", *_autosave_path, false);
718
719 /* Find the number for the most recent save, if any. */
720 if (list.begin() != list.end()) {
721 SortingBits order = _savegame_sort_order;
722 _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING;
723 std::sort(list.begin(), list.end());
724 _savegame_sort_order = order;
725
726 std::string name = list.begin()->title.GetDecodedString();
727 std::from_chars(name.data() + this->prefix.size(), name.data() + name.size(), this->number);
728 }
729}
730
736{
737 if (++this->number >= _settings_client.gui.max_num_autosaves) this->number = 0;
738 return fmt::format("{}{}.sav", this->prefix, this->number);
739}
740
746{
747 return fmt::format("-{}.sav", this->prefix);
748}
std::string GetDecodedString() const
Decode the encoded string.
Definition strings.cpp:207
List of file information.
Definition fios.h:87
void BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop, bool show_dirs)
Construct a file list with the given kind of files, for the stated purpose.
Definition fios.cpp:64
const FiosItem * FindItem(std::string_view file)
Find file information of a file by its name from the file list.
Definition fios.cpp:100
Helper for scanning for files with a given name.
Definition fileio_func.h:37
uint Scan(std::string_view extension, Subdirectory sd, bool tars=true, bool recursive=true)
Scan for files with the given extension in the given search path.
Definition fileio.cpp:1115
Scanner to scan for a particular type of FIOS file.
Definition fios.cpp:235
FiosFileScanner(SaveLoadOperation fop, FiosGetTypeAndNameProc *callback_proc, FileList &file_list)
Create the scanner.
Definition fios.cpp:246
SaveLoadOperation fop
The kind of file we are looking for.
Definition fios.cpp:236
bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename) override
Try to add a fios item set with the given filename.
Definition fios.cpp:258
FileList & file_list
Destination of the found files.
Definition fios.cpp:238
FiosGetTypeAndNameProc * callback_proc
Callback to check whether the file may be added.
Definition fios.cpp:237
Scanner to find the unique IDs of scenarios.
Definition fios.cpp:602
bool scanned
Whether we've already scanned.
Definition fios.cpp:603
void Scan(bool rescan)
Scan, but only if it's needed.
Definition fios.cpp:612
bool AddFile(const std::string &filename, size_t, const std::string &) override
Add a file with the given filename.
Definition fios.cpp:620
ScenarioScanner()
Initialise.
Definition fios.cpp:606
Parse data from a string / buffer.
std::optional< T > TryReadIntegerBase(int base, bool clamp=false)
Try to read and parse an integer in number 'base', and then advance the reader.
bool include(Container &container, typename Container::const_reference &item)
Helper function to append an item to a container if it is not already contained.
std::optional< FileHandle > FioFOpenFile(std::string_view filename, std::string_view mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
Definition fileio.cpp:242
Functions for standard in/out file operations.
SaveLoadOperation
Operation performed on the file.
Definition fileio_type.h:52
@ SLO_SAVE
File is being saved.
Definition fileio_type.h:55
@ SLO_LOAD
File is being loaded.
Definition fileio_type.h:54
@ DFT_FIOS_DRIVE
A drive (letter) entry.
Definition fileio_type.h:41
@ DFT_FIOS_DIR
A directory entry.
Definition fileio_type.h:43
@ DFT_FIOS_PARENT
A parent directory entry.
Definition fileio_type.h:42
@ DFT_INVALID
Unknown or invalid file.
Definition fileio_type.h:48
@ DFT_FIOS_DIRECT
Direct filename.
Definition fileio_type.h:44
Searchpath
Types of searchpaths OpenTTD might use.
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition fileio_type.h:88
@ NO_DIRECTORY
A path without any base directory.
@ SCREENSHOT_DIR
Subdirectory for all screenshots.
@ SCENARIO_DIR
Base directory for all scenarios.
Definition fileio_type.h:92
@ SAVE_DIR
Base directory for all savegames.
Definition fileio_type.h:90
@ HEIGHTMAP_DIR
Subdirectory of scenario for heightmaps.
Definition fileio_type.h:93
@ AUTOSAVE_DIR
Subdirectory of save for autosaves.
Definition fileio_type.h:91
AbstractFileType
The different abstract types of files that the system knows about.
Definition fileio_type.h:17
@ FT_SCENARIO
old or new scenario
Definition fileio_type.h:20
@ FT_HEIGHTMAP
heightmap file
Definition fileio_type.h:21
@ FT_NONE
nothing to do
Definition fileio_type.h:18
@ FT_SAVEGAME
old or new savegame
Definition fileio_type.h:19
@ FT_TOWN_DATA
town data file
Definition fileio_type.h:22
std::tuple< FiosType, std::string > FiosGetScenarioListCallback(SaveLoadOperation fop, std::string_view file, std::string_view ext)
Callback for FiosGetFileList.
Definition fios.cpp:438
static std::tuple< FiosType, std::string > FiosGetTownDataListCallback(SaveLoadOperation fop, std::string_view file, std::string_view ext)
Callback for FiosGetTownDataList.
Definition fios.cpp:544
std::optional< std::string_view > FindScenario(const ContentInfo &ci, bool md5sum)
Find a given scenario based on its unique ID.
Definition fios.cpp:661
std::string FiosMakeSavegameName(std::string_view name)
Make a save game or scenario filename from a name.
Definition fios.cpp:213
std::tuple< FiosType, std::string > FiosGetSavegameListCallback(SaveLoadOperation fop, std::string_view file, std::string_view ext)
Callback for FiosGetFileList.
Definition fios.cpp:389
static std::string GetFileTitle(std::string_view file, Subdirectory subdir)
Get the title of a file, which (if exists) is stored in a file named the same as the data file but wi...
Definition fios.cpp:367
std::string FiosGetCurrentPath()
Get the current path/working directory.
Definition fios.cpp:129
static std::string FiosMakeFilename(const std::string *path, std::string_view name, std::string_view ext)
Construct a filename from its components in destination buffer buf.
Definition fios.cpp:191
void FiosGetSavegameList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
Get a list of savegames.
Definition fios.cpp:418
void FiosGetHeightmapList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
Get a list of heightmaps.
Definition fios.cpp:525
static void FiosGetFileList(SaveLoadOperation fop, bool show_dirs, FiosGetTypeAndNameProc *callback_proc, Subdirectory subdir, FileList &file_list)
Fill the list of the files in a directory, according to some arbitrary rule.
Definition fios.cpp:304
void ScanScenarios()
Force a (re)scan of the scenarios.
Definition fios.cpp:689
std::string FiosMakeHeightmapName(std::string_view name)
Construct a filename for a height map.
Definition fios.cpp:225
bool HasScenario(const ContentInfo &ci, bool md5sum)
Check whether we've got a given scenario based on its unique ID.
Definition fios.cpp:681
void FiosGetScenarioList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
Get a list of scenarios.
Definition fios.cpp:465
std::string_view FiosGetScreenshotDir()
Get the directory for screenshots.
Definition fios.cpp:578
bool FiosBrowseTo(const FiosItem *item)
Browse to a new path based on the passed item, starting at _fios_path.
Definition fios.cpp:139
static ScenarioScanner _scanner
Scanner for scenarios.
Definition fios.cpp:653
void FiosGetTownDataList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
Get a list of town data files.
Definition fios.cpp:561
Declarations for savegames operations.
void FiosGetSavegameList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
Get a list of savegames.
Definition fios.cpp:418
void FiosGetHeightmapList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
Get a list of heightmaps.
Definition fios.cpp:525
void FiosGetScenarioList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
Get a list of scenarios.
Definition fios.cpp:465
void FiosGetTownDataList(SaveLoadOperation fop, bool show_dirs, FileList &file_list)
Get a list of town data files.
Definition fios.cpp:561
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Part of the network protocol handling content distribution.
A number of safeguards to prevent using unsafe methods.
std::string_view GetCurrentScreenshotExtension()
Get filename extension of current screenshot file format.
Functions to make screenshots.
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
bool StrEqualsIgnoreCase(std::string_view str1, std::string_view str2)
Compares two string( view)s for equality, while ignoring the case of the characters.
Definition string.cpp:323
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition string.cpp:427
static void StrMakeValid(Builder &builder, StringConsumer &consumer, StringValidationSettings settings)
Copies the valid (UTF-8) characters from consumer to the builder.
Definition string.cpp:119
Parse strings.
Functions related to low-level strings.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
Functions related to OTTD's strings.
GUISettings gui
settings related to the GUI
Container for all important information about a piece of content.
uint32_t unique_id
Unique ID; either GRF ID or shortname.
MD5Hash md5sum
The MD5 checksum.
Deals with finding savegames.
Definition fios.h:78
bool operator<(const FiosItem &other) const
Compare two FiosItem's.
Definition fios.cpp:45
std::string Filename()
Generate a savegame name and number according to _settings_client.gui.max_num_autosaves.
Definition fios.cpp:735
FiosNumberedSaveName(const std::string &prefix)
Constructs FiosNumberedSaveName.
Definition fios.cpp:698
std::string Extension()
Generate an extension for a savegame name.
Definition fios.cpp:745
Elements of a file system that are recognized.
Definition fileio_type.h:63
DetailedFileType detailed
Detailed file type.
Definition fileio_type.h:65
uint8_t max_num_autosaves
controls how many autosavegames are made before the game starts to overwrite (names them 0 to max_num...
Basic data to distinguish a scenario.
Definition fios.cpp:588
uint32_t scenid
ID for the scenario (generated by content).
Definition fios.cpp:589
MD5Hash md5sum
MD5 checksum of file.
Definition fios.cpp:590
std::string filename
filename of the file.
Definition fios.cpp:591
Structs, typedefs and macros used for TAR file handling.
std::wstring OTTD2FS(std::string_view name)
Convert from OpenTTD's encoding to a wide string.
Definition win32.cpp:357
std::string FS2OTTD(std::wstring_view name)
Convert to OpenTTD's encoding from a wide string.
Definition win32.cpp:340