Skip to content

Commit

Permalink
Add Update check
Browse files Browse the repository at this point in the history
  • Loading branch information
KyuubiRan committed Jun 26, 2023
1 parent 690147d commit ba7c5cb
Show file tree
Hide file tree
Showing 15 changed files with 289 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/.vscode
/.idea
/bin
/Downloader/src/dlver.h
17 changes: 17 additions & 0 deletions Downloader/Downloader.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
<PreBuildEvent>
<Command>python update_version.py</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
Expand All @@ -127,6 +130,9 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
<PreBuildEvent>
<Command>python update_version.py</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
Expand All @@ -145,6 +151,9 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
<PreBuildEvent>
<Command>python update_version.py</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
Expand All @@ -167,6 +176,9 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
<PreBuildEvent>
<Command>python update_version.py</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="src\api\Chimu.h" />
Expand Down Expand Up @@ -213,6 +225,7 @@
<ClInclude Include="src\api\Sayobot.h" />
<ClInclude Include="src\config\Field.h" />
<ClInclude Include="src\config\I18nManager.h" />
<ClInclude Include="src\dlver.h" />
<ClInclude Include="src\features\About.h" />
<ClInclude Include="src\features\CustomHotkey.h" />
<ClInclude Include="src\features\Downloader.h" />
Expand All @@ -224,9 +237,11 @@
<ClInclude Include="src\main.hpp" />
<ClInclude Include="src\HookManager.hpp" />
<ClInclude Include="src\misc\Color.h" />
<ClInclude Include="src\misc\glob.h" />
<ClInclude Include="src\misc\Hotkey.hpp" />
<ClInclude Include="src\misc\ISerializable.h" />
<ClInclude Include="src\misc\ResourcesLoader.hpp" />
<ClInclude Include="src\misc\VersionManager.h" />
<ClInclude Include="src\network\HttpRequest.h" />
<ClInclude Include="src\osu\Account.h" />
<ClInclude Include="src\osu\BeatmapManager.h" />
Expand Down Expand Up @@ -309,6 +324,7 @@
<ClCompile Include="src\features\HandleLinkHook.cpp" />
<ClCompile Include="src\features\MultiDownload.cpp" />
<ClCompile Include="src\features\Settings.cpp" />
<ClCompile Include="src\misc\VersionManager.cpp" />
<ClCompile Include="src\network\HttpRequest.cpp" />
<ClCompile Include="src\osu\Account.cpp" />
<ClCompile Include="src\osu\BeatmapManager.cpp" />
Expand Down Expand Up @@ -342,6 +358,7 @@
<Content Include="res\language\en_us.json" />
<Content Include="res\language\zh_cn.json" />
<Content Include="res\MiSans-Normal.ttf" />
<Content Include="update_version.py" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resource.rc" />
Expand Down
12 changes: 12 additions & 0 deletions Downloader/Downloader.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,15 @@
<ClInclude Include="src\api\chimu\Map.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\dlver.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\misc\glob.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\misc\VersionManager.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\dllmain.cpp">
Expand Down Expand Up @@ -353,6 +362,9 @@
<ClCompile Include="src\api\Chimu.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\misc\VersionManager.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Library Include="libraries\detours\detours-x64.lib" />
Expand Down
2 changes: 1 addition & 1 deletion Downloader/libraries/utility
9 changes: 8 additions & 1 deletion Downloader/res/language/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,12 @@
"IdSearchHotkey": "Toggle Sid/Bid Search UI Show",
"Main": "Main",
"Theme": "Theme",
"Paste": "Paste"
"Paste": "Paste",
"VersionChecking": "Checking update for BeatmapDownloader...",
"VersionIsLatest": "BeatmapDownloader is up to date!",
"FoundNewVersion": "Found new version: %s(%d)",
"VersionCheckFailed": "Cannot check latest version! code:%d",
"CurrentVersion": "Current Version: %s(%d)",
"GotoDownload": "Goto Download",
"CheckUpdate": "Check Update"
}
9 changes: 8 additions & 1 deletion Downloader/res/language/zh_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,12 @@
"IdSearchHotkey": "切换Sid/Bid搜索界面显示",
"Main": "主要",
"Theme": "主题",
"Paste": "粘贴"
"Paste": "粘贴",
"VersionChecking": "正在检查新版本...",
"VersionIsLatest": "谱面下载器已是最新版本!",
"FoundNewVersion": "发现新版本:%s(%d)",
"VersionCheckFailed": "版本更新检查失败!代码:%d",
"CurrentVersion": "当前版本:%s(%d)",
"GotoDownload": "前往下载",
"CheckUpdate": "检查更新"
}
19 changes: 19 additions & 0 deletions Downloader/src/features/About.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

#include "CustomHotkey.h"
#include "config/I18nManager.h"
#include "misc/Color.h"
#include "utils/gui_utils.h"
#include <shellapi.h>
#include "misc/VersionManager.h"

