Luanti 5.15.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
122 static std::string makeReferer(Client *client);
123
124private:
125 struct FileStatus {
127 std::string sha1;
129 std::vector<s32> available_remotes;
130 };
131
133 std::string baseurl;
135 };
136
137 void initialStep(Client *client);
138 void remoteHashSetReceived(const HTTPFetchResult &fetch_result);
139 void remoteMediaReceived(const HTTPFetchResult &fetch_result,
140 Client *client);
141 s32 selectRemoteServer(FileStatus *filestatus);
142 void startRemoteMediaTransfers();
143 void startConventionalTransfers(Client *client);
144
145 static void deSerializeHashSet(const std::string &data,
146 std::set<std::string> &result);
147
148 // Maps filename to file status
149 std::map<std::string, FileStatus*> m_files;
150
151 // Array of remote media servers
152 std::vector<RemoteServerStatus*> m_remotes;
153
154 // Has an attempt been made to load media files from the file cache?
155 // Have hash sets been requested from remote servers?
156 bool m_initial_step_done = false;
157
158 // Total number of media files to load
159 s32 m_uncached_count = 0;
160
161 // Number of media files that have been received
162 s32 m_uncached_received_count = 0;
163
164 // Status of remote transfers
166 u64 m_httpfetch_next_id = 0;
167 s32 m_httpfetch_active = 0;
168 s32 m_httpfetch_active_limit = 0;
169 s32 m_outstanding_hash_sets = 0;
170 std::unordered_map<u64, std::string> m_remote_file_transfers;
171
172 // All files up to this name have either been received from a
173 // remote server or failed on all remote servers, so those files
174 // don't need to be looked at again
175 // (use m_files.upper_bound(m_name_bound) to get an iterator)
176 std::string m_name_bound = "";
177
178};
179
180// A media downloader that only downloads a single file.
181// It does/doesn't do several things the normal downloader does:
182// - won't fetch hash sets from remote servers
183// - will mark loaded media as coming from file push
184// - writing to file cache is optional
186{
187public:
188 SingleMediaDownloader(bool write_to_cache);
190
191 bool isStarted() const override {
192 return m_stage > STAGE_INIT;
193 }
194
195 bool isDone() const override {
196 return m_stage >= STAGE_DONE;
197 }
198
199 void addFile(const std::string &name, const std::string &sha1) override;
200
201 void addRemoteServer(const std::string &baseurl) override;
202
203 void step(Client *client) override;
204
205 bool conventionalTransferDone(const std::string &name,
206 const std::string &data, Client *client) override;
207
208protected:
209 bool loadMedia(Client *client, const std::string &data,
210 const std::string &name) override;
211
212private:
213 void initialStep(Client *client);
214 void remoteMediaReceived(const HTTPFetchResult &fetch_result, Client *client);
215 void startRemoteMediaTransfer();
216 void startConventionalTransfer(Client *client);
217
218 enum Stage {
220 STAGE_CACHE_CHECKED, // we have tried to load the file from cache
221 STAGE_DONE
222 };
223
224 // Information about the one file we want to fetch
225 std::string m_file_name;
226 std::string m_file_sha1;
228
229 // Array of remote media servers
230 std::vector<std::string> m_remotes;
231
232 enum Stage m_stage = STAGE_INIT;
233
234 // Status of remote transfers
235 unsigned long m_httpfetch_caller;
236 unsigned long m_httpfetch_next_id = 0;
237
238};
#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:165
bool isDone() const override
Definition clientmedia.h:102
float getProgress() const
Definition clientmedia.h:90
std::vector< RemoteServerStatus * > m_remotes
Definition clientmedia.h:152
std::map< std::string, FileStatus * > m_files
Definition clientmedia.h:149
std::unordered_map< u64, std::string > m_remote_file_transfers
Definition clientmedia.h:170
Definition client.h:106
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:534
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:521
Definition clientmedia.h:186
std::string m_file_name
Definition clientmedia.h:225
unsigned long m_httpfetch_caller
Definition clientmedia.h:235
bool isDone() const override
Definition clientmedia.h:195
bool isStarted() const override
Definition clientmedia.h:191
Stage
Definition clientmedia.h:218
@ STAGE_CACHE_CHECKED
Definition clientmedia.h:220
@ STAGE_INIT
Definition clientmedia.h:219
s32 m_current_remote
Definition clientmedia.h:227
std::string m_file_sha1
Definition clientmedia.h:226
std::vector< std::string > m_remotes
Definition clientmedia.h:230
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:125
s32 current_remote
Definition clientmedia.h:128
bool received
Definition clientmedia.h:126
std::string sha1
Definition clientmedia.h:127
std::vector< s32 > available_remotes
Definition clientmedia.h:129
Definition clientmedia.h:132
std::string baseurl
Definition clientmedia.h:133
s32 active_count
Definition clientmedia.h:134
Definition httpfetch.h:81