123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- /*
- Minetest
- Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
- This program 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. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- #ifndef CLIENTMEDIA_HEADER
- #define CLIENTMEDIA_HEADER
- #include "irrlichttypes.h"
- #include "filecache.h"
- #include <ostream>
- #include <map>
- #include <set>
- #include <vector>
- class Client;
- struct HTTPFetchResult;
- #define MTHASHSET_FILE_SIGNATURE 0x4d544853 // 'MTHS'
- #define MTHASHSET_FILE_NAME "index.mth"
- class ClientMediaDownloader
- {
- public:
- ClientMediaDownloader();
- ~ClientMediaDownloader();
- float getProgress() const {
- if (m_uncached_count >= 1)
- return 1.0 * m_uncached_received_count /
- m_uncached_count;
- else
- return 0.0;
- }
- bool isStarted() const {
- return m_initial_step_done;
- }
- // If this returns true, the downloader is done and can be deleted
- bool isDone() const {
- return m_initial_step_done &&
- m_uncached_received_count == m_uncached_count;
- }
- // Add a file to the list of required file (but don't fetch it yet)
- void addFile(std::string name, std::string sha1);
- // Add a remote server to the list; ignored if not built with cURL
- void addRemoteServer(std::string baseurl);
- // Steps the media downloader:
- // - May load media into client by calling client->loadMedia()
- // - May check media cache for files
- // - May add files to media cache
- // - May start remote transfers by calling httpfetch_async
- // - May check for completion of current remote transfers
- // - May start conventional transfers by calling client->request_media()
- // - May inform server that all media has been loaded
- // by calling client->received_media()
- // After step has been called once, don't call addFile/addRemoteServer.
- void step(Client *client);
- // Must be called for each file received through TOCLIENT_MEDIA
- void conventionalTransferDone(
- const std::string &name,
- const std::string &data,
- Client *client);
- private:
- struct FileStatus {
- bool received;
- std::string sha1;
- s32 current_remote;
- std::vector<s32> available_remotes;
- };
- struct RemoteServerStatus {
- std::string baseurl;
- s32 active_count;
- bool request_by_filename;
- };
- void initialStep(Client *client);
- void remoteHashSetReceived(const HTTPFetchResult &fetch_result);
- void remoteMediaReceived(const HTTPFetchResult &fetch_result,
- Client *client);
- s32 selectRemoteServer(FileStatus *filestatus);
- void startRemoteMediaTransfers();
- void startConventionalTransfers(Client *client);
- bool checkAndLoad(const std::string &name, const std::string &sha1,
- const std::string &data, bool is_from_cache,
- Client *client);
- std::string serializeRequiredHashSet();
- static void deSerializeHashSet(const std::string &data,
- std::set<std::string> &result);
- // Maps filename to file status
- std::map<std::string, FileStatus*> m_files;
- // Array of remote media servers
- std::vector<RemoteServerStatus*> m_remotes;
- // Filesystem-based media cache
- FileCache m_media_cache;
- // Has an attempt been made to load media files from the file cache?
- // Have hash sets been requested from remote servers?
- bool m_initial_step_done;
- // Total number of media files to load
- s32 m_uncached_count;
- // Number of media files that have been received
- s32 m_uncached_received_count;
- // Status of remote transfers
- unsigned long m_httpfetch_caller;
- unsigned long m_httpfetch_next_id;
- long m_httpfetch_timeout;
- s32 m_httpfetch_active;
- s32 m_httpfetch_active_limit;
- s32 m_outstanding_hash_sets;
- std::map<unsigned long, std::string> m_remote_file_transfers;
- // All files up to this name have either been received from a
- // remote server or failed on all remote servers, so those files
- // don't need to be looked at again
- // (use m_files.upper_bound(m_name_bound) to get an iterator)
- std::string m_name_bound;
- };
- #endif // !CLIENTMEDIA_HEADER
|