namespace features {

Expand All @@ -20,13 +23,29 @@ FeatureInfo &About::getInfo() {
return info;
}

using misc::VersionManager;

void About::drawMain() {
auto &lang = i18n::I18nManager::GetInstance();
ImGui::BeginGroupPanel(lang.getTextCStr("About"));
ImGui::Text("%s", lang.getTextCStr("ProjectAuthor"));
ImGui::Text("%s", lang.getTextCStr("ProjectLink"));
ImGui::SameLine();
ImGui::TextUrl("https://github.com/KyuubiRan/BeatmapDownloader");
ImGui::TextColored(color::Green, lang.getTextCStr("CurrentVersion"), VersionManager::GetCurrentVersionName().data(),
VersionManager::GetCurrentVersionCode());
ImGui::SameLine();
if (ImGui::Button(lang.getTextCStr("CheckUpdate"))) {
VersionManager::CheckUpdate(true);
}
if (!VersionManager::IsLatest()) {
ImGui::TextColored(color::Orange, lang.getTextCStr("FoundNewVersion"), VersionManager::GetLatestVersionName().data(),
VersionManager::GetLatestVersionCode());
ImGui::SameLine();
if (ImGui::Button(lang.getTextCStr("GotoDownload"))) {
ShellExecuteW(nullptr, L"open", L"https://github.com/KyuubiRan/BeatmapDownloader/releases/latest", nullptr, nullptr, SW_HIDE);
}
}
ImGui::EndGroupPanel();

ImGui::BeginGroupPanel(lang.getTextCStr("Hotkey"));
Expand Down
2 changes: 2 additions & 0 deletions Downloader/src/main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "osu/OsuConfigManager.h"
#include "ui/MainUi.h"
#include "features/Settings.h"
#include "misc/VersionManager.h"
#include "utils/gui_utils.h"

void InitFeatures();
Expand Down Expand Up @@ -90,6 +91,7 @@ void Run(HMODULE *phModule) {
ui::main::ToggleShow();

GuiHelper::ShowSuccessToast(i18n::I18nManager::GetInstance().getTextCStr("DownloaderLoadSuccess"));
misc::VersionManager::CheckUpdate();
}

#include "features/About.h"
Expand Down
48 changes: 48 additions & 0 deletions Downloader/src/misc/VersionManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "pch.h"
#include "VersionManager.h"

#include "network/HttpRequest.h"
#include "utils/gui_utils.h"

void misc::VersionManager::CheckUpdate(const bool force) {
static bool checked = false;
static bool inCheck = false;

if (inCheck)
return;

if (checked && !force)
return;

GET_LANG();
inCheck = true;
GuiHelper::ShowInfoToast(lang.getTextCStr("VersionChecking"));
static std::vector<std::string> headers = {
"Accept: application/vnd.github+json",
"X-GitHub-Api-Version: 2022-11-28"
};
net::curl_get_async(
"https://api.github.com/repos/KyuubiRan/BeatmapDownloader/releases/latest", headers,
[&](const int code, std::string &res) {
if (code != 200) {
LOGW("Cannot check update, response code: %d, response body: %s", code, res.c_str());
GuiHelper::ShowWarnToast(lang.getTextCStr("VersionCheckFailed"), code);
inCheck = false;
return;
}
nlohmann::json j = nlohmann::json::parse(res);
s_LatestVersionName = j["name"];
const std::string vc = j["tag_name"];
s_LatestVersionCode = std::stoi(vc);
checked = true;
inCheck = false;
if (IsLatest()) {
LOGI("Downloader is up to date");
GuiHelper::ShowSuccessToast(lang.getTextCStr("VersionIsLatest"));
} else {
LOGI("Found new version: %s(%d)", s_LatestVersionName.c_str(), s_LatestVersionCode);
GuiHelper::ShowInfoToast(lang.getTextCStr("FoundNewVersion"), s_LatestVersionName.c_str(),
s_LatestVersionCode);
}
});
}
35 changes: 35 additions & 0 deletions Downloader/src/misc/VersionManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include <string>

// dlver.h will auto generated by `update_version.py` before build
// if you cant run this script, please copy this code to src/dlver.h
/*
#pragma once
#define LATEST_UPDATE_TIMESTAMP 0
#define DOWNLOADER_VERSION 0
#define DOWNLOADER_VERSION_STR "unknown"
*/
#include "dlver.h"

namespace misc {
class VersionManager {
inline static int s_LatestVersionCode = 0;
inline static std::string s_LatestVersionName = "unknown";

public:
static void CheckUpdate(bool force = false);
static int GetLatestVersionCode() { return s_LatestVersionCode; }
static std::string_view GetLatestVersionName() { return s_LatestVersionName; }

static int GetCurrentVersionCode() { return DOWNLOADER_VERSION; }
static std::string_view GetCurrentVersionName() { return DOWNLOADER_VERSION_STR; }

static bool IsLatest() {
return GetCurrentVersionCode() >= s_LatestVersionCode;
}
};
}
7 changes: 7 additions & 0 deletions Downloader/src/misc/glob.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include <ThreadPool.hpp>

namespace glob {
inline static thread::ThreadPool s_ThreadPool{};
}
29 changes: 21 additions & 8 deletions Downloader/src/network/HttpRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "HttpRequest.h"

#include "features/Downloader.h"
#include "misc/glob.h"
#include "utils/gui_utils.h"

#pragma comment(lib, "ws2_32.lib")
Expand All @@ -14,23 +15,26 @@ size_t string_write_fn(char *data, size_t size, size_t nmemb, std::string *write
return size * nmemb;
}

CURLcode net::curl_get(const char *url, std::string &response, std::vector<std::string> &extraHeader, int32_t *resCode) {
CURLcode net::curl_get(const char *url, std::string &response, const std::vector<std::string> &extraHeader, int32_t *resCode) {
CURL *curl = curl_easy_init();
if (!curl) {
LOGE("Cannot init curl");
return CURLE_FAILED_INIT;
}

auto &dl = features::Downloader::GetInstance();

curl_slist *headers = nullptr;

const std::string ua = "User-Agent: " + (dl.f_EnableCustomUserAgent.getValue()
? dl.f_CustomUserAgent.getValue()
: features::Downloader::DEFAULT_USER_AGENT);
headers = curl_slist_append(headers, ua.c_str());

for (const auto &s : extraHeader) {
curl_slist_append(headers, s.c_str());
headers = curl_slist_append(headers, s.c_str());
}
const std::string ua = "User-Agent: " + (dl.f_EnableCustomUserAgent.getValue()
? dl.f_CustomUserAgent.getValue()
: features::Downloader::DEFAULT_USER_AGENT);
curl_slist_append(headers, ua.c_str());

curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
Expand Down Expand Up @@ -68,6 +72,15 @@ CURLcode net::curl_get(const char *url, std::string &response, std::vector<std::
return res;
}

void net::curl_get_async(std::string url, std::vector<std::string> extraHeader, std::function<void(int, std::string &)> callback) {
glob::s_ThreadPool.post([u = std::move(url), h = std::move(extraHeader), c = std::move(callback)] {
std::string response;
int32_t code;
curl_get(u.c_str(), response, h, &code);
c(code, response);
});
}

size_t file_writer(char *data, size_t size, size_t nmemb, FILE *pFile) {
if (!data)
return 0;
Expand Down Expand Up @@ -147,7 +160,7 @@ CURLcode net::curl_download(const char *url, std::filesystem::path &path, std::v
LOGW("Curl req(dl) error: %d", res);
GuiHelper::ShowErrorToast(i18n::I18nManager::GetTextCStr("CurlError"), res);
}

curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return res;
Expand Down
17 changes: 12 additions & 5 deletions Downloader/src/network/HttpRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,32 @@

#include <curl.h>
#include <string>
#include <fstream>
#include <vector>

#include "features/DownloadQueue.h"

#pragma comment(lib, "crypt32.lib")

namespace net {
CURLcode curl_get(const char *url, std::string &response, std::vector<std::string> &extraHeader, int32_t *resCode = nullptr);
CURLcode curl_get(const char *url, std::string &response, const std::vector<std::string> &extraHeader, int32_t *resCode = nullptr);

inline CURLcode curl_get(const char *url, std::string &response, int32_t *resCode = nullptr) {
std::vector<std::string> empty = {};
const static std::vector<std::string> empty = {};
return curl_get(url, response, empty, resCode);
}

CURLcode curl_download(const char *url, std::filesystem::path &path, std::vector<std::string> &extraHeader, features::DownloadTask *task = nullptr,
void curl_get_async(std::string url, std::vector<std::string> extraHeader, std::function<void(int, std::string &)> callback);

inline void curl_get_async(std::string url, std::function<void(int, std::string &)> callback) {
return curl_get_async(std::move(url), std::vector<std::string>{}, std::move(callback));
}

CURLcode curl_download(const char *url, std::filesystem::path &path, std::vector<std::string> &extraHeader,
features::DownloadTask *task = nullptr,
int32_t *resCode = nullptr);

inline CURLcode curl_download(const char *url, std::filesystem::path &path, features::DownloadTask *task = nullptr, int32_t *resCode = nullptr) {
inline CURLcode curl_download(const char *url, std::filesystem::path &path, features::DownloadTask *task = nullptr,
int32_t *resCode = nullptr) {
std::vector<std::string> empty = {};
return curl_download(url, path, empty, task, resCode);
}
Expand Down
Loading

0 comments on commit ba7c5cb

Please sign in to comment.