From 6bf68eb29820deb045040a80a337b2d1133c16ea Mon Sep 17 00:00:00 2001 From: Jordon Brooks Date: Sun, 7 Jan 2024 20:29:47 +0000 Subject: [PATCH] Revamp: Transition HarmonyLink to C++ with DLL support This transformative commit marks the evolution of HarmonyLink from a Rust-based server-side application to a C++ implemented, C-compatible dynamic link library (DLL). We've restructured the codebase to streamline integration into games, eliminating the need for a server setup by end-users. Key Changes: - Introduced .gitattributes and .gitmodules to manage new dependencies and collaborations. - Replaced the GitHub workflow files with CMake configurations to support the new C++ build system. - Introduced a comprehensive set of header and implementation files defining the core functionality, platform-specific utilities, and cross-platform compatibility layers. - Removed all Rust-specific files (Cargo.toml, Cargo.lock, etc.) and references to ensure a clean transition to the C++ environment. - Implemented new testing mechanisms within HarmonyLinkTest to ensure robustness and reliability of the DLL. - Excised previous server-side components and models to focus on the DLL's direct integration into consumer applications. This update is a direct response to community feedback, showcasing our commitment to adaptability and innovation. HarmonyLink 2.0 is now more accessible, efficient, and tailored for diverse gaming environments, providing developers with an unparalleled level of hardware-software harmony. Please refer to the updated README for more details on the new structure and how to integrate HarmonyLink 2.0 into your projects. --- .gitattributes | 39 + .github/workflows/release.yml | 59 - .github/workflows/rust-build.yml | 51 - .gitignore | 24 +- .gitmodules | 0 CMakeLists.txt | 70 + Cargo.lock | 1589 ----------------- Cargo.toml | 42 - HarmonyLinkLib/CMakeLists.txt | 129 ++ HarmonyLinkLib/include/Core.h | 14 + HarmonyLinkLib/include/Enums/EDevice.h | 19 + HarmonyLinkLib/include/Enums/EPlatform.h | 15 + HarmonyLinkLib/include/FString.h | 165 ++ HarmonyLinkLib/include/HarmonyLinkLib.h | 44 + HarmonyLinkLib/include/HarmonyLinkStruct.h | 13 + HarmonyLinkLib/include/Structs/FBattery.h | 22 + HarmonyLinkLib/include/Structs/FCPUInfo.h | 40 + HarmonyLinkLib/include/Structs/FDevice.h | 16 + HarmonyLinkLib/include/Structs/FOSVerInfo.h | 50 + HarmonyLinkLib/include/Version.h | 45 + HarmonyLinkLib/include/Version.h.in | 11 + HarmonyLinkLib/src/HarmonyLinkLib.cpp | 94 + .../src/Platform/IPlatformUtilities.cpp | 122 ++ .../src/Platform/IPlatformUtilities.h | 34 + .../Platform/Unix/Linux/LinuxUtilities.cpp | 24 + .../src/Platform/Unix/Linux/LinuxUtilities.h | 23 + .../src/Platform/Unix/Mac/MacUtilities.cpp | 6 + .../src/Platform/Unix/Mac/MacUtilities.h | 11 + .../src/Platform/Unix/UnixUtilities.cpp | 24 + .../src/Platform/Unix/UnixUtilities.h | 16 + .../src/Platform/Windows/WindowsUtilities.cpp | 81 + .../src/Platform/Windows/WindowsUtilities.h | 16 + HarmonyLinkLib/src/Platform/WineUtilities.cpp | 202 +++ HarmonyLinkLib/src/Platform/WineUtilities.h | 46 + HarmonyLinkLib/src/Version.cpp | 1 + HarmonyLinkLib/src/dllmain.cpp | 49 + HarmonyLinkTest/CMakeLists.txt | 31 + HarmonyLinkTest/src/main.cpp | 143 ++ Resources/dock_models.json | 11 - build.rs | 72 - src/api/api.rs | 14 - src/api/endpoints_v1.rs | 99 - src/api/mod.rs | 3 - src/api/server.rs | 28 - src/main.rs | 37 - src/v1/all_info/mod.rs | 2 - src/v1/all_info/stats.rs | 18 - src/v1/all_info/structs.rs | 24 - src/v1/battery/mod.rs | 2 - src/v1/battery/stats.rs | 38 - src/v1/battery/structs.rs | 28 - src/v1/docking/mod.rs | 2 - src/v1/docking/stats.rs | 90 - src/v1/docking/structs.rs | 39 - src/v1/mod.rs | 4 - src/v1/os/mod.rs | 2 - src/v1/os/stats.rs | 45 - src/v1/os/structs.rs | 38 - src/version/info.rs | 41 - src/version/mod.rs | 1 - 60 files changed, 1629 insertions(+), 2389 deletions(-) create mode 100644 .gitattributes delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/rust-build.yml create mode 100644 .gitmodules create mode 100644 CMakeLists.txt delete mode 100644 Cargo.lock delete mode 100644 Cargo.toml create mode 100644 HarmonyLinkLib/CMakeLists.txt create mode 100644 HarmonyLinkLib/include/Core.h create mode 100644 HarmonyLinkLib/include/Enums/EDevice.h create mode 100644 HarmonyLinkLib/include/Enums/EPlatform.h create mode 100644 HarmonyLinkLib/include/FString.h create mode 100644 HarmonyLinkLib/include/HarmonyLinkLib.h create mode 100644 HarmonyLinkLib/include/HarmonyLinkStruct.h create mode 100644 HarmonyLinkLib/include/Structs/FBattery.h create mode 100644 HarmonyLinkLib/include/Structs/FCPUInfo.h create mode 100644 HarmonyLinkLib/include/Structs/FDevice.h create mode 100644 HarmonyLinkLib/include/Structs/FOSVerInfo.h create mode 100644 HarmonyLinkLib/include/Version.h create mode 100644 HarmonyLinkLib/include/Version.h.in create mode 100644 HarmonyLinkLib/src/HarmonyLinkLib.cpp create mode 100644 HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp create mode 100644 HarmonyLinkLib/src/Platform/IPlatformUtilities.h create mode 100644 HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp create mode 100644 HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h create mode 100644 HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp create mode 100644 HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h create mode 100644 HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp create mode 100644 HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h create mode 100644 HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp create mode 100644 HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h create mode 100644 HarmonyLinkLib/src/Platform/WineUtilities.cpp create mode 100644 HarmonyLinkLib/src/Platform/WineUtilities.h create mode 100644 HarmonyLinkLib/src/Version.cpp create mode 100644 HarmonyLinkLib/src/dllmain.cpp create mode 100644 HarmonyLinkTest/CMakeLists.txt create mode 100644 HarmonyLinkTest/src/main.cpp delete mode 100644 Resources/dock_models.json delete mode 100644 build.rs delete mode 100644 src/api/api.rs delete mode 100644 src/api/endpoints_v1.rs delete mode 100644 src/api/mod.rs delete mode 100644 src/api/server.rs delete mode 100644 src/main.rs delete mode 100644 src/v1/all_info/mod.rs delete mode 100644 src/v1/all_info/stats.rs delete mode 100644 src/v1/all_info/structs.rs delete mode 100644 src/v1/battery/mod.rs delete mode 100644 src/v1/battery/stats.rs delete mode 100644 src/v1/battery/structs.rs delete mode 100644 src/v1/docking/mod.rs delete mode 100644 src/v1/docking/stats.rs delete mode 100644 src/v1/docking/structs.rs delete mode 100644 src/v1/mod.rs delete mode 100644 src/v1/os/mod.rs delete mode 100644 src/v1/os/stats.rs delete mode 100644 src/v1/os/structs.rs delete mode 100644 src/version/info.rs delete mode 100644 src/version/mod.rs diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..970e13f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,39 @@ +* text=auto + +# Sources +*.c text diff=cpp +*.cc text diff=cpp +*.cxx text diff=cpp +*.cpp text diff=cpp +*.cpi text diff=cpp +*.c++ text diff=cpp +*.hpp text diff=cpp +*.h text diff=cpp +*.h++ text diff=cpp +*.hh text diff=cpp + +# Compiled Object files +*.slo binary +*.lo binary +*.o binary +*.obj binary + +# Precompiled Headers +*.gch binary +*.pch binary + +# Compiled Dynamic libraries +*.so binary +*.dylib binary +*.dll binary + +# Compiled Static libraries +*.lai binary +*.la binary +*.a binary +*.lib binary + +# Executables +*.exe binary +*.out binary +*.app binary \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 78fd72e..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,59 +0,0 @@ -# .github/workflows/release.yml - -on: - push: - tags: - - 'release*' - -jobs: - release: - name: release ${{ matrix.target }} - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-pc-windows-gnu - archive: zip - - target: x86_64-unknown-linux-musl - archive: tar.gz - steps: - - uses: actions/checkout@master - with: - ssh-key: "${{secrets.RELEASE_KEY}}" - - uses: Swatinem/rust-cache@v2 - with: - # The prefix cache key, this can be changed to start a new cache manually. - # default: "v0-rust" - prefix-key: "" - - # A cache key that is used instead of the automatic `job`-based key, - # and is stable over multiple jobs. - # default: empty - shared-key: "" - - # An additional cache key that is added alongside the automatic `job`-based - # cache key and can be used to further differentiate jobs. - # default: empty - key: "" - - # A whitespace separated list of env-var *prefixes* who's value contributes - # to the environment cache key. - # The env-vars are matched by *prefix*, so the default `RUST` var will - # match all of `RUSTC`, `RUSTUP_*`, `RUSTFLAGS`, `RUSTDOC_*`, etc. - # default: "CARGO CC CFLAGS CXX CMAKE RUST" - env-vars: "" - - # The cargo workspaces and target directory configuration. - # These entries are separated by newlines and have the form - # `$workspace -> $target`. The `$target` part is treated as a directory - # relative to the `$workspace` and defaults to "target" if not explicitly given. - # default: ". -> target" - workspaces: ". -> target" - - name: Compile and release - uses: rust-build/rust-build.action@v1.4.3 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - RUSTTARGET: ${{ matrix.target }} - ARCHIVE_TYPES: ${{ matrix.archive }} \ No newline at end of file diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml deleted file mode 100644 index 6cd0a6a..0000000 --- a/.github/workflows/rust-build.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Rust - -on: - push: - branches: [ "stable" ] - pull_request: - branches: [ "stable" ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@v2 - with: - # The prefix cache key, this can be changed to start a new cache manually. - # default: "v0-rust" - prefix-key: "" - - # A cache key that is used instead of the automatic `job`-based key, - # and is stable over multiple jobs. - # default: empty - shared-key: "" - - # An additional cache key that is added alongside the automatic `job`-based - # cache key and can be used to further differentiate jobs. - # default: empty - key: "" - - # A whitespace separated list of env-var *prefixes* who's value contributes - # to the environment cache key. - # The env-vars are matched by *prefix*, so the default `RUST` var will - # match all of `RUSTC`, `RUSTUP_*`, `RUSTFLAGS`, `RUSTDOC_*`, etc. - # default: "CARGO CC CFLAGS CXX CMAKE RUST" - env-vars: "" - - # The cargo workspaces and target directory configuration. - # These entries are separated by newlines and have the form - # `$workspace -> $target`. The `$target` part is treated as a directory - # relative to the `$workspace` and defaults to "target" if not explicitly given. - # default: ". -> target" - workspaces: ". -> target" - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose diff --git a/.gitignore b/.gitignore index 34d1b2e..d567bc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,18 @@ +# Setup .gitignore as a whitelist * !*/ +build/** + +# track this file !.gitignore -!src/** -!res/HarmonyLinkLogo.ico -!Resources/** -!Images/** -!.github/** -!Build.rs -!Cargo.toml -!Cargo.lock -!LICENSE -!README.md \ No newline at end of file +!.gitattributes +!.gitmodules + +!CMakeLists.txt +!license +!readme.md + +!HarmonyLinkLib/** +!HarmonyLinkTest/** +!tests/** \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2bf0723 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,70 @@ +cmake_minimum_required(VERSION 3.10) +project(HarmonyLinkProject) + +# Check the build type and display a message accordingly +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Building for Debug") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Building for Release") +elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") + message(STATUS "Building for MinSizeRel") +elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + message(STATUS "Building for RelWithDebInfo") +else() + message(STATUS "Building with unspecified build type") +endif() + +#set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +# Platform-specific definitions +if(WIN32) + add_definitions(-DBUILD_WINDOWS) +elseif(UNIX) + if(APPLE) + add_definitions(-DBUILD_MACOS) + else() + add_definitions(-DBUILD_LINUX) + endif() + add_definitions(-DBUILD_UNIX) +endif() + +# Set global output directories for all build types +foreach(TYPE IN ITEMS DEBUG RELEASE) + string(TOUPPER ${TYPE} TYPE_UPPER) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/lib/${TYPE}") + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}") +endforeach() + +# Add the library and executable directories + +add_subdirectory(HarmonyLinkLib) +add_subdirectory(HarmonyLinkTest) + +# Add Google Test as a subdirectory +#add_subdirectory(ThirdParty/googletest) + +# Enable testing +#enable_testing() + +# Include Google Test's include directory +#include_directories(ThirdParty/googletest/googletest/include) + +# Define your test executable +#file(GLOB_RECURSE TEST_SOURCES "tests/*.cpp") +#add_executable(Testing ${TEST_SOURCES}) + +# Set HarmonyLinkTest as the default startup project +set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT HarmonyLinkTest) + +# Link Google Test and HarmonyLink library to the test executable +#target_link_libraries(Testing gtest gtest_main gmock HarmonyLinkLib) + +#add_custom_command(TARGET Testing POST_BUILD +# COMMAND ${CMAKE_COMMAND} -E copy_if_different +# "$" +# "$") + +# Discover tests +#include(GoogleTest) +#gtest_discover_tests(Testing) diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index d46817e..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,1589 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "actix-codec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-http" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2079246596c18b4a33e274ae10c0e50613f4d32a4198e09c7b93771013fed74" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "ahash 0.8.3", - "base64", - "bitflags", - "brotli", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "futures-core", - "h2", - "http", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite", - "rand", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", - "zstd", -] - -[[package]] -name = "actix-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "actix-router" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" -dependencies = [ - "bytestring", - "http", - "regex", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" -dependencies = [ - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "num_cpus", - "socket2", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" -dependencies = [ - "futures-core", - "paste", - "pin-project-lite", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3cb42f9566ab176e1ef0b8b3a896529062b4efc6be0123046095914c4c1c96" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash 0.7.6", - "bytes", - "bytestring", - "cfg-if", - "cookie", - "derive_more", - "encoding_rs", - "futures-core", - "futures-util", - "http", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2", - "time", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2262160a7ae29e3415554a3f1fc04c764b1540c116aa524683208078b7a75bc9" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "ahash" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" -dependencies = [ - "memchr", -] - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "anyhow" -version = "1.0.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "base64" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" - -[[package]] -name = "battery" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b624268937c0e0a3edb7c27843f9e547c320d730c610d3b8e6e8e95b2026e4" -dependencies = [ - "cfg-if", - "core-foundation", - "lazycell", - "libc", - "mach", - "nix", - "num-traits", - "uom", - "winapi", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "brotli" -version = "3.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bytes" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" - -[[package]] -name = "bytestring" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" -dependencies = [ - "bytes", -] - -[[package]] -name = "cc" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - -[[package]] -name = "core-foundation-sys" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - -[[package]] -name = "cpufeatures" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "encoding_rs" -version = "0.8.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "env_logger" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "flate2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-util" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "h2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "harmony_link_server" -version = "0.2.0" -dependencies = [ - "actix-web", - "battery", - "env_logger", - "lazy_static", - "log", - "os_info", - "rusb", - "serde", - "serde_json", - "sysinfo", - "vergen", - "winres", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - -[[package]] -name = "http" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys", -] - -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", - "windows-sys", -] - -[[package]] -name = "itoa" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" - -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.146" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" - -[[package]] -name = "libusb1-sys" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d0e2afce4245f2c9a418511e5af8718bcaf2fa408aefb259504d1a9cb25f27" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "local-channel" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" -dependencies = [ - "futures-core", - "futures-sink", - "futures-util", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" - -[[package]] -name = "lock_api" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" - -[[package]] -name = "mach" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" -dependencies = [ - "libc", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys", -] - -[[package]] -name = "nix" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" -dependencies = [ - "bitflags", - "cc", - "cfg-if", - "libc", -] - -[[package]] -name = "ntapi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" -dependencies = [ - "winapi", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" -dependencies = [ - "hermit-abi 0.2.6", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "os_info" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" -dependencies = [ - "log", - "serde", - "winapi", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "paste" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" - -[[package]] -name = "percent-encoding" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "proc-macro2" -version = "1.0.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" - -[[package]] -name = "rusb" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44a8c36914f9b1a3be712c1dfa48c9b397131f9a75707e570a391735f785c5d1" -dependencies = [ - "libc", - "libusb1-sys", -] - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.37.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "rustversion" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" - -[[package]] -name = "ryu" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "semver" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" - -[[package]] -name = "serde" -version = "1.0.164" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.164" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - -[[package]] -name = "serde_json" -version = "1.0.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sysinfo" -version = "0.29.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9557d0845b86eea8182f7b10dff120214fb6cd9fd937b6f4917714e546a38695" -dependencies = [ - "cfg-if", - "core-foundation-sys 0.8.4", - "libc", - "ntapi", - "once_cell", - "rayon", - "winapi", -] - -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "time" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" -dependencies = [ - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" - -[[package]] -name = "time-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" -dependencies = [ - "time-core", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.28.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" -dependencies = [ - "autocfg", - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "windows-sys", -] - -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - -[[package]] -name = "unicode-ident" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "uom" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e76503e636584f1e10b9b3b9498538279561adcef5412927ba00c2b32c4ce5ed" -dependencies = [ - "num-traits", - "typenum", -] - -[[package]] -name = "url" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vergen" -version = "8.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b3c89c2c7e50f33e4d35527e5bf9c11d6d132226dbbd1753f0fbe9f19ef88c6" -dependencies = [ - "anyhow", - "rustc_version", - "rustversion", - "sysinfo", - "time", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "winres" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" -dependencies = [ - "toml", -] - -[[package]] -name = "zstd" -version = "0.12.3+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "6.0.5+zstd.1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" -dependencies = [ - "cc", - "libc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 89fa8a5..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "harmony_link_server" -version = "0.2.0" -edition = "2021" -authors = ["Jordon jordon@jordongamedev.co.uk"] -homepage = "https://jordongamedev.co.uk" -repository = "https://github.com/Jordonbc/HarmonyLinkServer" -license = "GPL-3.0-or-later" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[profile.release] -panic = "abort" # Strip expensive panic clean-up logic -codegen-units = 1 # Compile crates one after another so the compiler can optimize better -lto = true # Enables link to optimizations -opt-level = "z" # Optimize for binary size -strip = true # Remove debug symbols - -[package.metadata.winres] -LegalCopyright = "Copyright © 2023 Jordon Brooks" -ProductName = "HarmonyLink: Server" -FileDescription = "Optimized games for your handheld!" - -[[bin]] -name = "harmony_link_server" -path = "src/main.rs" - -[build-dependencies] -vergen = { version = "8.2.1", features = ["build", "cargo", "git", "gitcl", "rustc", "si"] } -winres = "0.1.12" - -[dependencies] -actix-web = "4.3.1" -env_logger = "0.10.0" -log = "0.4.18" -serde = {version = "1.0.163", features = ["derive"]} -serde_json = "1.0.96" -sysinfo = "0.29.0" -os_info = "3.0" -battery = "0.7.8" -lazy_static = "1.4.0" -rusb = "0.9.2" diff --git a/HarmonyLinkLib/CMakeLists.txt b/HarmonyLinkLib/CMakeLists.txt new file mode 100644 index 0000000..8412f45 --- /dev/null +++ b/HarmonyLinkLib/CMakeLists.txt @@ -0,0 +1,129 @@ +cmake_minimum_required(VERSION 3.10) +project(HarmonyLinkLib VERSION 2.0.0) + +# Find the current Git branch and the last commit timestamp +find_package(Git QUIET) +if(GIT_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_BRANCH_NAME + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + execute_process( + COMMAND ${GIT_EXECUTABLE} log -1 --format=%ct + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_TIMESTAMP + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +else() + set(GIT_BRANCH_NAME "Unknown") + set(GIT_COMMIT_TIMESTAMP "Unknown") +endif() + +configure_file(include/Version.h.in Version.generated.h) + +# Specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# Explicitly list source files +set(COMMON_SOURCES + "src/Platform/IPlatformUtilities.cpp" + "src/HarmonyLinkLib.cpp" + "src/Version.cpp" + "src/dllmain.cpp" + "src/Platform/WineUtilities.cpp" +) + +# Explicitly list include files +set(COMMON_INCLUDES + "include/Core.h" + "include/Structs/FBattery.h" + "include/Structs/FOSVerInfo.h" + "include/Structs/FDevice.h" + "include/Structs/FCPUInfo.h" + + "include/Enums/EDevice.h" + "include/Enums/EPlatform.h" + + "include/FString.h" + "include/HarmonyLinkLib.h" + "include/Version.h" + + "src/Platform/IPlatformUtilities.h" + "src/Platform/WineUtilities.h" +) + +set(WINDOWS_SOURCES + "src/Platform/Windows/WindowsUtilities.cpp" +) + +set(WINDOWS_INCLUDES + "src/Platform/Windows/WindowsUtilities.h" +) + +set(LINUX_SOURCES + "src/Platform/Unix/Linux/LinuxUtilities.cpp" + "src/Platform/Unix/UnixUtilities.cpp" +) + +set(LINUX_INCLUDES + "src/Platform/Unix/Linux/LinuxUtilities.h" + "src/Platform/Unix/UnixUtilities.h" +) + +set(MAC_SOURCES + "src/Platform/Unix/Mac/MacUtilities.cpp" + "src/Platform/Unix/UnixUtilities.cpp" +) + +set(MAC_INCLUDES + "src/Platform/Unix/Mac/MacUtilities.h" + "src/Platform/Unix/UnixUtilities.h" +) + +# Platform-specific definitions +if(WIN32) + message(STATUS "Compiling for Windows...") + list(APPEND LIB_SOURCES ${COMMON_SOURCES} ${WINDOWS_SOURCES}) + list(APPEND LIB_INCLUDES ${COMMON_INCLUDES} ${WINDOWS_INCLUDES}) +elseif(UNIX) + message(STATUS "Compiling for Unix-based systems...") + if(APPLE) + message(STATUS "Compiling for Mac...") + list(APPEND LIB_SOURCES ${COMMON_SOURCES} ${MAC_SOURCES}) + list(APPEND LIB_INCLUDES ${COMMON_INCLUDES} ${MAC_INCLUDES}) + else() + message(STATUS "Compiling for Linux...") + list(APPEND LIB_SOURCES ${COMMON_SOURCES} ${LINUX_SOURCES}) + list(APPEND LIB_INCLUDES ${COMMON_INCLUDES} ${LINUX_INCLUDES}) + endif() +endif() + +# Add library +add_library(HarmonyLinkLib SHARED ${LIB_SOURCES} ${LIB_INCLUDES}) + +target_include_directories(HarmonyLinkLib + PRIVATE + "${PROJECT_SOURCE_DIR}/src" + PUBLIC + "${PROJECT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}/include" +) + +target_compile_definitions(HarmonyLinkLib PRIVATE HARMONYLINKLIB_EXPORTS) + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions(HarmonyLinkLib PRIVATE "DEBUG_MODE") +endif() + +# Set output directories for all build types +foreach(TYPE IN ITEMS DEBUG RELEASE) + string(TOUPPER ${TYPE} TYPE_UPPER) + set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}/${PROJECT_NAME}" + LIBRARY_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/lib/${TYPE}/${PROJECT_NAME}" + ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/archive/${TYPE}/${PROJECT_NAME}" + ) +endforeach() diff --git a/HarmonyLinkLib/include/Core.h b/HarmonyLinkLib/include/Core.h new file mode 100644 index 0000000..90d63b4 --- /dev/null +++ b/HarmonyLinkLib/include/Core.h @@ -0,0 +1,14 @@ +// Copyright (C) 2023 Jordon Brooks + +#pragma once + +// Use a preprocessor definition to switch between export and import declarations +#ifdef _WIN32 + #ifdef HARMONYLINKLIB_EXPORTS + #define HARMONYLINKLIB_API __declspec(dllexport) + #else + #define HARMONYLINKLIB_API __declspec(dllimport) + #endif +#else + #define HARMONYLINKLIB_API +#endif diff --git a/HarmonyLinkLib/include/Enums/EDevice.h b/HarmonyLinkLib/include/Enums/EDevice.h new file mode 100644 index 0000000..75d3cc5 --- /dev/null +++ b/HarmonyLinkLib/include/Enums/EDevice.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +// Enum class for representing different types of devices +namespace HarmonyLinkLib +{ + enum class EDevice : uint8_t + { + DESKTOP, + LAPTOP, + HANDHELD, + + STEAM_DECK, + // ROG_ALLY + // AYONEO_SLIDE + // etc... + }; +} diff --git a/HarmonyLinkLib/include/Enums/EPlatform.h b/HarmonyLinkLib/include/Enums/EPlatform.h new file mode 100644 index 0000000..c050ca3 --- /dev/null +++ b/HarmonyLinkLib/include/Enums/EPlatform.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +// Enum class for representing different operating platforms +namespace HarmonyLinkLib +{ + enum class EPlatform : uint8_t + { + WINDOWS, + LINUX, + MAC, + UNIX, + }; +} diff --git a/HarmonyLinkLib/include/FString.h b/HarmonyLinkLib/include/FString.h new file mode 100644 index 0000000..3f23dc1 --- /dev/null +++ b/HarmonyLinkLib/include/FString.h @@ -0,0 +1,165 @@ +// Copyright (C) 2024 Jordon Brooks + +#pragma once + +#include +#include +#include + +#include "Core.h" // Replace with actual API export macro + +/** + * @file FString.h + * @brief FString Class - Custom String Management for DLL Export + * + * The FString class is a custom string management class designed to safely encapsulate + * string handling and memory management, especially for use in DLLs (Dynamic Link Libraries). + * It resolves the common issue of exporting classes containing standard library types, + * such as std::string, across DLL boundaries, which can lead to compiler warnings or errors. + * + * Features: + * - Implements basic string operations such as construction, destruction, copy, and move semantics. + * - Utilizes smart pointers (std::unique_ptr) for automatic memory management, reducing the risk of memory leaks. + * - Provides a simple interface for interacting with character strings, similar to std::string. + * - Includes both deep copy semantics for safety and move semantics for performance in object transfers. + * + * Usage: + * FString can be used as a safer alternative to std::string for classes that are exported from a DLL. + * It handles memory allocation/deallocation automatically and provides a basic set of string operations. + * + * Example: + * FString myString("Hello, world!"); + * std::cout << myString.c_str() << std::endl; // Output: Hello, world! + * + * Note: + * - The class is currently designed with basic functionality. Additional features such as + * string concatenation, substring, and comparison operations can be added as needed. + * - Ensure that the HarmonyLinkLibApi.h (or equivalent) file correctly defines the export macro + * for DLL usage. + * + */ + namespace HarmonyLinkLib + { + class HARMONYLINKLIB_API FString { + public: + FString() : data_(new char[1]) { + data_[0] = '\0'; + } + + FString(const char* str) { + const size_t len = strlen(str); + data_ = new char[len + 1]; + memcpy(data_, str, len + 1); + } + + // Copy constructor + FString(const FString& other) { + const size_t len = strlen(other.data_); + data_ = new char[len + 1]; + memcpy(data_, other.data_, len + 1); + } + + ~FString() { + delete[] data_; + } + + // Copy assignment operator + FString& operator=(const FString& other) { + if (this != &other) { + delete[] data_; + const size_t len = strlen(other.data_); + data_ = new char[len + 1]; + memcpy(data_, other.data_, len + 1); + } + return *this; + } + + // Concatenation operator for FString objects + FString operator+(const FString& other) const { + size_t thisLen = strlen(this->data_); + size_t otherLen = strlen(other.data_); + char* concatenated = new char[thisLen + otherLen + 1]; + + memcpy(concatenated, this->data_, thisLen); + memcpy(concatenated + thisLen, other.data_, otherLen + 1); + + FString result(concatenated); + delete[] concatenated; + return result; + } + + // Concatenation operator for const char* + FString operator+(const char* other) const { + return *this + FString(other); + } + + // Friend function to allow concatenation with const char* on the left-hand side + friend FString operator+(const char* lhs, const FString& rhs) { + return FString(lhs) + rhs; + } + + // Move constructor + FString(FString&& other) noexcept : data_(other.data_) { + other.data_ = nullptr; + } + + FString(const std::string& str) { + const size_t len = str.length(); + data_ = new char[len + 1]; + memcpy(data_, str.c_str(), len + 1); + } + + // Move assignment operator + FString& operator=(FString&& other) noexcept { + if (this != &other) { + delete[] data_; + data_ = other.data_; + other.data_ = nullptr; + } + return *this; + } + + bool operator==(const FString& other) const { + return strcmp(data_, other.data_) == 0; + } + + // Method to get a lowercase version of the string + static FString to_lower(FString& from) + { + for (size_t i = 0; i < strlen(from.data_); ++i) { + from.data_[i] = static_cast(std::tolower(static_cast(from.data_[i]))); + } + return from; + } + + // Overloaded static method to handle const char* + static FString to_lower(const char* from) { + FString temp_string(from); // Create an FString from const char* + return to_lower(temp_string); // Reuse the existing to_lower method + } + + const char* c_str() const { + return data_; + } + + private: + char* data_ = nullptr; + }; + } + +namespace std { + template<> + struct hash { + size_t operator()(const HarmonyLinkLib::FString& s) const { + size_t hashValue = 5381; // Starting value recommended by the djb2 algorithm + const char* str = s.c_str(); + + for (size_t i = 0; str[i] != '\0'; ++i) { + hashValue = ((hashValue << 5) + hashValue) + static_cast(str[i]); + // Equivalent to hashValue * 33 + str[i] + } + + return hashValue; + } + }; +} diff --git a/HarmonyLinkLib/include/HarmonyLinkLib.h b/HarmonyLinkLib/include/HarmonyLinkLib.h new file mode 100644 index 0000000..abd095e --- /dev/null +++ b/HarmonyLinkLib/include/HarmonyLinkLib.h @@ -0,0 +1,44 @@ +// Copyright (C) 2023 Jordon Brooks + + +/** + * IMPORTANT REMINDER: + * Do NOT use standard output functions like std::cout and printf anywhere in this codebase. + * + * Reason: + * Unreal Engine 5's packaging tool encounters issues with these functions, leading to + * packaging failures. The engine sets stdout to UTF-8, which can cause conflicts with + * these standard functions, resulting in a "SECURE CRT: Invalid parameter detected" error + * during packaging. + * + * This issue once required an extensive debugging effort that lasted over 8 hours. + * To prevent similar issues in the future and ensure smooth packaging, always use + * wide-character versions of these functions, such as wprintf and std::wcout, when working + * within the DLL. These functions are compatible with the UTF-8 setting in Unreal Engine 5. + * + */ + + +#pragma once + +#include "Core.h" +#include "Structs/FBattery.h" +#include "Structs/FCPUInfo.h" +#include "Structs/FDevice.h" +#include "Structs/FOSVerInfo.h" + + +class IPlatformUtilities; + +namespace HarmonyLinkLib +{ + extern "C" HARMONYLINKLIB_API bool get_is_wine(); + + extern "C" HARMONYLINKLIB_API FCPUInfo* get_cpu_info(); + + extern "C" HARMONYLINKLIB_API FDevice* get_device_info(); + + extern "C" HARMONYLINKLIB_API FOSVerInfo* get_os_version(); + + extern "C" HARMONYLINKLIB_API FBattery* get_battery_status(); +} diff --git a/HarmonyLinkLib/include/HarmonyLinkStruct.h b/HarmonyLinkLib/include/HarmonyLinkStruct.h new file mode 100644 index 0000000..aa4497d --- /dev/null +++ b/HarmonyLinkLib/include/HarmonyLinkStruct.h @@ -0,0 +1,13 @@ +#pragma once + +struct HarmonyLinkStruct +{ + // Virtual destructor is important for proper cleanup of derived types + virtual ~HarmonyLinkStruct() = default; + + // Method to deallocate the object + void free() const + { + delete this; + } +}; diff --git a/HarmonyLinkLib/include/Structs/FBattery.h b/HarmonyLinkLib/include/Structs/FBattery.h new file mode 100644 index 0000000..6c41595 --- /dev/null +++ b/HarmonyLinkLib/include/Structs/FBattery.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#include "HarmonyLinkStruct.h" + +namespace HarmonyLinkLib +{ + struct FBattery : HarmonyLinkStruct + { + bool has_battery; + bool is_connected_to_ac; + uint8_t battery_percent; + + void to_string() const { + std::wcout << "Battery present: " << (has_battery ? "'Yes'" : "'No'") << '\n'; + std::wcout << "Connected to AC: " << (is_connected_to_ac ? "'Yes'" : "'No'") << '\n'; + std::wcout << "Battery percent: '" << static_cast(battery_percent) << "%'" << '\n'; + } + }; +} diff --git a/HarmonyLinkLib/include/Structs/FCPUInfo.h b/HarmonyLinkLib/include/Structs/FCPUInfo.h new file mode 100644 index 0000000..8694e6a --- /dev/null +++ b/HarmonyLinkLib/include/Structs/FCPUInfo.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include "FString.h" + +#include "HarmonyLinkStruct.h" + +namespace HarmonyLinkLib +{ + struct FCPUInfo : HarmonyLinkStruct + { + FString VendorID; + FString Model_Name; + uint32_t Physical_Cores = 0; + uint32_t Logical_Cores = 0; + std::unordered_set Flags; + + void print() const + { + wprintf(L"VendorID: '%hs'\n", VendorID.c_str()); + wprintf(L"Model_Name: '%hs'\n", Model_Name.c_str()); + wprintf(L"Physical_Cores: '%d'\n", Physical_Cores); + wprintf(L"Logical_Cores: '%d'\n", Logical_Cores); + + // Initialize a string to hold all flags + std::string allFlags; + for (const auto& flag : Flags) { + allFlags += std::string(flag.c_str()) + " "; // Append each flag followed by a space + } + + // Remove the trailing space + if (!allFlags.empty()) { + allFlags.pop_back(); + } + + wprintf(L"Flags: '%hs'\n", allFlags.c_str()); + } + }; +} diff --git a/HarmonyLinkLib/include/Structs/FDevice.h b/HarmonyLinkLib/include/Structs/FDevice.h new file mode 100644 index 0000000..204a5da --- /dev/null +++ b/HarmonyLinkLib/include/Structs/FDevice.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +#include "Enums/EDevice.h" +#include "Enums/EPlatform.h" + +namespace HarmonyLinkLib +{ + // Struct to represent a specific device with both platform and device type + struct FDevice : HarmonyLinkStruct + { + EPlatform platform; + EDevice device; + }; +} diff --git a/HarmonyLinkLib/include/Structs/FOSVerInfo.h b/HarmonyLinkLib/include/Structs/FOSVerInfo.h new file mode 100644 index 0000000..6b62db3 --- /dev/null +++ b/HarmonyLinkLib/include/Structs/FOSVerInfo.h @@ -0,0 +1,50 @@ +#pragma once + +#include "FString.h" +#include "HarmonyLinkStruct.h" + +namespace HarmonyLinkLib +{ + struct FOSVerInfo : HarmonyLinkStruct { + // 'name' represents the operating system's name, e.g., "Ubuntu" in Linux or "Windows" in Windows systems. + FString name; + + // 'version' is a numerical representation of the OS version. In Linux, it might be the kernel version, + // whereas in Windows, it could be the major version number like 10 for Windows 10. + uint32_t version = 0; + + // 'id' is a unique identifier for the OS. In Linux, it might be a lower-case string like "ubuntu". + // In Windows, this could map to the edition ID, such as "Professional". + FString id; + + // 'version_id' is a string representing the specific version of the OS. + // For example, "20.04" in Ubuntu or "1909" in Windows 10. + FString version_id; + + // 'version_codename' is a codename for the OS version, if available. + // This is common in Linux distributions (e.g., "focal" for Ubuntu 20.04) but not typically used in Windows. + FString version_codename; + + // 'pretty_name' is a more readable version of the name, potentially including the version and codename. + // For example, "Ubuntu 20.04 LTS (Focal Fossa)" or "Windows 10 Pro". + FString pretty_name; + + // 'variant_id' is an identifier for the specific variant of the OS, if available. + // For example, in Linux distributions, this might be "desktop" for the desktop edition, + // "server" for the server edition, or "core" for a minimal installation. It helps distinguish + // between different flavors or editions of the same version. + // On the Steam Deck, this is set to "steamdeck". + FString variant_id; + + void print() const + { + wprintf(L"Name: '%hs'\n", name.c_str()); + wprintf(L"Version: '%d'\n", version); + wprintf(L"ID: '%hs'\n", id.c_str()); + wprintf(L"Version ID: '%hs'\n", version_id.c_str()); + wprintf(L"Version Codename: '%hs'\n", version_codename.c_str()); + wprintf(L"Pretty Name: '%hs'\n", pretty_name.c_str()); + wprintf(L"Variant ID: '%hs'\n", variant_id.c_str()); + } +}; +} diff --git a/HarmonyLinkLib/include/Version.h b/HarmonyLinkLib/include/Version.h new file mode 100644 index 0000000..61d6e3f --- /dev/null +++ b/HarmonyLinkLib/include/Version.h @@ -0,0 +1,45 @@ +// Copyright (C) 2024 Jordon Brooks +#pragma once + +#include "Core.h" +#include + +#include "FString.h" + +namespace HarmonyLinkLib +{ + class HARMONYLINKLIB_API version + { + public: + version() = default; + + static FString ToString() + { + return HARMONYLINK_VERSION; + } + + static FString get_build_timestamp() + { + return {__TIMESTAMP__}; + } + + static FString get_git_branch() + { + return {GIT_BRANCH_NAME}; + } + + static FString get_git_commit_timestamp() + { + return {GIT_COMMIT_TIMESTAMP}; + } + + static bool is_debug() + { +#ifdef DEBUG_MODE + return true; +#else + return false; +#endif + } + }; +} diff --git a/HarmonyLinkLib/include/Version.h.in b/HarmonyLinkLib/include/Version.h.in new file mode 100644 index 0000000..4081f8d --- /dev/null +++ b/HarmonyLinkLib/include/Version.h.in @@ -0,0 +1,11 @@ +// Version.h.in +#pragma once + +#define HARMONYLINK_VERSION_MAJOR @HarmonyLinkLib_VERSION_MAJOR@ +#define HARMONYLINK_VERSION_MINOR @HarmonyLinkLib_VERSION_MINOR@ +#define HARMONYLINK_VERSION_PATCH @HarmonyLinkLib_VERSION_PATCH@ +#define HARMONYLINK_VERSION_TWEAK @HarmonyLinkLib_VERSION_TWEAK@ +#define HARMONYLINK_VERSION "@HarmonyLinkLib_VERSION@" + +#define GIT_BRANCH_NAME "@GIT_BRANCH_NAME@" +#define GIT_COMMIT_TIMESTAMP "@GIT_COMMIT_TIMESTAMP@" diff --git a/HarmonyLinkLib/src/HarmonyLinkLib.cpp b/HarmonyLinkLib/src/HarmonyLinkLib.cpp new file mode 100644 index 0000000..d3f0bc2 --- /dev/null +++ b/HarmonyLinkLib/src/HarmonyLinkLib.cpp @@ -0,0 +1,94 @@ +#include "HarmonyLinkLib.h" + +#include +#include "Platform/IPlatformUtilities.h" + +namespace HarmonyLinkLib +{ + std::shared_ptr PlatformUtilities = IPlatformUtilities::GetInstance(); + + bool get_is_wine() + { + if (!PlatformUtilities) + { + std::wcout << "Failed to get platform utilities!\n"; + return false; + } + + return PlatformUtilities->is_running_under_wine(); + } + + FCPUInfo* get_cpu_info() + { + if (!PlatformUtilities) + { + std::wcout << "Failed to get platform utilities!\n"; + return nullptr; + } + + const std::shared_ptr cpu_info = PlatformUtilities->get_cpu_info(); + if (!cpu_info) + { + return nullptr; + } + + FCPUInfo* new_cpu_info = new FCPUInfo(*cpu_info); + return new_cpu_info; + } + + FDevice* get_device_info() + { + if (!PlatformUtilities) + { + std::wcout << "Failed to get platform utilities!\n"; + return nullptr; + } + + const std::shared_ptr device = PlatformUtilities->get_device(); + if (!device) + { + return nullptr; + } + + FDevice* new_device = new FDevice(*device); + return new_device; + } + + FOSVerInfo* get_os_version() + { + + + if (!PlatformUtilities) + { + std::wcout << "Failed to get platform utilities!\n"; + return nullptr; + } + + const std::shared_ptr os_version_info = PlatformUtilities->get_os_version(); + if (!os_version_info) + { + return nullptr; + } + + FOSVerInfo* new_os_info = new FOSVerInfo(*os_version_info); + return new_os_info; + } + + FBattery* get_battery_status() + { + if (!PlatformUtilities) + { + std::wcout << "Failed to get platform utilities!\n"; + return nullptr; + } + + const std::shared_ptr new_battery = PlatformUtilities->get_battery_status(); + if (!new_battery) + { + return nullptr; + } + + FBattery* battery = new FBattery(*new_battery); + return battery; + } +} diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp b/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp new file mode 100644 index 0000000..44d6e80 --- /dev/null +++ b/HarmonyLinkLib/src/Platform/IPlatformUtilities.cpp @@ -0,0 +1,122 @@ +#include "IPlatformUtilities.h" + +#include + +#include "WineUtilities.h" +#if BUILD_WINDOWS +#include "Windows/WindowsUtilities.h" +#elif BUILD_LINUX +#include "Unix/Linux/LinuxUtilities.h" +#elif BUILD_MAC +#include "Unix/Mac/MacUtilities.h" +#elif BUILD_UNIX +#include "Unix/Mac/MacUtilities.h" +#endif + +namespace HarmonyLinkLib +{ + static std::shared_ptr INSTANCE = nullptr; + +std::shared_ptr& IPlatformUtilities::GetInstance() +{ + if (!INSTANCE) + { +#if BUILD_WINDOWS + INSTANCE = std::make_shared(); +#elif BUILD_LINUX + INSTANCE = std::make_shared(); +#elif BUILD_MAC + INSTANCE = std::make_shared(); +#elif BUILD_UNIX + INSTANCE = std::make_shared(); +// ... other platform checks +#else + std::wcout << "Platform is not supported.\n" +#endif + } + + return INSTANCE; +} + +bool IPlatformUtilities::is_running_under_wine() +{ + return WineUtilities::is_wine_present(); +} + +bool IPlatformUtilities::is_linux() +{ +#ifdef BUILD_LINUX + return true; +#else + return is_running_under_wine(); +#endif +} + +std::shared_ptr IPlatformUtilities::get_device() +{ + FDevice new_device; + + if (is_linux()) + { + new_device.platform = EPlatform::LINUX; + } + else + { + new_device.platform = EPlatform::WINDOWS; + } + + const std::shared_ptr battery_status = get_battery_status(); + + if (battery_status && !battery_status->has_battery) + { + new_device.device = EDevice::DESKTOP; + } + else + { + new_device.device = EDevice::LAPTOP; + } + + if (is_steam_deck(new_device)) { + new_device.device = EDevice::STEAM_DECK; + } + return std::make_shared(new_device); +} + +// Helper function to check if the device is a Steam Deck +bool IPlatformUtilities::is_steam_deck(const FDevice& device) { + + // Check if the device is already identified as a Steam Deck + if (device.device == EDevice::STEAM_DECK) { + return true; + } + + // Check for Steam Deck by OS version + if (const std::shared_ptr version = get_os_version()) { + if (version->variant_id == "steamdeck" && version->name == "SteamOS") { + return true; + } + } else { + wprintf(L"OS version information not available.\n"); + } + + // Set of known Steam Deck CPU model names + const std::set steam_deck_models = {"amd custom apu 0405" /*, other models... */}; + + // Check for Steam Deck by CPU model name + if (const std::shared_ptr cpu_info = get_cpu_info()) { + const FString cpu_model_lower = FString::to_lower(cpu_info->Model_Name); + for (const auto& model : steam_deck_models) { + if (cpu_model_lower == model) { + wprintf(L"Steam Deck detected by CPU model name.\n"); + return true; + } + } + } else { + wprintf(L"CPU information not available.\n"); + } + + wprintf(L"Device is not a Steam Deck.\n"); + + return false; +} +} diff --git a/HarmonyLinkLib/src/Platform/IPlatformUtilities.h b/HarmonyLinkLib/src/Platform/IPlatformUtilities.h new file mode 100644 index 0000000..b3d55da --- /dev/null +++ b/HarmonyLinkLib/src/Platform/IPlatformUtilities.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Structs/FBattery.h" +#include "Structs/FCPUInfo.h" +#include "Structs/FDevice.h" +#include "Structs/FOSVerInfo.h" + +namespace HarmonyLinkLib +{ + class IPlatformUtilities { + public: + static std::shared_ptr& GetInstance(); + + IPlatformUtilities() = default; + IPlatformUtilities(const IPlatformUtilities& other) = default; + IPlatformUtilities(IPlatformUtilities&& other) = default; + IPlatformUtilities& operator=(const IPlatformUtilities& other) = default; + IPlatformUtilities& operator=(IPlatformUtilities&& other) = default; + virtual ~IPlatformUtilities() = default; + + // General OS-level functions + virtual bool is_running_under_wine(); + virtual bool is_linux(); + + virtual std::shared_ptr get_device(); + virtual std::shared_ptr get_cpu_info() = 0; + virtual std::shared_ptr get_battery_status() = 0; + virtual std::shared_ptr get_os_version() = 0; + + bool is_steam_deck(const FDevice& device); + + // Add more virtual functions for other OS interactions here + }; +} diff --git a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp b/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp new file mode 100644 index 0000000..fa7e4ff --- /dev/null +++ b/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.cpp @@ -0,0 +1,24 @@ +#include "LinuxUtilities.h" + + +#include +#include +#include "Platform/WineUtilities.h" + +namespace HarmonyLinkLib +{ + std::shared_ptr LinuxUtilities::get_battery_status() + { + return WineUtilities::get_battery_status(); + } + + std::shared_ptr LinuxUtilities::get_os_version() + { + return WineUtilities::get_linux_info(); + } + + std::shared_ptr LinuxUtilities::get_cpu_info() + { + return WineUtilities::get_cpu_info(); + } +} diff --git a/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h b/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h new file mode 100644 index 0000000..6e7d780 --- /dev/null +++ b/HarmonyLinkLib/src/Platform/Unix/Linux/LinuxUtilities.h @@ -0,0 +1,23 @@ +#pragma once + +#include "Structs/FOSVerInfo.h" + +#include "Platform/Unix/UnixUtilities.h" + +namespace HarmonyLinkLib +{ + class LinuxUtilities : public UnixUtilities { + public: + // Implementation for other Linux-specific functions + std::shared_ptr get_battery_status() override; + + std::shared_ptr get_os_version() override; + + std::shared_ptr get_cpu_info() override; + + bool is_linux() override + { + return true; + } + }; +} diff --git a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp b/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp new file mode 100644 index 0000000..2166845 --- /dev/null +++ b/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.cpp @@ -0,0 +1,6 @@ +#include "MacUtilities.h" + +namespace HarmonyLinkLib +{ + +} \ No newline at end of file diff --git a/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h b/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h new file mode 100644 index 0000000..e636401 --- /dev/null +++ b/HarmonyLinkLib/src/Platform/Unix/Mac/MacUtilities.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Platform/Unix/UnixUtilities.h" + +namespace HarmonyLinkLib +{ + class MacUtitities : public UnixUtilities { + public: + // Mac-specific overrides and additional functionality + }; +} diff --git a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp b/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp new file mode 100644 index 0000000..46ef352 --- /dev/null +++ b/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.cpp @@ -0,0 +1,24 @@ +#include "UnixUtilities.h" + +namespace HarmonyLinkLib +{ + bool UnixUtilities::is_running_under_wine() + { + return false; + } + + std::shared_ptr UnixUtilities::get_cpu_info() + { + return nullptr; + } + + std::shared_ptr UnixUtilities::get_battery_status() + { + return nullptr; + } + + std::shared_ptr UnixUtilities::get_os_version() + { + return nullptr; + } +} \ No newline at end of file diff --git a/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h b/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h new file mode 100644 index 0000000..b17e42e --- /dev/null +++ b/HarmonyLinkLib/src/Platform/Unix/UnixUtilities.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Platform/IPlatformUtilities.h" +namespace HarmonyLinkLib +{ + class UnixUtilities : public IPlatformUtilities { + public: + bool is_running_under_wine() override; + + std::shared_ptr get_cpu_info() override; + std::shared_ptr get_battery_status() override; + std::shared_ptr get_os_version() override; + + // Implementation for other Unix/Linux-specific functions + }; +} diff --git a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp b/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp new file mode 100644 index 0000000..4384a7a --- /dev/null +++ b/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.cpp @@ -0,0 +1,81 @@ +#include "WindowsUtilities.h" + +#include +#include + +#include "Platform/WineUtilities.h" + +namespace HarmonyLinkLib +{ + std::shared_ptr WindowsUtilities::get_battery_status() +{ + if (is_linux()) + { + return WineUtilities::get_battery_status(); + } + FBattery result; + + SYSTEM_POWER_STATUS status; + if (GetSystemPowerStatus(&status)) { + result.has_battery = status.BatteryFlag != 128; // 128 indicates no battery + result.is_connected_to_ac = status.ACLineStatus == 1; + result.battery_percent = result.has_battery ? status.BatteryLifePercent : 0; + } else { + std::wcout << "Failed to get power statistics.\n"; + } + + return std::make_shared(result); +} + +std::shared_ptr WindowsUtilities::get_cpu_info() +{ + if (is_linux()) + { + return WineUtilities::get_cpu_info(); + } + + return {}; +} + +std::shared_ptr WindowsUtilities::get_os_version() +{ + if (is_linux()) + { + return WineUtilities::get_linux_info(); + } + + OSVERSIONINFOEX os_version_info; + ZeroMemory(&os_version_info, sizeof(OSVERSIONINFOEX)); + os_version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if (!GetVersionEx(reinterpret_cast(&os_version_info))) { + // Handle error if needed + return nullptr; + } + + FOSVerInfo os_version; + + HKEY h_key; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_READ, &h_key) == ERROR_SUCCESS) + { + DWORD dw_size; + DWORD dw_type; + char sz_product_name[256]; + dw_size = sizeof(sz_product_name); + if (RegQueryValueEx(h_key, TEXT("ProductName"), nullptr, &dw_type, reinterpret_cast(sz_product_name), &dw_size) == ERROR_SUCCESS) + { + os_version.pretty_name = sz_product_name; + } + RegCloseKey(h_key); + } + + std::stringstream version; + version << os_version_info.dwMajorVersion << "." << os_version_info.dwMinorVersion; + os_version.version_id = version.str(); + + os_version.name = "Windows"; + os_version.version = os_version_info.dwBuildNumber; // Build number as the version + + return std::make_shared(os_version); +} +} diff --git a/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h b/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h new file mode 100644 index 0000000..849d269 --- /dev/null +++ b/HarmonyLinkLib/src/Platform/Windows/WindowsUtilities.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Platform/IPlatformUtilities.h" + +namespace HarmonyLinkLib +{ + class WindowsUtilities : public IPlatformUtilities + { + public: + std::shared_ptr get_battery_status() override; + + std::shared_ptr get_cpu_info() override; + + std::shared_ptr get_os_version() override; + }; +} diff --git a/HarmonyLinkLib/src/Platform/WineUtilities.cpp b/HarmonyLinkLib/src/Platform/WineUtilities.cpp new file mode 100644 index 0000000..3b420b1 --- /dev/null +++ b/HarmonyLinkLib/src/Platform/WineUtilities.cpp @@ -0,0 +1,202 @@ +#include "WineUtilities.h" + +#include +#include +#include +#include +#include + +#ifdef BUILD_WINDOWS +#include +#endif + +namespace HarmonyLinkLib +{ + bool force_detect_wine = false; + + std::shared_ptr HarmonyLinkLib::WineUtilities::get_battery_status() + { + std::string append; + if (is_wine_present()) + { + append = "Z:"; + } + + FBattery result = {}; + for (int i = 0; i <= 9; ++i) { + if (std::string bat_path = append + "/sys/class/power_supply/BAT" + std::to_string(i); std::filesystem::exists(bat_path)) { + result.has_battery = true; + + std::ifstream status_file(bat_path + "/status"); + std::string status; + if (status_file.is_open() && std::getline(status_file, status)) { + if (status == "Charging" || status == "AC") { + result.is_connected_to_ac = true; + } + } + + std::ifstream capacity_file(bat_path + "/capacity"); + if (capacity_file.is_open() && std::getline(capacity_file, status)) { + result.battery_percent = static_cast(std::stoi(status)); + break; // assuming you only need data from the first battery found + } + } + } + + return std::make_shared(result); + } + + std::shared_ptr WineUtilities::get_cpu_info() + { + std::wcout << "Getting cpu info\n"; + + std::string append; + if (is_wine_present()) + { + append = "Z:"; + } + + FCPUInfo cpu_info; + + std::ifstream file(append + "/proc/cpuinfo"); + std::unordered_map hashmap; + + if (file) { + std::string line; + while (std::getline(file, line)) { + std::istringstream line_stream(line); + std::string key, value; + if (std::getline(line_stream, key, ':')) { + key.erase(key.find_last_not_of(" \t") + 1); // Trim trailing whitespace from key + if (std::getline(line_stream, value)) { + value.erase(0, value.find_first_not_of(" \t")); // Trim leading whitespace from value + + // Aggregate flags + if (key == "flags") { + std::istringstream flag_stream(value); + std::string flag; + while (flag_stream >> flag) { + flag.erase(flag.find_last_not_of(" \t") + 1); // Trim trailing whitespace from flag + cpu_info.Flags.insert(HarmonyLinkLib::FString(flag)); + //printf("Flag detected: %s\n", flag.c_str()); + } + } else { + hashmap[key] = value; + } + } + } + } + file.close(); + } + + // Now you can access the values using the keys: + cpu_info.VendorID = hashmap["vendor_id"]; + cpu_info.Model_Name = hashmap["model name"]; + + try { + cpu_info.Physical_Cores = std::stoi(hashmap["cpu cores"].c_str()); + } catch (const std::invalid_argument& ia) { + std::wcerr << "Invalid argument: " << ia.what() << '\n'; + } catch (const std::out_of_range& oor) { + std::wcerr << "Out of Range error: " << oor.what() << '\n'; + } + + cpu_info.Logical_Cores = (cpu_info.Flags.find("ht") != cpu_info.Flags.end()) ? cpu_info.Physical_Cores * 2 : cpu_info.Physical_Cores; + + return std::make_shared(cpu_info); + } + + std::shared_ptr WineUtilities::get_linux_info() + { + std::string append; + if (is_wine_present()) + { + append = "Z:"; + } + + FOSVerInfo os_info; + + std::ifstream file(append + "/etc/os-release"); + std::unordered_map hashmap; + + if (file) { + std::string line; + while (std::getline(file, line)) { + std::istringstream lineStream(line); + std::string key, value; + if (std::getline(lineStream, key, '=')) { + if (std::getline(lineStream, value)) { + // Remove leading and trailing whitespace + size_t firstNonSpace = value.find_first_not_of(" \t"); + size_t lastNonSpace = value.find_last_not_of(" \t"); + if (firstNonSpace != std::string::npos && lastNonSpace != std::string::npos) { + value = value.substr(firstNonSpace, lastNonSpace - firstNonSpace + 1); + } else { + value.clear(); // If value is all whitespace, make it empty + } + + // Check for double quotes and remove them + if (!value.empty() && value.front() == '"' && value.back() == '"') { + value = value.substr(1, value.length() - 2); + } + + hashmap[key] = value; + } + } + } + file.close(); + } + + // Now you can access the values using the keys: + os_info.name = hashmap["NAME"]; + os_info.id = hashmap["ID"]; + os_info.version_id = hashmap["VERSION_ID"]; + os_info.version_codename = hashmap["VERSION_CODENAME"]; + os_info.pretty_name = hashmap["PRETTY_NAME"]; + + try { + os_info.version = std::stoi(hashmap["VERSION"].c_str()); + } catch (const std::invalid_argument& ia) { + std::cerr << "Invalid argument: " << ia.what() << '\n'; + // Handle the error, perhaps by setting a default value or leaving the field unchanged + } catch (const std::out_of_range& oor) { + std::cerr << "Out of Range error: " << oor.what() << '\n'; + // Handle the error, perhaps by setting a default value or leaving the field unchanged + } + + return std::make_shared(os_info); + } + + bool WineUtilities::is_wine_present() + { + static bool isWineCached = false; // Static variable to store the cached result + static bool isWine = false; // Static variable to indicate if the caching has been done + + if (!isWineCached) + { + // Only detect wine if force_detect_wine is true or if we haven't cached the result yet +#ifdef BUILD_WINDOWS + std::wcout << "Detecting wine...\n"; + bool HasFound = GetProcAddress(GetModuleHandle("ntdll.dll"), "wine_get_version") != nullptr; + + if (!HasFound) + HasFound = GetProcAddress(GetModuleHandle("ntdll.dll"), "proton_get_version") != nullptr; + + wprintf(L"wine %s found\n", HasFound ? L"has been" : L"not"); + + isWine = HasFound; // Cache the result +#else + isWine = false; // In non-Windows builds, always set isWine to false +#endif + isWineCached = true; // Indicate that the result is now cached + } + + return isWine; // Return the cached result + } + + bool WineUtilities::force_detect_wine_presence() + { + force_detect_wine = true; + return is_wine_present(); + } +} diff --git a/HarmonyLinkLib/src/Platform/WineUtilities.h b/HarmonyLinkLib/src/Platform/WineUtilities.h new file mode 100644 index 0000000..33f2b30 --- /dev/null +++ b/HarmonyLinkLib/src/Platform/WineUtilities.h @@ -0,0 +1,46 @@ +#pragma once + +#include "Structs/FBattery.h" +#include "Structs/FCPUInfo.h" +#include "Structs/FOSVerInfo.h" + +namespace HarmonyLinkLib +{ + class WineUtilities + { + public: + static std::shared_ptr get_battery_status(); + + static std::shared_ptr get_cpu_info(); + + /** + * @brief Retrieves Linux OS version information from a specified file. + * + * This function parses a file (typically a Linux OS release file) at the given location + * to extract operating system version information. It reads key-value pairs from the file, + * processes them to handle whitespace and quotes, and then stores them in an FOSVerInfo + * structure. If the file location is invalid or the file cannot be opened, it returns an + * empty FOSVerInfo structure. Errors during parsing, such as invalid format or out of range + * values, are handled with exception catching. In Windows builds where Wine is detected, + * this function can use the file location 'Z:/etc/os-release' to retrieve the underlying + * Linux system information. + * + * @param file_location The location of the file containing OS version information. + * @return A shared pointer to a structure containing the parsed OS version information. + */ + static std::shared_ptr get_linux_info(); + + /** + * @brief Detects the presence of Wine or Proton in Windows builds. + * + * This function assesses if the application is running under Wine or Proton by + * querying specific functions in the 'ntdll.dll' module. It is only active in + * Windows builds, returning false for non-Windows builds. + * + * @return bool True if Wine or Proton is detected, false otherwise. + */ + static bool is_wine_present(); + + static bool force_detect_wine_presence(); + }; +} diff --git a/HarmonyLinkLib/src/Version.cpp b/HarmonyLinkLib/src/Version.cpp new file mode 100644 index 0000000..50b5049 --- /dev/null +++ b/HarmonyLinkLib/src/Version.cpp @@ -0,0 +1 @@ +#include "Version.h" diff --git a/HarmonyLinkLib/src/dllmain.cpp b/HarmonyLinkLib/src/dllmain.cpp new file mode 100644 index 0000000..a292db4 --- /dev/null +++ b/HarmonyLinkLib/src/dllmain.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2024 Jordon Brooks + +#include +#include "Version.h" + +namespace HarmonyLinkLib +{ + void HarmonyLinkInit() + { + std::wcout << "HarmonyLink V" << version::ToString().c_str() << " Copyright (C) 2023 Jordon Brooks\n"; + } +} + + +#if BUILD_WINDOWS +#include + +// Standard DLL entry point +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + // Code to run when the DLL is loaded + HarmonyLinkLib::HarmonyLinkInit(); + break; + case DLL_THREAD_ATTACH: + // Code to run when a thread is created during the DLL's lifetime + case DLL_THREAD_DETACH: + // Code to run when a thread ends normally. + case DLL_PROCESS_DETACH: + // Code to run when the DLL is unloaded + default: + break; + } + return TRUE; // Successful DLL_PROCESS_ATTACH. +} +#endif + +#if BUILD_UNIX +__attribute__((constructor)) +static void onLibraryLoad() { + // Code to run when the library is loaded + HarmonyLinkLib::HarmonyLinkInit(); +} + +__attribute__((destructor)) +static void onLibraryUnload() { + // Code to run when the library is unloaded +} +#endif diff --git a/HarmonyLinkTest/CMakeLists.txt b/HarmonyLinkTest/CMakeLists.txt new file mode 100644 index 0000000..5616a24 --- /dev/null +++ b/HarmonyLinkTest/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.10) +project(HarmonyLinkTest) + +# Specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# Automatically add all .cpp and .h/.hpp files in the src directory +file(GLOB_RECURSE TEST_SOURCES "src/*.cpp") +file(GLOB_RECURSE TEST_HEADERS "src/*.h" "src/*.hpp") + +# Add executable +add_executable(HarmonyLinkTest ${TEST_SOURCES} ${TEST_HEADERS}) + +# Link the HarmonyLinkLib with HarmonyLinkTest +target_link_libraries(HarmonyLinkTest PRIVATE HarmonyLinkLib) + +# Set output directories for all build types +foreach(TYPE IN ITEMS DEBUG RELEASE) + string(TOUPPER ${TYPE} TYPE_UPPER) + set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}/${PROJECT_NAME}" + LIBRARY_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}/${PROJECT_NAME}" + ARCHIVE_OUTPUT_DIRECTORY_${TYPE_UPPER} "${CMAKE_BINARY_DIR}/bin/${TYPE}/${PROJECT_NAME}" + ) +endforeach() + +add_custom_command(TARGET HarmonyLinkTest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "$") diff --git a/HarmonyLinkTest/src/main.cpp b/HarmonyLinkTest/src/main.cpp new file mode 100644 index 0000000..6b7ac05 --- /dev/null +++ b/HarmonyLinkTest/src/main.cpp @@ -0,0 +1,143 @@ +// Copyright (C) 2023 Jordon Brooks + +#include +#include +#include +#include + +#include "HarmonyLinkLib.h" + +// Include necessary headers for platform-specific functionality +#ifdef BUILD_WINDOWS +#include // For _kbhit() and _getch() +#include // For system("cls") +#else +#include // For read() +#include // For termios +#include // For getchar() +#include // For F_GETFL, F_SETFL and O_NONBLOCK +#endif + +std::atomic quitFlag(false); + +// Function to clear the screen cross-platform +void clearScreen() { +#ifdef _WIN32 + system("cls"); +#else + std::cout << "\x1B[2J\x1B[H"; +#endif +} + + +// Function to check if 'q' or 'Q' is pressed in Windows +void checkForQuit() { + while (!quitFlag) { +#ifdef BUILD_WINDOWS + if (_kbhit()) { + const char c = static_cast(_getch()); + if (c == 'q' || c == 'Q') { + quitFlag = true; + break; + } + } +#else + struct termios oldt, newt; + int ch; + int oldf; + + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + oldf = fcntl(STDIN_FILENO, F_GETFL, 0); + fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); + + ch = getchar(); + + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + fcntl(STDIN_FILENO, F_SETFL, oldf); + + if (ch != EOF) { + ungetc(ch, stdin); + if (ch == 'q' || ch == 'Q') { + quitFlag = true; + break; + } + } +#endif + // Checks for input every roughly 60 frames + std::this_thread::sleep_for(std::chrono::milliseconds(16)); + } +} + +int main() +{ + std::cout << "Hello, World!" << '\n'; + + std::thread inputThread(checkForQuit); + + const bool isWine = HarmonyLinkLib::get_is_wine(); + const char* test = isWine ? "is" : "isn't"; + + const HarmonyLinkLib::FOSVerInfo* os_info = HarmonyLinkLib::get_os_version(); + + const HarmonyLinkLib::FDevice* device_info = HarmonyLinkLib::get_device_info(); + + const HarmonyLinkLib::FCPUInfo* cpu_info = HarmonyLinkLib::get_cpu_info(); + + // This loop is to test how stable & expensive these functions are + while (!quitFlag) + { + // Clear the screen + clearScreen(); + + std::wcout << "This program " << test << " running under wine.\n"; + + if (cpu_info) + { + cpu_info->print(); + } + + if (os_info) + { + os_info->print(); + } + + if (device_info) + { + wprintf(L"Is SteamDeck: %s\n", device_info->device == HarmonyLinkLib::EDevice::STEAM_DECK ? L"true" : L"false"); + } + + // we can't do this before the loop because we need updated values + if (const HarmonyLinkLib::FBattery* battery = HarmonyLinkLib::get_battery_status()) + { + battery->to_string(); + battery->free(); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + if (inputThread.joinable()) + { + inputThread.join(); + } + + if (os_info) + { + os_info->free(); + } + + if (device_info) + { + device_info->free(); + } + + if (cpu_info) + { + cpu_info->free(); + } + + return 0; +} diff --git a/Resources/dock_models.json b/Resources/dock_models.json deleted file mode 100644 index 4da9504..0000000 --- a/Resources/dock_models.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "brand": "JSAUX", - "model": "HB0603", - "usb_ids": [ - [ 4826, 21521 ], - [ 4826, 1041 ], - [ 4826, 33139 ] - ] - } -] \ No newline at end of file diff --git a/build.rs b/build.rs deleted file mode 100644 index 0c857ec..0000000 --- a/build.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; -use std::path::Path; - -use vergen::EmitBuilder; - -fn copy_resources() -> Result<(), Box> { - // The directory of the Cargo manifest of the package that is currently being built. - let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is not defined"); - - // The directory where the final binaries will be placed. - let profile = env::var("PROFILE")?; - let out_dir = Path::new(&manifest_dir).join("target").join(profile).join("Resources"); - - if !out_dir.exists() { - fs::create_dir(&out_dir)?; - } - - // The Resources directory. - let resources_dir = Path::new(&manifest_dir).join("Resources"); - - // Ensure the Resources directory exists. - if !resources_dir.exists() { - panic!("Resources directory does not exist"); - } - - // Iterate over each entry in the Resources directory. - for entry in fs::read_dir(resources_dir)? { - let entry = entry?; - let path = entry.path(); - if path.is_file() { - // The destination path is the output directory plus the file name. - let dest_path = out_dir.join(path.file_name().expect("file has no name")); - // Copy the file. - fs::copy(&path, &dest_path)?; - } - } - - Ok(()) -} - -#[cfg(windows)] -fn windows_resource() -> Result<(), Box> { - let mut res = winres::WindowsResource::new(); - res.set_icon("res/HarmonyLinkLogo.ico"); - res.compile()?; - Ok(()) -} - -#[cfg(unix)] -fn windows_resource() -> Result<(), Box> { - Ok(()) -} - -fn main() -> Result<(), Box> { - // Emit the instructions - EmitBuilder::builder() - .all_build() - .all_cargo() - .all_git() - .all_rustc() - .all_sysinfo() - .emit()?; - - // Copy the Resources folder - copy_resources()?; - - windows_resource()?; - - Ok(()) -} diff --git a/src/api/api.rs b/src/api/api.rs deleted file mode 100644 index 1709874..0000000 --- a/src/api/api.rs +++ /dev/null @@ -1,14 +0,0 @@ -use actix_web::{HttpResponse, get, web}; - -use crate::version::info::Version; - -#[get("/supported_versions")] -pub async fn versions() -> HttpResponse { - let version = Version::get(); - HttpResponse::Ok().json(&version.supported_api_versions) -} - -pub fn configure(cfg: &mut web::ServiceConfig) { - cfg.service(versions); - // Register other version 1 handlers here... -} \ No newline at end of file diff --git a/src/api/endpoints_v1.rs b/src/api/endpoints_v1.rs deleted file mode 100644 index d055b7c..0000000 --- a/src/api/endpoints_v1.rs +++ /dev/null @@ -1,99 +0,0 @@ -use actix_web::web; -use actix_web::{HttpResponse, get}; - -use crate::v1::{docking, os, all_info, battery}; -use crate::version; - -#[get("/are_you_there")] -pub async fn heartbeat() -> HttpResponse { - HttpResponse::Ok().body("yes") -} - -#[get("/all_info")] -pub async fn get_all_info() -> HttpResponse { - match all_info::stats::get_all_info() { - Ok(info) => { - - #[cfg(debug_assertions)] - { - println!("Successfully got all info: {}", &info.clone().to_string()); - } - HttpResponse::Ok().json(&info) - }, - Err(err) => { - eprintln!("Failed to get all info: {}", err); - HttpResponse::InternalServerError().body(format!("Failed to get device info: {}", err)) - } - } -} - -#[get("/dock_info")] -pub async fn get_dock_info() -> HttpResponse { - match docking::stats::get_dock() { - Ok(info) => { - #[cfg(debug_assertions)] - { - println!("Successfully got dock info: {}", &info.clone().to_string()); - } - HttpResponse::Ok().json(&info) - }, - Err(err) => { - eprintln!("Failed to get dock info: {}", err); - HttpResponse::InternalServerError().body(format!("Failed to get dock info: {}", err)) - } - } -} - - -#[get("/os_info")] -pub async fn get_os_info() -> HttpResponse { - match os::stats::get_os() { - Ok(info) => { - #[cfg(debug_assertions)] - { - println!("Successfully got os info: {}", &info.clone().to_string()); - } - HttpResponse::Ok().json(&info) - }, - Err(err) => { - eprintln!("Failed to get os info: {}", err); - HttpResponse::InternalServerError().body(format!("Failed to get OS info: {}", err)) - } - } -} - -#[get("/battery_info")] -pub async fn get_battery_info() -> HttpResponse { - match battery::stats::get_battery_info() { - Ok(info) => { - #[cfg(debug_assertions)] - { - println!("Successfully got battery info: {}", &info.clone().to_string()); - } - HttpResponse::Ok().json(&info) - }, - Err(err) => { - eprintln!("Failed to get battery info: {}", err); - HttpResponse::InternalServerError().body(format!("Failed to get battery info: {}", err)) - } - } -} - -#[get("/version_info")] -pub async fn get_version_info() -> HttpResponse { - #[cfg(debug_assertions)] - { - println!("Successfully got version info: {}", version::info::Version::get().to_string()); - } - HttpResponse::Ok().json(&version::info::Version::get()) -} - -pub fn configure(cfg: &mut web::ServiceConfig) { - cfg.service(heartbeat); - cfg.service(get_all_info); - cfg.service(get_dock_info); - cfg.service(get_os_info); - cfg.service(get_battery_info); - cfg.service(get_version_info); - // Register other version 1 handlers here... -} \ No newline at end of file diff --git a/src/api/mod.rs b/src/api/mod.rs deleted file mode 100644 index e02bcc6..0000000 --- a/src/api/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod server; -mod endpoints_v1; -mod api; \ No newline at end of file diff --git a/src/api/server.rs b/src/api/server.rs deleted file mode 100644 index d9233f5..0000000 --- a/src/api/server.rs +++ /dev/null @@ -1,28 +0,0 @@ -use actix_web::{HttpServer, web}; - -use crate::api::endpoints_v1; -use crate::api::api; - -#[allow(dead_code)] -pub async fn stop_actix_web(server: actix_web::dev::Server) -> std::io::Result<()> { - println!("Stopping server."); - server.handle().stop(true).await; - Ok(()) -} - -pub fn start_actix_web(port: u16) -> std::io::Result { - - println!("Starting webserver on 127.0.0.1:{}", port); - - let server = HttpServer::new(move || { - let logger = actix_web::middleware::Logger::default(); - actix_web::App::new() - .wrap(logger) - .service(web::scope("/api").configure(api::configure)) - .service(web::scope("/v1").configure(endpoints_v1::configure)) - }) - .bind(("127.0.0.1", port))? - .run(); - - Ok(server) -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index ea17ce1..0000000 --- a/src/main.rs +++ /dev/null @@ -1,37 +0,0 @@ -mod v1; - -mod version; -use version::info::Version; - -mod api; - -static PORT: u16 = 9000; - -static USE_FALLBACK_DOCK_DETECTION: bool = false; - -fn main() { - - //#[cfg(debug_assertions)] - { - let version_info = Version::get(); - println!("Version: {}", version_info.version); - println!("Build Timestamp: {}", version_info.build_timestamp); - println!("Git Branch: {}", version_info.git_branch); - println!("Git Describe: {}", version_info.git_describe); - println!("Git Commit Timestamp: {}", version_info.git_commit_timestamp); - println!("Debug Build: {}", version_info.debug); - println!("API versions: {}", version_info.supported_api_versions_to_string()); - - println!("\n\n"); - } - - println!("HarmonyLink ©️ Jordon Brooks 2023"); - - - let sys = actix_web::rt::System::new(); - sys.block_on(async { - let result = api::server::start_actix_web(PORT).expect("err"); - - let _ = result.await; - }); -} diff --git a/src/v1/all_info/mod.rs b/src/v1/all_info/mod.rs deleted file mode 100644 index 8a30527..0000000 --- a/src/v1/all_info/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod stats; -pub mod structs; \ No newline at end of file diff --git a/src/v1/all_info/stats.rs b/src/v1/all_info/stats.rs deleted file mode 100644 index 1e3ebc6..0000000 --- a/src/v1/all_info/stats.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::v1::docking; -use crate::v1::battery; -use crate::v1::os; -use crate::version; - -use super::structs::Allinfo; - -/* This will query all the modules and return all the combined data */ -pub fn get_all_info() -> Result> { - let mut all_info = Allinfo::new(); - - all_info.dock = docking::stats::get_dock_info()?; - all_info.battery = battery::stats::get_battery_info()?; - all_info.os = os::stats::get_os()?; - all_info.version = version::info::Version::get(); - - Ok(all_info) -} \ No newline at end of file diff --git a/src/v1/all_info/structs.rs b/src/v1/all_info/structs.rs deleted file mode 100644 index 6e39a11..0000000 --- a/src/v1/all_info/structs.rs +++ /dev/null @@ -1,24 +0,0 @@ -use serde::{Deserialize, Serialize}; -use crate::{v1::{os, battery, docking::{self, structs::DockInfo}}, version}; - - -#[derive(Deserialize, Serialize, Clone)] -pub struct Allinfo { - pub os: os::structs::OSInfo, - pub battery: battery::structs::BatteryInfo, - pub dock: docking::structs::DockInfo, - pub version: version::info::Version -} - -impl Allinfo { - pub fn new() -> Allinfo { - Allinfo { os: os::structs::OSInfo::new(), - battery: battery::structs::BatteryInfo::new(), - dock: DockInfo::new(), - version: version::info::Version::get() - } - } - pub fn to_string(self) -> String { - serde_json::to_string(&self).expect("Failed to parse into string") - } -} \ No newline at end of file diff --git a/src/v1/battery/mod.rs b/src/v1/battery/mod.rs deleted file mode 100644 index 8a30527..0000000 --- a/src/v1/battery/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod stats; -pub mod structs; \ No newline at end of file diff --git a/src/v1/battery/stats.rs b/src/v1/battery/stats.rs deleted file mode 100644 index 0ffb957..0000000 --- a/src/v1/battery/stats.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::v1::battery::structs::ChargingStatus; - -use super::structs::BatteryInfo; - -pub fn get_battery_info() -> Result> { - let mut battery_info = BatteryInfo { has_battery: false, battery_percent: 0, charging_status: ChargingStatus::UNKNOWN }; - - let manager = battery::Manager::new().unwrap(); - - battery_info.has_battery = manager.batteries().unwrap().count() > 0; - - if !battery_info.has_battery { - return Ok(battery_info); - } - - for (idx, battery) in manager.batteries()?.enumerate() { - let battery = battery?; - let state = battery.state(); - let energy = battery.energy(); - let full_energy = battery.energy_full(); - let state_of_charge = (energy / full_energy).get::(); - - println!("Battery #{}:", idx); - println!("Charging status: {:?}", state); - println!("Charge level: {:.2}%", state_of_charge); - - battery_info.battery_percent = state_of_charge.round() as i8; - battery_info.charging_status = match state { - battery::State::Charging => ChargingStatus::Charging, - battery::State::Discharging => ChargingStatus::Battery, - battery::State::Empty => ChargingStatus::Battery, - battery::State::Full => ChargingStatus::Battery, - _ => ChargingStatus::UNKNOWN, - } - } - - Ok(battery_info) -} \ No newline at end of file diff --git a/src/v1/battery/structs.rs b/src/v1/battery/structs.rs deleted file mode 100644 index 2f9f202..0000000 --- a/src/v1/battery/structs.rs +++ /dev/null @@ -1,28 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize, Serialize, PartialEq, Clone)] -pub enum ChargingStatus { - Charging, - Battery, - UNKNOWN, -} - -#[derive(Deserialize, Serialize, Clone)] -pub struct BatteryInfo { - pub has_battery: bool, - pub battery_percent: i8, - pub charging_status: ChargingStatus, -} - -impl BatteryInfo { - pub fn new() -> BatteryInfo { - BatteryInfo { - has_battery: false, - battery_percent: 0, - charging_status: ChargingStatus::UNKNOWN - } - } - pub fn to_string(self) -> String { - serde_json::to_string(&self).expect("Failed to parse into string") - } -} \ No newline at end of file diff --git a/src/v1/docking/mod.rs b/src/v1/docking/mod.rs deleted file mode 100644 index 8a30527..0000000 --- a/src/v1/docking/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod stats; -pub mod structs; \ No newline at end of file diff --git a/src/v1/docking/stats.rs b/src/v1/docking/stats.rs deleted file mode 100644 index f24fc90..0000000 --- a/src/v1/docking/stats.rs +++ /dev/null @@ -1,90 +0,0 @@ -use std::{io::BufReader, fs::File}; - -#[allow(unused_imports)] -use std::collections::HashSet; - -use crate::{v1::{battery::{stats::get_battery_info, structs::ChargingStatus}}, USE_FALLBACK_DOCK_DETECTION}; - -use super::structs::{Dock, DockInfo}; - -/* This will get the current dock info. */ -pub fn get_dock_info() -> Result> { - let mut dock = DockInfo::new(); - dock.dock_info = get_dock()?; - - dock.is_docked = dock.dock_info.brand == String::new() && dock.dock_info.model == String::new(); - - /* - This code will manually detect a dock if it wasn't automatically picked up by get_dock(). - The code currently doesnt work. To manually detect a dock we will detect the presence of - a battery, charging of the handheld, and eventually when I find a cross-platform create, - it will also detect the presence of an external monitor (will most likely only work on a - Steam Deck for now) - */ - if USE_FALLBACK_DOCK_DETECTION { - if !dock.is_docked { - dock.fallback_detection = true; - - let battery_info = get_battery_info()?; - - if battery_info.has_battery && battery_info.charging_status == ChargingStatus::Charging { - } - } - } - - Ok(dock) -} - -/* Reads the dock_models.json file and returns a vector of structs with the data */ -#[allow(dead_code)] -pub fn read_dock_models_from_file() -> Result, Box> { - let file = File::open("Resources/dock_models.json")?; - let reader = BufReader::new(file); - let dock_models: Vec = serde_json::from_reader(reader)?; - Ok(dock_models) -} - -#[cfg(target_os = "linux")] -/* This will detect the dock model and brand. */ -pub fn get_dock() -> Result> { - let devices = rusb::devices()?; - let dock_models = read_dock_models_from_file()?; - - for dock_model in dock_models { - let mut found_components = HashSet::new(); - - for device in devices.iter() { - let device_desc = device.device_descriptor()?; - let device_id = (device_desc.vendor_id(), device_desc.product_id()); - - // Check if the device is one of the components of the dock. - if dock_model.usb_ids.contains(&[device_desc.vendor_id(), device_desc.product_id()]) { - found_components.insert(device_id); - println!("(get_dock) Detected: {}", serde_json::to_string_pretty(&device_id)?); - } - } - - if found_components.len() == dock_model.usb_ids.len() { - println!("(get_dock) All components detected for {}", serde_json::to_string_pretty(&dock_model)?); - return Ok(Dock { - model: dock_model.model.clone(), - brand: dock_model.brand.clone(), - usb_ids: dock_model.usb_ids.clone() - }); - } - } - Ok(Dock::new()) -} - -#[cfg(target_os = "macos")] -/* This will detect the dock model and brand. */ -pub fn get_dock() -> Result> { - Ok(Dock::new()) - //Err(Box::new(std::io::Error::new(std::io::ErrorKind::Other, "Incorrect OS"))) -} - -/* This will detect the dock model and brand. */ -#[cfg(target_os = "windows")] -pub fn get_dock() -> Result> { - Ok(Dock::new()) -} \ No newline at end of file diff --git a/src/v1/docking/structs.rs b/src/v1/docking/structs.rs deleted file mode 100644 index 4a165f2..0000000 --- a/src/v1/docking/structs.rs +++ /dev/null @@ -1,39 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize, Serialize, Clone)] -pub struct Dock { - pub brand: String, // ex: JSAUX - pub model: String, // ex: HB0603 - pub usb_ids: Vec<[u16; 2]>, -} - -impl Dock { - pub fn new() -> Dock { - Dock { brand: String::new(), - model: String::new(), - usb_ids: vec![], - } - } - pub fn to_string(self) -> String { - serde_json::to_string(&self).expect("Failed to parse into string") - } -} - -#[derive(Deserialize, Serialize, Clone)] -pub struct DockInfo { - pub dock_info: Dock, - pub is_docked: bool, - pub fallback_detection: bool, -} - -impl DockInfo { - pub fn new() -> DockInfo { - DockInfo { dock_info: Dock::new(), - is_docked: false, - fallback_detection: false - } - } - pub fn to_string(self) -> String { - serde_json::to_string(&self).expect("Failed to parse into string") - } -} \ No newline at end of file diff --git a/src/v1/mod.rs b/src/v1/mod.rs deleted file mode 100644 index 1f4beb0..0000000 --- a/src/v1/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod battery; -pub mod docking; -pub mod os; -pub mod all_info; \ No newline at end of file diff --git a/src/v1/os/mod.rs b/src/v1/os/mod.rs deleted file mode 100644 index 8a30527..0000000 --- a/src/v1/os/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod stats; -pub mod structs; \ No newline at end of file diff --git a/src/v1/os/stats.rs b/src/v1/os/stats.rs deleted file mode 100644 index 200da63..0000000 --- a/src/v1/os/stats.rs +++ /dev/null @@ -1,45 +0,0 @@ -use super::structs::{OSInfo, Platform, Architecture}; - -pub fn get_platform() -> Platform { - if cfg!(target_os = "windows") { - Platform::WINDOWS - } else if cfg!(target_os = "macos") { - Platform::MAC - } else if cfg!(target_os = "linux") { - Platform::LINUX - } else { - Platform::UNKNOWN - } -} - - -pub fn get_os() -> Result> { - let mut temp = OSInfo::new(); - let info = os_info::get(); - - temp.platform = get_platform(); - - temp.name = match info.codename() { - Some(s) => s.to_string(), - _ => String::new(), - }; - - temp.version = info.version().to_string(); - - if temp.name == String::new() { - temp.name = match info.edition() { - Some(s) => s.to_string(), - _ => String::new(), - }; - } - - temp.bits = match info.bitness() - { - os_info::Bitness::X32 => Architecture::X86, - os_info::Bitness::X64 => Architecture::X86_64, - _ => Architecture::UNKNOWN, - }; - - Ok(temp) - -} \ No newline at end of file diff --git a/src/v1/os/structs.rs b/src/v1/os/structs.rs deleted file mode 100644 index 48db188..0000000 --- a/src/v1/os/structs.rs +++ /dev/null @@ -1,38 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize, Serialize, PartialEq, Clone)] -pub enum Platform { - WINDOWS = 0, - LINUX = 1, - MAC = 2, - UNKNOWN = 255 -} - -#[derive(Deserialize, Serialize, Clone)] -pub enum Architecture { - X86 = 0, - X86_64 = 1, - UNKNOWN = 255, -} - -#[derive(Deserialize, Serialize, Clone)] -pub struct OSInfo { - pub platform: Platform, // Windows, Mac, Linux - pub name: String, // "Windows 11 2306", "Ubuntu 22.04 LTS" - pub version: String, // 2306, 22.04 - pub bits: Architecture // 32, 64 -} - -impl OSInfo { - pub fn new() -> OSInfo { - OSInfo { - platform: Platform::UNKNOWN, - name: String::new(), - version: String::new(), - bits: Architecture::UNKNOWN - } - } - pub fn to_string(self) -> String { - serde_json::to_string(&self).expect("Failed to parse into string") - } -} \ No newline at end of file diff --git a/src/version/info.rs b/src/version/info.rs deleted file mode 100644 index 52bcba7..0000000 --- a/src/version/info.rs +++ /dev/null @@ -1,41 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize, Serialize, Clone)] -pub struct Version { - pub build_timestamp: String, - pub git_branch: String, - pub git_describe: String, - pub git_commit_timestamp: String, - pub debug: bool, - pub version: String, - pub version_major: i32, - pub version_minor: i32, - pub version_patch: i32, - pub version_pre: String, - pub supported_api_versions: Vec -} - -impl Version { - pub fn get() -> Version { - Version { - build_timestamp: env!("VERGEN_BUILD_TIMESTAMP").to_string(), - git_branch: env!("VERGEN_GIT_BRANCH").to_string(), - git_describe: env!("VERGEN_GIT_DESCRIBE").to_string(), - git_commit_timestamp: env!("VERGEN_GIT_COMMIT_TIMESTAMP").to_string(), - debug: env!("VERGEN_CARGO_DEBUG").parse().unwrap(), - version: env!("CARGO_PKG_VERSION").to_string(), - version_major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(), - version_minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(), - version_patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(), - version_pre: "Alpha".to_string(), - supported_api_versions: vec!["v1".to_string()] - } - } - pub fn to_string(self) -> String { - serde_json::to_string(&self).expect("Failed to parse into string") - } - pub fn supported_api_versions_to_string(self) -> String { - self.supported_api_versions.join(", ") - } - -} \ No newline at end of file diff --git a/src/version/mod.rs b/src/version/mod.rs deleted file mode 100644 index 55cc091..0000000 --- a/src/version/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod info; \ No newline at end of file