61 lines
1.5 KiB
C
Raw Normal View History

2019-02-10 21:46:39 -05:00
#pragma once
#include "util.h"
#include <winhttp.h>
using InternetHandle = AutoHandle<Functor<WinHttpCloseHandle>>;
2019-02-12 23:54:33 -05:00
inline std::optional<std::wstring> ReceiveHttpRequest(HINTERNET request)
2019-02-10 21:46:39 -05:00
{
WinHttpReceiveResponse(request, NULL);
std::string data;
DWORD dwSize, dwDownloaded;
do
{
dwSize = 0;
WinHttpQueryDataAvailable(request, &dwSize);
if (!dwSize) break;
std::vector<char> buffer(dwSize);
WinHttpReadData(request, buffer.data(), dwSize, &dwDownloaded);
2019-02-12 23:54:33 -05:00
data.append(buffer.data(), dwDownloaded);
2019-02-10 21:46:39 -05:00
} while (dwSize > 0);
if (data.empty()) return {};
return StringToWideString(data);
}
2019-06-05 20:26:50 -04:00
inline void Unescape(std::wstring& text)
2019-02-10 21:46:39 -05:00
{
for (int i = 0; i < text.size(); ++i)
{
if (text[i] == L'\\')
{
text[i] = 0x200b;
if (text[i + 1] == L'r') text[i + 1] = 0x200b; // for some reason \r gets displayed as a newline
if (text[i + 1] == L'n') text[i + 1] = L'\n';
if (text[i + 1] == L't') text[i + 1] = L'\t';
}
}
}
2019-06-05 20:26:50 -04:00
class RateLimiter
{
public:
RateLimiter(int tokenCount, int delay) : tokenCount(tokenCount), delay(delay) {}
bool Request()
{
auto tokens = this->tokens.Acquire();
tokens->push_back(GetTickCount());
if (tokens->size() > tokenCount * 5) tokens->erase(tokens->begin(), tokens->begin() + tokenCount * 3);
tokens->erase(std::remove_if(tokens->begin(), tokens->end(), [this](DWORD token) { return GetTickCount() - token > delay; }), tokens->end());
return tokens->size() < tokenCount;
}
const int tokenCount, delay;
private:
Synchronized<std::vector<DWORD>> tokens;
};