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