Luanti 5.11.0-dev
 
Loading...
Searching...
No Matches
clientmedia.h
Go to the documentation of this file.
1// Luanti
2// SPDX-License-Identifier: LGPL-2.1-or-later
3// Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5#pragma once
6
7#include "irrlichttypes.h"
8#include "filecache.h"
9#include "util/basic_macros.h"
10#include <map>
11#include <set>
12#include <vector>
13#include <unordered_map>
14
15class Client;
16struct HTTPFetchResult;
17
18#define MTHASHSET_FILE_SIGNATURE 0x4d544853 // 'MTHS'
19#define MTHASHSET_FILE_NAME "index.mth"
20
21// Store file into media cache (unless it exists already)
22// Caller should check the hash.
23// return true if something was updated
24bool clientMediaUpdateCache(const std::string &raw_hash,
25 const std::string &filedata);
26
27// Copy file on disk(!) into media cache (unless it exists already)
28bool clientMediaUpdateCacheCopy(const std::string &raw_hash,
29 const std::string &path);
30
31// more of a base class than an interface but this name was most convenient...
33{
34public:
36
37 virtual bool isStarted() const = 0;
38
39 // If this returns true, the downloader is done and can be deleted
40 virtual bool isDone() const = 0;
41
42 // Add a file to the list of required file (but don't fetch it yet)
43 virtual void addFile(const std::string &name, const std::string &sha1) = 0;
44
45 // Add a remote server to the list; ignored if not built with cURL
46 virtual void addRemoteServer(const std::string &baseurl) = 0;
47
48 // Steps the media downloader:
49 // - May load media into client by calling client->loadMedia()
50 // - May check media cache for files
51 // - May add files to media cache
52 // - May start remote transfers by calling httpfetch_async
53 // - May check for completion of current remote transfers
54 // - May start conventional transfers by calling client->request_media()
55 // - May inform server that all media has been loaded
56 // by calling client->received_media()
57 // After step has been called once, don't call addFile/addRemoteServer.
58 virtual void step(Client *client) = 0;
59
60 // Must be called for each file received through TOCLIENT_MEDIA
61 // returns true if this file belongs to this downloader
62 virtual bool conventionalTransferDone(const std::string &name,
63 const std::string &data, Client *client) = 0;
64
65protected:
67 virtual ~IClientMediaDownloader() = default;
68
69 // Forwards the call to the appropriate Client method
70 virtual bool loadMedia(Client *client, const std::string &data,
71 const std::string &name) = 0;
72
73 bool tryLoadFromCache(const std::string &name, const std::string &sha1,
74 Client *client);
75
76 bool checkAndLoad(const std::string &name, const std::string &sha1,
77 const std::string &data, bool is_from_cache, Client *client);
78
79 // Filesystem-based media cache
82};
83
85{
86public:
89
90 float getProgress() const {
91 if (m_uncached_count >= 1)
92 return 1.0f * m_uncached_received_count /
93 m_uncached_count;
94
95 return 0.0f;
96 }
97
98 bool isStarted() const override {
99 return m_initial_step_done;
100 }
101
102 bool isDone() const override {
103 return m_initial_step_done &&
104 m_uncached_received_count == m_uncached_count;
105 }
106
107 void addFile(const std::string &name, const std::string &sha1) override;
108
109 void addRemoteServer(const std::string &baseurl) override;
110
111 void step(Client *client) override;
112
114 const std::string &name,
115 const std::string &data,
116 Client *client) override;
117
118protected:
119 bool loadMedia(Client *client, const std::string &data,
120 const std::string &name) override;
121
122private:
123 struct FileStatus {
125 std::string sha1;
127 std::vector<s32> available_remotes;
128 };
129
131 std::string baseurl;
133 };
134
135 void initialStep(Client *client);
136 void remoteHashSetReceived(const HTTPFetchResult &fetch_result);
137 void remoteMediaReceived(const HTTPFetchResult &fetch_result,
138 Client *client);
139 s32 selectRemoteServer(FileStatus *filestatus);
140 void startRemoteMediaTransfers();
141 void startConventionalTransfers(Client *client);
142
143 static void deSerializeHashSet(const std::string &data,
144 std::set<std::string> &result);
145 std::string serializeRequiredHashSet();
146
147 // Maps filename to file status
148 std::map<std::string, FileStatus*> m_files;
149
150 // Array of remote media servers
151 std::vector<RemoteServerStatus*> m_remotes;
152
153 // Has an attempt been made to load media files from the file cache?
154 // Have hash sets been requested from remote servers?
155 bool m_initial_step_done = false;
156
157 // Total number of media files to load
158 s32 m_uncached_count = 0;
159
160 // Number of media files that have been received
161 s32 m_uncached_received_count = 0;
162
163 // Status of remote transfers
165 u64 m_httpfetch_next_id = 0;
166 s32 m_httpfetch_active = 0;
167 s32 m_httpfetch_active_limit = 0;
168 s32 m_outstanding_hash_sets = 0;
169 std::unordered_map<u64, std::string> m_remote_file_transfers;
170
171 // All files up to this name have either been received from a
172 // remote server or failed on all remote servers, so those files
173 // don't need to be looked at again
174 // (use m_files.upper_bound(m_name_bound) to get an iterator)
175 std::string m_name_bound = "";
176
177};
178
179// A media downloader that only downloads a single file.
180// It does/doesn't do several things the normal downloader does:
181// - won't fetch hash sets from remote servers
182// - will mark loaded media as coming from file push
183// - writing to file cache is optional
185{
186public:
187 SingleMediaDownloader(bool write_to_cache);
189
190 bool isStarted() const override {
191 return m_stage > STAGE_INIT;
192 }
193
194 bool isDone() const override {
195 return m_stage >= STAGE_DONE;
196 }
197
198 void addFile(const std::string &name, const std::string &sha1) override;
199
200 void addRemoteServer(const std::string &baseurl) override;
201
202 void step(Client *client) override;
203
204 bool conventionalTransferDone(const std::string &name,
205 const std::string &data, Client *client) override;
206
207protected:
208 bool loadMedia(Client *client, const std::string &data,
209 const std::string &name) override;
210
211private:
212 void initialStep(Client *client);
213 void remoteMediaReceived(const HTTPFetchResult &fetch_result, Client *client);
214 void startRemoteMediaTransfer();
215 void startConventionalTransfer(Client *client);
216
217 enum Stage {
219 STAGE_CACHE_CHECKED, // we have tried to load the file from cache
220 STAGE_DONE
221 };
222
223 // Information about the one file we want to fetch
224 std::string m_file_name;
225 std::string m_file_sha1;
227
228 // Array of remote media servers
229 std::vector<std::string> m_remotes;
230
231 enum Stage m_stage = STAGE_INIT;
232
233 // Status of remote transfers
234 unsigned long m_httpfetch_caller;
235 unsigned long m_httpfetch_next_id = 0;
236
237};
#define DISABLE_CLASS_COPY(C)
Definition basic_macros.h:26
Definition clientmedia.h:85
bool isStarted() const override
Definition clientmedia.h:98
u64 m_httpfetch_caller
Definition clientmedia.h:164
bool isDone() const override
Definition clientmedia.h:102
float getProgress() const
Definition clientmedia.h:90
std::vector< RemoteServerStatus * > m_remotes
Definition clientmedia.h:151
std::map< std::string, FileStatus * > m_files
Definition clientmedia.h:148
std::unordered_map< u64, std::string > m_remote_file_transfers
Definition clientmedia.h:169
Definition client.h:105
Definition filecache.h:13
Definition clientmedia.h:33
virtual bool loadMedia(Client *client, const std::string &data, const std::string &name)=0
virtual void addRemoteServer(const std::string &baseurl)=0
bool checkAndLoad(const std::string &name, const std::string &sha1, const std::string &data, bool is_from_cache, Client *client)
Definition clientmedia.cpp:531
virtual bool conventionalTransferDone(const std::string &name, const std::string &data, Client *client)=0
virtual void addFile(const std::string &name, const std::string &sha1)=0
FileCache m_media_cache
Definition clientmedia.h:80
virtual bool isStarted() const =0
virtual void step(Client *client)=0
bool m_write_to_cache
Definition clientmedia.h:81
virtual bool isDone() const =0
bool tryLoadFromCache(const std::string &name, const std::string &sha1, Client *client)
Definition clientmedia.cpp:518
Definition clientmedia.h:185
std::string m_file_name
Definition clientmedia.h:224
unsigned long m_httpfetch_caller
Definition clientmedia.h:234
bool isDone() const override
Definition clientmedia.h:194
bool isStarted() const override
Definition clientmedia.h:190
Stage
Definition clientmedia.h:217
@ STAGE_CACHE_CHECKED
Definition clientmedia.h:219
@ STAGE_INIT
Definition clientmedia.h:218
s32 m_current_remote
Definition clientmedia.h:226
std::string m_file_sha1
Definition clientmedia.h:225
std::vector< std::string > m_remotes
Definition clientmedia.h:229
bool clientMediaUpdateCacheCopy(const std::string &raw_hash, const std::string &path)
Definition clientmedia.cpp:34
bool clientMediaUpdateCache(const std::string &raw_hash, const std::string &filedata)
Definition clientmedia.cpp:25
Definition activeobjectmgr.cpp:11
Definition clientmedia.h:123
s32 current_remote
Definition clientmedia.h:126
bool received
Definition clientmedia.h:124
std::string sha1
Definition clientmedia.h:125
std::vector< s32 > available_remotes
Definition clientmedia.h:127
Definition clientmedia.h:130
std::string baseurl
Definition clientmedia.h:131
s32 active_count
Definition clientmedia.h:132
Definition httpfetch.h:81