mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Implement an API rate limiter
This commit is contained in:
@@ -396,6 +396,8 @@ MainWindow::MainWindow(QSettings &initSettings
|
||||
connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(validateFailed(QString)), this, SLOT(validationFailed(QString)));
|
||||
connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)),
|
||||
this, SLOT(updateWindowTitle(const QString&, bool)));
|
||||
connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)),
|
||||
NexusInterface::instance(&m_PluginContainer), SLOT(setRateMax(const QString&, bool)));
|
||||
|
||||
connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString)));
|
||||
connect(ui->tabWidget, SIGNAL(currentChanged(int)), &TutorialManager::instance(), SIGNAL(tabChanged(int)));
|
||||
@@ -430,6 +432,11 @@ MainWindow::MainWindow(QSettings &initSettings
|
||||
connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas()));
|
||||
m_SaveMetaTimer.start(5000);
|
||||
|
||||
m_NexusLimitTimer.setTimerType(Qt::TimerType::PreciseTimer);
|
||||
m_NexusLimitTimer.setSingleShot(false);
|
||||
connect(&m_NexusLimitTimer, SIGNAL(timeout()), NexusInterface::instance(&m_PluginContainer), SLOT(calculateRequests()));
|
||||
m_NexusLimitTimer.start(1000);
|
||||
|
||||
setCategoryListVisible(initSettings.value("categorylist_visible", true).toBool());
|
||||
FileDialogMemory::restore(initSettings);
|
||||
|
||||
@@ -5526,6 +5533,7 @@ void MainWindow::nxmDescriptionAvailable(QString gameName, int modID, QVariant u
|
||||
std::vector<ModInfo::Ptr> modsList = ModInfo::getByModID(gameName, modID);
|
||||
for (auto mod : modsList) {
|
||||
mod->setNexusDescription(result["description"].toString());
|
||||
mod->setNewestVersion(result["version"].toString());
|
||||
|
||||
if ((mod->endorsedState() != ModInfo::ENDORSED_NEVER) && (result.contains("endorsement"))) {
|
||||
QVariantMap endorsement = result["endorsement"].toMap();
|
||||
|
||||
@@ -348,6 +348,7 @@ private:
|
||||
QTimer m_CheckBSATimer;
|
||||
QTimer m_SaveMetaTimer;
|
||||
QTimer m_UpdateProblemsTimer;
|
||||
QTimer m_NexusLimitTimer;
|
||||
|
||||
QFuture<void> m_MetaSave;
|
||||
|
||||
|
||||
+26
-2
@@ -148,7 +148,7 @@ QAtomicInt NexusInterface::NXMRequestInfo::s_NextID(0);
|
||||
|
||||
|
||||
NexusInterface::NexusInterface(PluginContainer *pluginContainer)
|
||||
: m_NMMVersion(), m_PluginContainer(pluginContainer)
|
||||
: m_NMMVersion(), m_PluginContainer(pluginContainer), m_RemainingRequests(300), m_MaxRequests(300)
|
||||
{
|
||||
m_MOVersion = createVersionInfo();
|
||||
|
||||
@@ -190,6 +190,16 @@ void NexusInterface::loginCompleted()
|
||||
nextRequest();
|
||||
}
|
||||
|
||||
void NexusInterface::setRateMax(const QString &userName, bool isPremium)
|
||||
{
|
||||
if (isPremium) {
|
||||
m_MaxRequests = 600;
|
||||
m_RemainingRequests = 600;
|
||||
} else {
|
||||
m_MaxRequests = 300;
|
||||
m_RemainingRequests = 300;
|
||||
}
|
||||
}
|
||||
|
||||
void NexusInterface::interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query)
|
||||
{
|
||||
@@ -459,6 +469,11 @@ void NexusInterface::nextRequest()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_RemainingRequests <= 0) {
|
||||
qWarning() << tr("You've exceeded the Nexus API rate limit and requests are now being throttled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (requiresLogin(m_RequestQueue.head()) && !getAccessManager()->validated()) {
|
||||
if (!getAccessManager()->validateAttempted()) {
|
||||
emit needLogin();
|
||||
@@ -468,6 +483,8 @@ void NexusInterface::nextRequest()
|
||||
}
|
||||
}
|
||||
|
||||
m_RemainingRequests--;
|
||||
|
||||
NXMRequestInfo info = m_RequestQueue.dequeue();
|
||||
info.m_Timeout = new QTimer(this);
|
||||
info.m_Timeout->setInterval(60000);
|
||||
@@ -634,6 +651,12 @@ void NexusInterface::requestTimeout()
|
||||
}
|
||||
}
|
||||
|
||||
void NexusInterface::calculateRequests()
|
||||
{
|
||||
if (m_RemainingRequests < m_MaxRequests)
|
||||
m_RemainingRequests++;
|
||||
}
|
||||
|
||||
namespace {
|
||||
QString get_management_url(MOBase::IPluginGame const *game)
|
||||
{
|
||||
@@ -661,7 +684,8 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
|
||||
, m_NexusGameID(game->nexusGameID())
|
||||
, m_GameName(game->gameNexusName())
|
||||
, m_Endorse(false)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
|
||||
, QString modVersion
|
||||
|
||||
@@ -349,6 +349,11 @@ signals:
|
||||
void nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
|
||||
void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, QNetworkReply::NetworkError error, const QString &errorString);
|
||||
|
||||
public slots:
|
||||
|
||||
void setRateMax(const QString &userName, bool isPremium);
|
||||
void calculateRequests();
|
||||
|
||||
private slots:
|
||||
|
||||
void requestFinished();
|
||||
@@ -418,6 +423,9 @@ private:
|
||||
|
||||
PluginContainer *m_PluginContainer;
|
||||
|
||||
int m_RemainingRequests;
|
||||
int m_MaxRequests;
|
||||
|
||||
};
|
||||
|
||||
#endif // NEXUSINTERFACE_H
|
||||
|
||||
@@ -252,8 +252,7 @@ void NXMAccessManager::validateFinished()
|
||||
QString test = jdoc.toJson();
|
||||
QString name = credentialsData.value("name").toString();
|
||||
bool premium = credentialsData.value("is_premium?").toBool();
|
||||
emit credentialsReceived(credentialsData.value("name").toString(),
|
||||
credentialsData.value("is_premium?").toBool());
|
||||
emit credentialsReceived(name, premium);
|
||||
|
||||
m_ValidateReply->deleteLater();
|
||||
m_ValidateReply = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user