Manages HTTP metadata cache for efficient file downloads and validation.
Class: HttpMetaCache
Header: launcher/net/HttpMetaCache.h
Inherits: QObject
Constructor
HttpMetaCache (QString path = QString ());
Path to the cache index file. If empty, cache is memory-only.
Cache Entry Management
getEntry(QString base, QString resource_path)
Retrieves an entry from cache without validation. Use only for specific caching needs.
resolveEntry(QString base, QString resource_path, QString expected_etag)
Gets an entry and verifies it isn’t stale. This is the recommended method for most use cases.
updateEntry(MetaEntryPtr stale_entry)
Updates a previously resolved stale entry. Returns true on success.
Eviction
evictEntry(MetaEntryPtr entry)
Removes a specific entry from the cache. Returns true on success.
Clears all entries from the cache. Returns true on success.
Base Path Management
addBase(QString base, QString base_root)
Registers a base path for a cache category (e.g., “assets”, “libraries”).
getBasePath(QString base)
Returns the root path for a registered base.
Persistence
Loads cache entries from the index file.
Immediately saves cache entries to the index file.
Schedules a save operation to occur later (batched saves).
Example Usage
#include "net/HttpMetaCache.h"
#include "Application.h"
// Get the global cache
HttpMetaCache * cache = APPLICATION -> metacache ();
// Add a base path
cache -> addBase ( "assets" , "/path/to/assets" );
// Resolve an entry (checks if cached file is still valid)
MetaEntryPtr entry = cache -> resolveEntry (
"assets" ,
"minecraft/sounds/ambient/cave/cave1.ogg"
);
if (entry && ! entry -> isStale ()) {
qDebug () << "Using cached file:" << entry -> getFullPath ();
} else {
qDebug () << "Need to download file" ;
// After download:
entry -> setETag (response_etag);
entry -> setStale ( false );
cache -> updateEntry (entry);
}
// Save cache
cache -> SaveEventually ();
MetaEntry
Represents a single cached file with metadata.
Class: MetaEntry
Header: launcher/net/HttpMetaCache.h
Staleness
Returns true if the entry is stale and should be re-downloaded.
Marks the entry as stale or fresh.
File Path
Returns the full filesystem path to the cached file.
HTTP Validation
Returns the HTTP ETag for cache validation.
Returns the MD5 checksum of the file.
setMD5Sum(QString md5sum)
Sets the MD5 checksum.
Timestamps
getRemoteChangedTimestamp()
Returns the remote file’s last modified timestamp (RFC 2822 format).
setRemoteChangedTimestamp(QString timestamp)
Sets the remote changed timestamp.
setLocalChangedTimestamp(qint64 timestamp)
Sets the local file’s changed timestamp.
Cache Expiration
Returns the current age of the cached entry.
setCurrentAge(qint64 age)
Sets the current age.
Returns the maximum age before expiration.
setMaximumAge(qint64 age)
Sets the maximum age.
Returns true if the entry has expired (accounting for offset).
makeEternal(bool eternal)
Makes the entry never expire (eternal = true) or expire normally (eternal = false).
Returns true if the entry never expires.
NetJob
Manages concurrent network operations (downloads, uploads).
Class: NetJob
Header: launcher/net/NetJob.h
Inherits: ConcurrentTask
Constructor
explicit NetJob (
QString job_name,
QNetworkAccessManager * network,
int max_concurrent = - 1
);
Human-readable name for the job.
Network manager to use for requests.
Maximum concurrent requests (-1 for unlimited).
Adding Actions
addNetAction(Net::NetRequest::Ptr action)
Adds a network request to the job. Returns true on success.
Returns the number of network actions in the job.
Failure Handling
Returns list of failed network requests.
Returns list of file paths that failed to download.
setAskRetry(bool askRetry)
Sets whether to prompt the user to retry failed downloads.
Control
Aborts the network job. Returns true if successful.
Returns true if the job can be aborted.
Example Usage
#include "net/NetJob.h"
#include "net/Download.h"
#include "Application.h"
// Create a network job
NetJob * job = new NetJob ( "Download assets" , APPLICATION -> network ());
// Add downloads
for ( const QString & url : urls) {
auto dl = Net :: Download :: makeFile (
QUrl (url),
"/path/to/destination.jar"
);
job -> addNetAction (dl);
}
// Connect signals
connect (job, & NetJob ::succeeded, []() {
qDebug () << "All downloads completed" ;
});
connect (job, & NetJob ::failed, [ job ]( QString reason ) {
qDebug () << "Job failed:" << reason;
for ( auto * failed : job -> getFailedActions ()) {
qDebug () << " Failed:" << failed -> url (). toString ();
}
});
connect (job, & NetJob ::progress, []( qint64 current , qint64 total ) {
qDebug () << "Progress:" << current << "/" << total;
});
// Start the job
job -> start ();
Net::Download
Handles individual file downloads with caching support.
Class: Net::Download
Namespace: Net
Header: launcher/net/Download.h
Inherits: Net::NetRequest
Factory Methods
Cached Download
File Download
Byte Array Download
static Download :: Ptr makeCached (
QUrl url ,
MetaEntryPtr entry ,
Options options = Option :: NoOptions
);
Creates a download that uses the HTTP metadata cache. static Download :: Ptr makeFile (
QUrl url ,
QString path ,
Options options = Option :: NoOptions
);
Creates a download that saves to a file. static std :: pair < Download :: Ptr , QByteArray * > makeByteArray (
QUrl url ,
Options options = Option :: NoOptions
);
Creates a download that returns data in a QByteArray. The array lives as long as the Download object.
Example Usage
#include "net/Download.h"
#include "net/NetJob.h"
// Download to file
auto dl = Net :: Download :: makeFile (
QUrl ( "https://example.com/mod.jar" ),
"/path/to/mods/mod.jar"
);
// Download with caching
MetaEntryPtr entry = cache -> resolveEntry ( "downloads" , "mod.jar" );
auto cached_dl = Net :: Download :: makeCached (
QUrl ( "https://example.com/mod.jar" ),
entry
);
// Download to memory
auto [dl_mem, data] = Net :: Download :: makeByteArray (
QUrl ( "https://example.com/api/version.json" )
);
connect ( dl_mem . get (), & Task ::succeeded, [ data ]() {
QJsonDocument doc = QJsonDocument :: fromJson ( * data);
qDebug () << "JSON:" << doc . object ();
});
// Add to job
NetJob * job = new NetJob ( "Downloads" , network);
job -> addNetAction (dl);
job -> addNetAction (cached_dl);
job -> addNetAction (dl_mem);
job -> start ();
Net::NetRequest
Base class for all network requests.
Class: Net::NetRequest
Namespace: Net
Header: launcher/net/NetRequest.h
Inherits: Task
Options
enum class Option {
NoOptions = 0 ,
AcceptLocalFiles = 1 , // Allow file:// URLs
MakeEternal = 2 , // Cache entry never expires
AutoRetry = 4 // Auto-retry on HTTP 429
};
Q_DECLARE_FLAGS (Options, Option)
Configuration
setNetwork(QNetworkAccessManager* network)
Sets the network access manager.
addValidator(Validator* v)
Adds a validator to check the downloaded data.
Adds a header proxy for modifying request headers.
Auto-Retry
enableAutoRetry(bool enable)
Enables automatic retry on HTTP 429 (Too Many Requests) errors.
Returns the HTTP status code.
error()
QNetworkReply::NetworkError
Returns the network error code.
Returns the error description.
Control
Aborts the request. Returns true on success.
Returns true if the request can be aborted.
Example Usage
#include "net/NetRequest.h"
#include "net/Download.h"
auto dl = Net :: Download :: makeFile (
QUrl ( "https://api.example.com/data.json" ),
"/tmp/data.json" ,
Net :: NetRequest :: Option ::AutoRetry
);
// Enable auto-retry for rate limiting
dl -> enableAutoRetry ( true );
connect ( dl . get (), & Task ::succeeded, [ dl ]() {
qDebug () << "Downloaded successfully" ;
qDebug () << "Status code:" << dl -> replyStatusCode ();
});
connect ( dl . get (), & Task ::failed, [ dl ]( QString reason ) {
qDebug () << "Download failed:" << reason;
qDebug () << "Error:" << dl -> errorString ();
});
dl -> start ();
Common Patterns
Show Downloading with Progress
auto dl = Net :: Download :: makeFile (url, path);
connect ( dl . get (), & Task ::progress, []( qint64 current , qint64 total ) {
int percent = (total > 0 ) ? (current * 100 / total) : 0 ;
qDebug () << "Progress:" << percent << "%" ;
});
dl -> start ();
Show Batch Downloads with NetJob
NetJob * job = new NetJob ( "Batch download" , network, 4 ); // max 4 concurrent
for ( const auto & [url, path] : downloads) {
auto dl = Net :: Download :: makeFile (url, path);
job -> addNetAction (dl);
}
connect (job, & Task ::finished, [ job ]() {
if ( job -> wasSuccessful ()) {
qDebug () << "All downloads completed" ;
} else {
qDebug () << "Some downloads failed:" << job -> getFailedFiles ();
}
});
job -> start ();