-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
9,538 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
cmake_minimum_required(VERSION 3.5) | ||
project(hydra_go) | ||
|
||
set(HYDRA_GO_SOURCES downloader.go) | ||
set(LIB libhydra_go.a) | ||
|
||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${LIB} | ||
DEPENDS ${HYDRA_GO_SOURCES} | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} | ||
COMMAND env GOPATH=${GOPATH} go build -buildmode=c-archive | ||
-o "${CMAKE_CURRENT_BINARY_DIR}/${LIB}" | ||
COMMENT "Building hydra_go library...") | ||
add_custom_target(hydra_go ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${LIB}) | ||
add_library(hydra_go_static STATIC IMPORTED GLOBAL) | ||
set_target_properties(hydra_go_static PROPERTIES | ||
IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${LIB} | ||
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Why use Go in a C++ project? | ||
|
||
Go has nice builtin HTTPS support and a lot of other goodies in its standard library. The other option was using OpenSSL, which my system (Archlinux) failed to find and it would mean an additional dependency that is harder to install on systems like Windows. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package main | ||
|
||
/* | ||
#include "downloader.h" | ||
#include <stdlib.h> | ||
#include <string.h> | ||
inline void* my_malloc(size_t size) { return malloc(size); } | ||
*/ | ||
import "C" | ||
import ( | ||
"io" | ||
"net/http" | ||
"unsafe" | ||
) | ||
|
||
//export hydra_download | ||
func hydra_download(url *C.cchar_t) C.hydra_buffer_t { | ||
var buffer C.hydra_buffer_t | ||
buffer.data = nil | ||
buffer.size = 0 | ||
|
||
goURL := C.GoString(url) | ||
response, err := http.Get(goURL) | ||
if err != nil { | ||
println("Go: " + err.Error()) | ||
return buffer | ||
} | ||
defer response.Body.Close() | ||
|
||
b, err := io.ReadAll(response.Body) | ||
if err != nil { | ||
println("Go: " + err.Error()) | ||
return buffer | ||
} | ||
|
||
buffer.data = C.my_malloc(C.size_t(response.ContentLength)) | ||
C.memcpy(buffer.data, unsafe.Pointer(&b[0]), C.size_t(response.ContentLength)) | ||
buffer.size = C.size_t(response.ContentLength) | ||
return buffer | ||
} | ||
|
||
// For whatever reason, this is required to build with -buildmode=c-archive | ||
func main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include <stdint.h> | ||
#include <stdlib.h> | ||
|
||
typedef const char cchar_t; | ||
|
||
typedef struct { | ||
void* data; | ||
uint64_t size; | ||
} hydra_buffer_t; | ||
|
||
extern hydra_buffer_t hydra_download(cchar_t* url); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module hydra_go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#pragma once | ||
|
||
#include "go/downloader.h" | ||
#include <string> | ||
|
||
namespace hydra | ||
{ | ||
struct HydraBufferWrapper | ||
{ | ||
HydraBufferWrapper() = default; | ||
|
||
HydraBufferWrapper(const hydra_buffer_t& buffer) : buffer_(buffer) {} | ||
|
||
~HydraBufferWrapper() | ||
{ | ||
if (buffer_.data) | ||
free(buffer_.data); | ||
} | ||
|
||
hydra_buffer_t* operator->() | ||
{ | ||
return &buffer_; | ||
} | ||
|
||
private: | ||
hydra_buffer_t buffer_; | ||
}; | ||
|
||
struct Downloader | ||
{ | ||
static HydraBufferWrapper Download(const std::string& url) | ||
{ | ||
#ifndef HYDRA_USE_GOLANG | ||
printf("Tried to download when built without golang support, this shouldn't happen"); | ||
return {}; | ||
#endif | ||
try | ||
{ | ||
hydra_buffer_t buffer = hydra_download(url.c_str()); | ||
return HydraBufferWrapper(buffer); | ||
} catch (...) | ||
{ | ||
printf("Failed while trying to download %s using Go\n", url.c_str()); | ||
return {}; | ||
} | ||
} | ||
}; | ||
} // namespace hydra |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#pragma once | ||
|
||
#include "json.hpp" | ||
#include "settings.hxx" | ||
#include <download.hxx> | ||
#include <miniz/miniz.h> | ||
#include <mutex> | ||
#include <sstream> | ||
#include <thread> | ||
|
||
namespace hydra | ||
{ | ||
struct Updater | ||
{ | ||
static std::mutex& GetMutex() | ||
{ | ||
static std::mutex mutex; | ||
return mutex; | ||
} | ||
|
||
static bool NeedsDatabaseUpdate() | ||
{ | ||
std::string old_date = Settings::Get("database_date"); | ||
if (old_date.empty()) | ||
return true; | ||
|
||
std::string new_date = get_database_time(); | ||
return is_newer_date(old_date, new_date); | ||
} | ||
|
||
static void UpdateDatabase() | ||
{ | ||
std::thread t([]() { | ||
std::mutex& mutex = GetMutex(); | ||
std::lock_guard<std::mutex> lock(mutex); | ||
HydraBufferWrapper buffer = Downloader::Download( | ||
"https://github.com/hydra-emu/database/archive/refs/heads/master.zip"); | ||
|
||
if (!buffer->data) | ||
{ | ||
log_fatal("Failed to download database zip\n"); | ||
} | ||
|
||
mz_zip_archive zip_archive; | ||
memset(&zip_archive, 0, sizeof(zip_archive)); | ||
|
||
if (!mz_zip_reader_init_mem(&zip_archive, buffer->data, buffer->size, 0)) | ||
log_fatal("Failed to read database zip\n"); | ||
|
||
if (!std::filesystem::create_directories(Settings::GetSavePath() / "database")) | ||
{ | ||
if (!std::filesystem::exists(Settings::GetSavePath() / "database")) | ||
log_fatal("Failed to create database directory\n"); | ||
} | ||
|
||
for (size_t i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) | ||
{ | ||
mz_zip_archive_file_stat file_stat; | ||
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) | ||
log_fatal("Failed to stat file in zip\n"); | ||
|
||
std::filesystem::path path = file_stat.m_filename; | ||
if (path.extension() == ".json") | ||
{ | ||
std::string data; | ||
data.resize(file_stat.m_uncomp_size); | ||
if (!mz_zip_reader_extract_to_mem(&zip_archive, i, data.data(), data.size(), | ||
0)) | ||
log_fatal("Failed to extract file from zip\n"); | ||
|
||
std::ofstream file(Settings::GetSavePath() / "database" / path.filename()); | ||
file << data; | ||
} | ||
} | ||
}); | ||
t.detach(); | ||
} | ||
|
||
private: | ||
static std::string get_database_time() | ||
{ | ||
HydraBufferWrapper result = Downloader::Download( | ||
"https://api.github.com/repos/hydra-emu/database/commits/master"); | ||
|
||
if (result->data) | ||
log_fatal("Failed to download database info\n"); | ||
|
||
std::string data = std::string((char*)result->data, result->size); | ||
auto json = nlohmann::json::parse(data); | ||
std::string date = json["commit"]["commit"]["commiter"]["date"]; | ||
|
||
return date; | ||
} | ||
|
||
static bool is_newer_date(const std::string& date_old, const std::string& date_new) | ||
{ | ||
std::istringstream ss_old(date_old); | ||
std::istringstream ss_new(date_new); | ||
|
||
std::tm timeinfo_old = {}; | ||
std::tm timeinfo_new = {}; | ||
|
||
ss_old >> std::get_time(&timeinfo_old, "%Y-%m-%dT%H:%M:%SZ"); | ||
ss_new >> std::get_time(&timeinfo_new, "%Y-%m-%dT%H:%M:%SZ"); | ||
|
||
std::time_t time_old = std::mktime(&timeinfo_old); | ||
std::time_t time_new = std::mktime(&timeinfo_new); | ||
|
||
return time_new > time_old; | ||
} | ||
}; | ||
|
||
} // namespace hydra |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Copyright 2013-2014 RAD Game Tools and Valve Software | ||
Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC | ||
|
||
All Rights Reserved. | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
Oops, something went wrong.