OpenTTD Source: src/base_media_base.h Source File

OpenTTD Source 15.0-RC2

base_media_base.h
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#ifndef BASE_MEDIA_BASE_H
11#define BASE_MEDIA_BASE_H
12
13#include "fileio_func.h"
14#include "textfile_type.h"
15#include "textfile_gui.h"
16#include "3rdparty/md5/md5.h"
17#include <unordered_map>
18
19struct IniFile;
20struct IniGroup;
21struct IniItem;
22struct ContentInfo;
23
25 struct MD5File {
27 enum ChecksumResult : uint8_t {
28 CR_UNKNOWN,
29 CR_MATCH,
30 CR_MISMATCH,
31 CR_NO_FILE,
32 };
33
34 std::string filename;
35 MD5Hash hash;
36 std::string missing_warning;
37 ChecksumResult check_result;
38
39 ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const;
40};
41
43 template <class T> struct BaseSetTraits;
44
49template <class T>
50 struct BaseSet {
51 typedef std::unordered_map<std::string, std::string, StringHash, std::equal_to<>> TranslatedStrings;
52
54 static constexpr size_t NUM_FILES = BaseSetTraits<T>::num_files;
55
57 static constexpr bool SEARCH_IN_TARS = BaseSetTraits<T>::search_in_tars;
58
60 static constexpr std::string_view SET_TYPE = BaseSetTraits<T>::set_type;
61
62 std::string name;
63 std::string url;
64 TranslatedStrings description;
65 uint32_t shortname = 0;
66 std::vector<uint32_t> version;
67 bool fallback = false;
68
69 std::array<MD5File, BaseSet<T>::NUM_FILES> files{};
70 uint found_files = 0;
71 uint valid_files = 0;
72
77 int GetNumMissing() const
78 {
79 return BaseSet<T>::NUM_FILES - this->found_files;
80 }
81
87 int GetNumInvalid() const
88 {
89 return BaseSet<T>::NUM_FILES - this->valid_files;
90 }
91
92 void LogError(std::string_view full_filename, std::string_view detail, int level = 0) const;
93 const IniItem *GetMandatoryItem(std::string_view full_filename, const IniGroup &group, std::string_view name) const;
94
95 bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true);
96 void CopyCompatibleConfig([[maybe_unused]] const T &src) {}
97
106 const std::string &GetDescription(std::string_view isocode) const
107 {
108 if (!isocode.empty()) {
109 /* First the full ISO code */
110 auto desc = this->description.find(isocode);
111 if (desc != this->description.end()) return desc->second;
112
113 /* Then the first two characters */
114 desc = this->description.find(isocode.substr(0, 2));
115 if (desc != this->description.end()) return desc->second;
116 }
117 /* Then fall back */
118 return this->description.at(std::string{});
119 }
120
130 static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
131 {
132 return file->CheckMD5(subdir, SIZE_MAX);
133 }
134
140 std::optional<std::string> GetTextfile(TextfileType type) const
141 {
142 for (const auto &file : this->files) {
143 auto textfile = ::GetTextfile(type, BASESET_DIR, file.filename);
144 if (textfile.has_value()) {
145 return textfile;
146 }
147 }
148 return std::nullopt;
149 }
150
155 static std::span<const std::string_view> GetFilenames();
156};
157
162template <class Tbase_set>
163 class BaseMedia : FileScanner {
164protected:
165 static inline std::vector<std::unique_ptr<Tbase_set>> available_sets;
166 static inline std::vector<std::unique_ptr<Tbase_set>> duplicate_sets;
167 static inline const Tbase_set *used_set;
168
169 bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename) override;
170
175 static std::string_view GetExtension();
176
181 static std::span<const std::unique_ptr<Tbase_set>> GetDuplicateSets() { return BaseMedia<Tbase_set>::duplicate_sets; }
182public:
188 static bool DetermineBestSet();
189
191 static uint FindSets()
192 {
193 BaseMedia<Tbase_set> fs;
194 /* Searching in tars is only done in the old "data" directories basesets. */
195 uint num = fs.Scan(GetExtension(), Tbase_set::SEARCH_IN_TARS ? OLD_DATA_DIR : OLD_GM_DIR, Tbase_set::SEARCH_IN_TARS);
196 return num + fs.Scan(GetExtension(), BASESET_DIR, Tbase_set::SEARCH_IN_TARS);
197 }
198
203 static std::span<const std::unique_ptr<Tbase_set>> GetAvailableSets() { return BaseMedia<Tbase_set>::available_sets; }
204
205 static bool SetSet(const Tbase_set *set);
206 static bool SetSetByName(const std::string &name);
207 static bool SetSetByShortname(uint32_t shortname);
208 static void GetSetsList(std::back_insert_iterator<std::string> &output_iterator);
209 static int GetNumSets();
210 static int GetIndexOfUsedSet();
211 static const Tbase_set *GetSet(int index);
212 static const Tbase_set *GetUsedSet();
213
220 static bool HasSet(const ContentInfo &ci, bool md5sum);
221};
222
230template <class Tbase_set>
231std::optional<std::string_view> TryGetBaseSetFile(const ContentInfo &ci, bool md5sum, std::span<const std::unique_ptr<Tbase_set>> sets);
232
233#endif /* BASE_MEDIA_BASE_H */
TryGetBaseSetFile
std::optional< std::string_view > TryGetBaseSetFile(const ContentInfo &ci, bool md5sum, std::span< const std::unique_ptr< Tbase_set > > sets)
Check whether there's a base set matching some information.
Definition base_media_func.h:328
BaseMedia
Base for all base media (graphics, sounds)
Definition base_media_base.h:163
BaseMedia::GetUsedSet
static const Tbase_set * GetUsedSet()
Return the used set.
Definition base_media_func.h:400
BaseMedia::available_sets
static std::vector< std::unique_ptr< Tbase_set > > available_sets
All available sets.
Definition base_media_base.h:165
BaseMedia::AddFile
bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename) override
Add a file with the given filename.
Definition base_media_func.h:188
BaseMedia::SetSetByShortname
static bool SetSetByShortname(uint32_t shortname)
Set the set to be used.
Definition base_media_func.h:287
BaseMedia::GetSetsList
static void GetSetsList(std::back_insert_iterator< std::string > &output_iterator)
Returns a list with the sets.
Definition base_media_func.h:306
BaseMedia::GetAvailableSets
static std::span< const std::unique_ptr< Tbase_set > > GetAvailableSets()
Return the available sets.
Definition base_media_base.h:203
BaseMedia::GetNumSets
static int GetNumSets()
Count the number of available graphics sets.
Definition base_media_func.h:357
BaseMedia::FindSets
static uint FindSets()
Do the scan for files.
Definition base_media_base.h:191
BaseMedia::HasSet
static bool HasSet(const ContentInfo &ci, bool md5sum)
Check whether we have an set with the exact characteristics as ci.
Definition base_media_func.h:346
BaseMedia::used_set
static const Tbase_set * used_set
The currently used set.
Definition base_media_base.h:167
BaseMedia::duplicate_sets
static std::vector< std::unique_ptr< Tbase_set > > duplicate_sets
All sets that aren't available, but needed for not downloading base sets when a newer version than th...
Definition base_media_base.h:166
BaseMedia::GetSet
static const Tbase_set * GetSet(int index)
Get the name of the graphics set at the specified index.
Definition base_media_func.h:385
BaseMedia::GetIndexOfUsedSet
static int GetIndexOfUsedSet()
Get the index of the currently active graphics set.
Definition base_media_func.h:369
BaseMedia::DetermineBestSet
static bool DetermineBestSet()
Determine the graphics pack that has to be used.
BaseMedia::SetSetByName
static bool SetSetByName(const std::string &name)
Set the set to be used.
Definition base_media_func.h:267
BaseMedia::GetDuplicateSets
static std::span< const std::unique_ptr< Tbase_set > > GetDuplicateSets()
Return the duplicate sets.
Definition base_media_base.h:181
BaseMedia::SetSet
static bool SetSet(const Tbase_set *set)
Set the set to be used.
Definition base_media_func.h:250
BaseMedia::GetExtension
static std::string_view GetExtension()
Get the extension that is used to identify this set.
FileScanner
Helper for scanning for files with a given name.
Definition fileio_func.h:37
FileScanner::Scan
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
fileio_func.h
Functions for Standard In/Out file operations.
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition fileio_type.h:88
OLD_DATA_DIR
@ OLD_DATA_DIR
Old subdirectory for the data.
Definition fileio_type.h:95
OLD_GM_DIR
@ OLD_GM_DIR
Old subdirectory for the music.
Definition fileio_type.h:94
BASESET_DIR
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition fileio_type.h:96
BaseSetTraits
Defines the traits of a BaseSet type.
Definition base_media_base.h:43
BaseSet
Information about a single base set.
Definition base_media_base.h:50
BaseSet::found_files
uint found_files
Number of the files that could be found.
Definition base_media_base.h:70
BaseSet::files
std::array< MD5File, BaseSet< T >::NUM_FILES > files
All files part of this set.
Definition base_media_base.h:69
BaseSet::valid_files
uint valid_files
Number of the files that could be found and are valid.
Definition base_media_base.h:71
BaseSet::LogError
void LogError(std::string_view full_filename, std::string_view detail, int level=0) const
Log error from reading basesets.
Definition base_media_func.h:29
BaseSet::GetMandatoryItem
const IniItem * GetMandatoryItem(std::string_view full_filename, const IniGroup &group, std::string_view name) const
Try to read a single piece of metadata and return nullptr if it doesn't exist.
Definition base_media_func.h:43
BaseSet::url
std::string url
URL for information about the base set.
Definition base_media_base.h:63
BaseSet::description
TranslatedStrings description
Description of the base set.
Definition base_media_base.h:64
BaseSet::NUM_FILES
static constexpr size_t NUM_FILES
Number of files in this set.
Definition base_media_base.h:54
BaseSet::GetTextfile
std::optional< std::string > GetTextfile(TextfileType type) const
Search a textfile file next to this base media.
Definition base_media_base.h:140
BaseSet::SEARCH_IN_TARS
static constexpr bool SEARCH_IN_TARS
Whether to search in the tars or not.
Definition base_media_base.h:57
BaseSet::CheckMD5
static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
Calculate and check the MD5 hash of the supplied file.
Definition base_media_base.h:130
BaseSet::GetFilenames
static std::span< const std::string_view > GetFilenames()
Get the internal names of the files in this set.
BaseSet::SET_TYPE
static constexpr std::string_view SET_TYPE
BaseSet type name.
Definition base_media_base.h:60
BaseSet::name
std::string name
The name of the base set.
Definition base_media_base.h:62
BaseSet::fallback
bool fallback
This set is a fallback set, i.e. it should be used only as last resort.
Definition base_media_base.h:67
BaseSet::FillSetDetails
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename=true)
Read the set information from a loaded ini.
Definition base_media_func.h:60
BaseSet::GetNumMissing
int GetNumMissing() const
Get the number of missing files.
Definition base_media_base.h:77
BaseSet::version
std::vector< uint32_t > version
The version of this base set.
Definition base_media_base.h:66
BaseSet::shortname
uint32_t shortname
Four letter short variant of the name.
Definition base_media_base.h:65
BaseSet::GetNumInvalid
int GetNumInvalid() const
Get the number of invalid files.
Definition base_media_base.h:87
BaseSet::GetDescription
const std::string & GetDescription(std::string_view isocode) const
Get the description for the given ISO code.
Definition base_media_base.h:106
ContentInfo
Container for all important information about a piece of content.
Definition tcp_content_type.h:56
IniFile
Ini file that supports both loading and saving.
Definition ini_type.h:86
IniGroup
A group within an ini file.
Definition ini_type.h:34
IniItem
A single "line" in an ini file.
Definition ini_type.h:23
MD5File
Structure holding filename and MD5 information about a single file.
Definition base_media_base.h:25
MD5File::missing_warning
std::string missing_warning
warning when this file is missing
Definition base_media_base.h:36
MD5File::check_result
ChecksumResult check_result
cached result of md5 check
Definition base_media_base.h:37
MD5File::CheckMD5
ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const
Calculate and check the MD5 hash of the supplied filename.
Definition gfxinit.cpp:444
MD5File::ChecksumResult
ChecksumResult
The result of a checksum check.
Definition base_media_base.h:27
MD5File::CR_MATCH
@ CR_MATCH
The file did exist and the md5 checksum did match.
Definition base_media_base.h:29
MD5File::CR_MISMATCH
@ CR_MISMATCH
The file did exist, just the md5 checksum did not match.
Definition base_media_base.h:30
MD5File::CR_NO_FILE
@ CR_NO_FILE
The file did not exist.
Definition base_media_base.h:31
MD5File::CR_UNKNOWN
@ CR_UNKNOWN
The file has not been checked yet.
Definition base_media_base.h:28
MD5File::hash
MD5Hash hash
md5 sum of the file
Definition base_media_base.h:35
MD5File::filename
std::string filename
filename
Definition base_media_base.h:34
textfile_gui.h
GUI functions related to textfiles.
textfile_type.h
Types related to textfiles.
TextfileType
TextfileType
Additional text files accompanying Tar archives.
Definition textfile_type.h:14