mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-10-31 07:25:22 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			151 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| 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
 |