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