diff --git a/.github/shared-actions/code-changes.yml b/.github/shared-actions/code-changes.yml
new file mode 100644
index 0000000..3087820
--- /dev/null
+++ b/.github/shared-actions/code-changes.yml
@@ -0,0 +1,80 @@
+name: Rustdesk Code Changes
+description: changes to the source code to fix connection delay and allow custom.txt. Also changes icon and app name
+inputs:
+ extras:
+ required: true
+ appname:
+ required: true
+ iconbase64:
+ required: true
+ filename:
+ required: true
+runs:
+ using: "composite"
+ steps:
+ - name: icon stuff
+ continue-on-error: true
+ shell: bash
+ run: |
+ mv ./res/icon.ico ./res/icon.ico.bak
+ mv ./res/icon.png ./res/icon.png.bak
+ mv ./res/tray-icon.ico ./res/tray-icon.ico.bak
+ echo "${{ inputs.iconbase64 }}" | base64 -d > ./res/icon.png
+
+ - name: magick stuff
+ continue-on-error: true
+ run: |
+ mv ./res/32x32.png ./res/32x32.png.bak
+ mv ./res/64x64.png ./res/64x64.png.bak
+ mv ./res/128x128.png ./res/128x128.png.bak
+ mv ./res/128x128@2x.png ./res/128x128@2x.png.bak
+ magick ./res/icon.png -define icon:auto-resize=256,64,48,32,16 ./res/icon.ico
+ cp ./res/icon.ico ./res/tray-icon.ico
+ magick ./res/icon.png -resize 32x32 ./res/32x32.png
+ magick ./res/icon.png -resize 64x64 ./res/64x64.png
+ magick ./res/icon.png -resize 128x128 ./res/128x128.png
+ magick ./res/128x128.png -resize 200% ./res/128x128@2x.png
+
+
+ - name: ui.rs icon
+ continue-on-error: true
+ shell: bash
+ run: |
+ cp ./src/ui.rs ./src/ui.rs.bak
+ sed -i -e 's|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|${{ inputs.iconbase64 }}|' ./src/ui.rs
+
+ - name: cargo.toml, runner.rc name, en.rs
+ continue-on-error: true
+ shell: bash
+ run: |
+ cp ./Cargo.toml ./Cargo.toml.bak
+ sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./Cargo.toml
+ cp ./libs/portable/Cargo.toml ./libs/portable/Cargo.toml.bak
+ sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./libs/portable/Cargo.toml
+ cp ./flutter/windows/runner/Runner.rc ./flutter/windows/runner/Runner.rc.bak
+ sed -i -e 's|"RustDesk Remote Desktop"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ inputs.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"Copyright © 2024 Purslane Ltd. All rights reserved."|"Copyright © 2024"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"rustdesk.exe"|"${{ inputs.filename }}"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"RustDesk"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc
+ cp ./src/lang/en.rs ./src/lang/en.rs.bak
+ sed -i -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/en.rs
+ sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py
+ sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ fromJson(inputs.extras).urlLink }}'));|" ./flutter/lib/common.dart
+ sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
+ sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart
+ sed -i -e '/const KEY:/,/};/d' ./src/common.rs
+ sed -i -e '/let Ok(data) = sign::verify(&data, &pk)/,/};/d' ./src/common.rs
+
+ - name: fix connection delay
+ continue-on-error: true
+ if: ${{ fromJson(inputs.extras).delayFix == 'true' }}
+ shell: bash
+ run: |
+ sed -i -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs
\ No newline at end of file
diff --git a/.github/workflows/generator-android.yml b/.github/workflows/generator-android.yml
new file mode 100644
index 0000000..b9d7dcd
--- /dev/null
+++ b/.github/workflows/generator-android.yml
@@ -0,0 +1,505 @@
+name: Custom Android Client Generator
+run-name: Custom Android Client Generator
+on:
+ workflow_dispatch:
+ inputs:
+ server:
+ description: 'Rendezvous Server'
+ required: true
+ default: ''
+ type: string
+ key:
+ description: 'Public Key'
+ required: true
+ default: ''
+ type: string
+ apiServer:
+ description: 'API Server'
+ required: true
+ default: ''
+ type: string
+ custom:
+ description: "Custom JSON"
+ required: true
+ default: ''
+ type: string
+ uuid:
+ description: "uuid of request"
+ required: true
+ default: ''
+ type: string
+ iconbase64:
+ description: "icon in base64"
+ required: false
+ default: ''
+ type: string
+ logobase64:
+ description: "logo in base64"
+ required: false
+ default: ''
+ type: string
+ appname:
+ description: "app name"
+ required: true
+ default: 'rustdesk'
+ type: string
+ filename:
+ description: "Filename"
+ required: true
+ default: 'rustdesk'
+ type: string
+ extras:
+ description: "extra inputs in json"
+ required: true
+ default: '{}'
+ type: string
+
+
+env:
+ SCITER_RUST_VERSION: "1.75" # https://github.com/rustdesk/rustdesk/discussions/7503, also 1.78 has ABI change which causes our sciter version not working, https://blog.rust-lang.org/2024/03/30/i128-layout-update.html
+ RUST_VERSION: "1.75" # sciter failed on m1 with 1.78 because of https://blog.rust-lang.org/2024/03/30/i128-layout-update.html
+ CARGO_NDK_VERSION: "3.1.2"
+ SCITER_ARMV7_CMAKE_VERSION: "3.29.7"
+ SCITER_NASM_DEBVERSION: "2.14-1"
+ LLVM_VERSION: "15.0.6"
+ FLUTTER_VERSION: "3.19.6"
+ ANDROID_FLUTTER_VERSION: "3.13.9" # >= 3.16 is very slow on my android phone, but work well on most of others. We may switch to new flutter after changing to texture rendering (I believe it can solve my problem).
+ FLUTTER_RUST_BRIDGE_VERSION: "1.80.1"
+ # for arm64 linux because official Dart SDK does not work
+ FLUTTER_ELINUX_VERSION: "3.16.9"
+ TAG_NAME: "${{ inputs.upload-tag }}"
+ VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
+ # vcpkg version: 2024.07.12
+ VCPKG_COMMIT_ID: "1de2026f28ead93ff1773e6e680387643e914ea1"
+ VERSION: "1.3.1"
+ NDK_VERSION: "r27"
+ #signing keys env variable checks
+ ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}"
+ MACOS_P12_BASE64: "${{ secrets.MACOS_P12_BASE64 }}"
+ # To make a custom build with your own servers set the below secret values
+ RS_PUB_KEY: "${{ inputs.key }}"
+ RENDEZVOUS_SERVER: "${{ inputs.server }}"
+ CUSTOM: "${{ inputs.custom }}"
+ UUIDFOLDER: "${{ inputs.uuid }}"
+ API_SERVER: "${{ inputs.apiServer }}"
+ UPLOAD_ARTIFACT: 'true'
+ SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}"
+ ICONBASE64: "$${{ inputs.iconbase64 }}"
+
+
+jobs:
+ generate-bridge-linux:
+ uses: ./.github/workflows/bridge.yml
+
+ build-rustdesk-android:
+ needs: [generate-bridge-linux]
+ name: build rustdesk android apk ${{ matrix.job.target }}
+ runs-on: [self-hosted, linux]
+ strategy:
+ fail-fast: false
+ matrix:
+ job:
+ - {
+ arch: aarch64,
+ target: aarch64-linux-android,
+ os: ubuntu-20.04,
+ reltype: release,
+ suffix: "",
+ }
+ # - {
+ # arch: armv7,
+ # target: armv7-linux-androideabi,
+ # os: ubuntu-20.04,
+ # reltype: release,
+ # suffix: "",
+ # }
+ # - {
+ # arch: x86_64,
+ # target: x86_64-linux-android,
+ # os: ubuntu-20.04,
+ # reltype: release,
+ # suffix: "",
+ # }
+ steps:
+ # - name: Free Disk Space (Ubuntu)
+ # uses: jlumbroso/free-disk-space@main
+ # with:
+ # tool-cache: false
+ # android: false
+ # dotnet: true
+ # haskell: true
+ # large-packages: false
+ # docker-images: true
+ # swap-storage: false
+
+ - name: Export GitHub Actions cache environment variables
+ uses: actions/github-script@v6
+ with:
+ script: |
+ core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
+ core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
+
+ # - name: Install dependencies
+ # run: |
+ # echo ${{ secrets.SUDOPW }} | sudo -S apt-get update
+ # echo ${{ secrets.SUDOPW }} | sudo -S apt-get install -y \
+ # clang \
+ # cmake \
+ # curl \
+ # gcc-multilib \
+ # git \
+ # g++ \
+ # g++-multilib \
+ # imagemagick \
+ # libappindicator3-dev \
+ # libasound2-dev \
+ # libc6-dev \
+ # libclang-10-dev \
+ # libgstreamer1.0-dev \
+ # libgstreamer-plugins-base1.0-dev \
+ # libgtk-3-dev \
+ # libpam0g-dev \
+ # libpulse-dev \
+ # libva-dev \
+ # libvdpau-dev \
+ # libxcb-randr0-dev \
+ # libxcb-shape0-dev \
+ # libxcb-xfixes0-dev \
+ # libxdo-dev \
+ # libxfixes-dev \
+ # llvm-10-dev \
+ # nasm \
+ # ninja-build \
+ # openjdk-11-jdk-headless \
+ # pkg-config \
+ # tree \
+ # wget
+
+ - name: Checkout source code
+ uses: actions/checkout@v4
+ with:
+ repository: rustdesk/rustdesk
+
+ # - name: Install flutter
+ # uses: subosito/flutter-action@v2
+ # with:
+ # channel: "stable"
+ # flutter-version: ${{ env.ANDROID_FLUTTER_VERSION }}
+
+ - uses: nttld/setup-ndk@v1
+ id: setup-ndk
+ with:
+ ndk-version: ${{ env.NDK_VERSION }}
+ add-to-path: true
+
+ # - name: Setup vcpkg with Github Actions binary cache
+ # uses: lukka/run-vcpkg@v11
+ # with:
+ # vcpkgDirectory: /opt/artifacts/vcpkg
+ # vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
+ # doNotCache: false
+
+ # - name: Install vcpkg dependencies
+ # run: |
+ # #case ${{ matrix.job.target }} in
+ # # aarch64-linux-android)
+ # ANDROID_TARGET=arm64-v8a
+ # # ;;
+ # # armv7-linux-androideabi)
+ # # ANDROID_TARGET=armeabi-v7a
+ # # ;;
+ # # x86_64-linux-android)
+ # # ANDROID_TARGET=x86_64
+ # # ;;
+ # # i686-linux-android)
+ # # ANDROID_TARGET=x86
+ # # ;;
+ # # esac
+ # if ! ./flutter/build_android_deps.sh "${ANDROID_TARGET}"; then
+ # find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
+ # echo "$_1:"
+ # echo "======"
+ # cat "$_1"
+ # echo "======"
+ # echo ""
+ # done
+ # exit 1
+ # fi
+ # shell: bash
+
+ - name: Restore bridge files
+ uses: actions/download-artifact@master
+ with:
+ name: bridge-artifact
+ path: ./
+
+ # - name: Install Rust toolchain
+ # uses: dtolnay/rust-toolchain@v1
+ # with:
+ # toolchain: ${{ env.RUST_VERSION }}
+ # components: "rustfmt"
+
+ # - uses: Swatinem/rust-cache@v2
+ # with:
+ # prefix-key: rustdesk-lib-cache-android # TODO: drop '-android' part after caches are invalidated
+ # key: ${{ matrix.job.target }}
+
+ - name: fix android for flutter 3.13
+ if: $${{ env.ANDROID_FLUTTER_VERSION == '3.13.9' }}
+ run: |
+ cd flutter
+ sed -i 's/uni_links_desktop/#uni_links_desktop/g' pubspec.yaml
+ sed -i 's/extended_text: .*/extended_text: 11.1.0/' pubspec.yaml
+ flutter pub get
+ cd lib
+ find . | grep dart | xargs sed -i 's/textScaler: TextScaler.linear(\(.*\)),/textScaleFactor: \1,/g'
+
+ ##########################################################
+ - name: icon stuff
+ continue-on-error: true
+ shell: bash
+ run: |
+ mv ./res/icon.ico ./res/icon.ico.bak
+ mv ./res/icon.png ./res/icon.png.bak
+ mv ./res/tray-icon.ico ./res/tray-icon.ico.bak
+ echo "${{ inputs.iconbase64 }}" | base64 -d > ./res/icon.png
+
+ - name: magick stuff
+ continue-on-error: true
+ run: |
+ mv ./res/32x32.png ./res/32x32.png.bak
+ mv ./res/64x64.png ./res/64x64.png.bak
+ mv ./res/128x128.png ./res/128x128.png.bak
+ mv ./res/128x128@2x.png ./res/128x128@2x.png.bak
+ convert ./res/icon.png -define icon:auto-resize=256,64,48,32,16 ./res/icon.ico
+ cp ./res/icon.ico ./res/tray-icon.ico
+ convert ./res/icon.png -resize 32x32 ./res/32x32.png
+ convert ./res/icon.png -resize 64x64 ./res/64x64.png
+ convert ./res/icon.png -resize 128x128 ./res/128x128.png
+ convert ./res/128x128.png -resize 200% ./res/128x128@2x.png
+
+
+ - name: ui.rs icon
+ continue-on-error: true
+ shell: bash
+ run: |
+ #cp ./src/ui.rs ./src/ui.rs.bak
+ sed -i -e 's|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|${{ inputs.iconbase64 }}|' ./src/ui.rs
+
+ - name: cargo.toml, runner.rc name, en.rs
+ continue-on-error: true
+ shell: bash
+ run: |
+ cp ./Cargo.toml ./Cargo.toml.bak
+ sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./Cargo.toml
+ cp ./libs/portable/Cargo.toml ./libs/portable/Cargo.toml.bak
+ sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./libs/portable/Cargo.toml
+ cp ./flutter/windows/runner/Runner.rc ./flutter/windows/runner/Runner.rc.bak
+ sed -i -e 's|"RustDesk Remote Desktop"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ inputs.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"Copyright © 2024 Purslane Ltd. All rights reserved."|"Copyright © 2024"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"rustdesk.exe"|"${{ inputs.filename }}"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"RustDesk"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc
+ cp ./src/lang/en.rs ./src/lang/en.rs.bak
+ sed -i -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/en.rs
+ sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py
+ sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ fromJson(inputs.extras).urlLink }}'));|" ./flutter/lib/common.dart
+ sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
+ sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart
+ sed -i -e '/const KEY:/,/};/d' ./src/common.rs
+ sed -i -e '/let Ok(data) = sign::verify(&data, &pk)/,/};/d' ./src/common.rs
+ #cp ./flutter/android/app/src/main/res/values/strings.xml ./flutter/android/app/src/main/res/values/strings.xml.bak
+ sed -i -e 's|RustDesk|${{ inputs.appname }}|' ./flutter/android/app/src/main/res/values/strings.xml
+ sed -i -e "s|title: 'RustDesk'|title: '${{ inputs.appname }}'|" ./flutter/lib/main.dart
+ sed -i -e "s|return 'RustDesk';|return '${{ inputs.appname }}';|" ./flutter/lib/web/bridge.dart
+
+ - name: fix connection delay
+ continue-on-error: true
+ if: ${{ fromJson(inputs.extras).delayFix == 'true' }}
+ shell: bash
+ run: |
+ sed -i -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs
+
+ - name: replace flutter icons
+ run: |
+ cd ./flutter
+ flutter pub run flutter_launcher_icons
+ cd ..
+ ##########################################################
+
+ - name: Build rustdesk lib
+ env:
+ ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
+ ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
+ run: |
+ rustup target add ${{ matrix.job.target }}
+ cargo install cargo-ndk --version ${{ env.CARGO_NDK_VERSION }}
+ # case ${{ matrix.job.target }} in
+ # aarch64-linux-android)
+ ./flutter/ndk_arm64.sh
+ mkdir -p ./flutter/android/app/src/main/jniLibs/arm64-v8a
+ cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so
+ # ;;
+ # armv7-linux-androideabi)
+ # ./flutter/ndk_arm.sh
+ # mkdir -p ./flutter/android/app/src/main/jniLibs/armeabi-v7a
+ # cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/librustdesk.so
+ # ;;
+ # x86_64-linux-android)
+ # ./flutter/ndk_x64.sh
+ # mkdir -p ./flutter/android/app/src/main/jniLibs/x86_64
+ # cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86_64/librustdesk.so
+ # ;;
+ # i686-linux-android)
+ # ./flutter/ndk_x86.sh
+ # mkdir -p ./flutter/android/app/src/main/jniLibs/x86
+ # cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86/librustdesk.so
+ # ;;
+ # esac
+
+ - name: Upload Rustdesk library to Artifacts
+ uses: actions/upload-artifact@master
+ with:
+ name: librustdesk.so.${{ matrix.job.target }}
+ path: ./target/${{ matrix.job.target }}/release/liblibrustdesk.so
+
+ - name: Build rustdesk
+ shell: bash
+ env:
+ JAVA_HOME: /usr/lib/jvm/java-11-openjdk-amd64
+ run: |
+ export PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:$PATH
+ # temporary use debug sign config
+ sed -i "s/signingConfigs.release/signingConfigs.debug/g" ./flutter/android/app/build.gradle
+ #case ${{ matrix.job.target }} in
+ # aarch64-linux-android)
+ mkdir -p ./flutter/android/app/src/main/jniLibs/arm64-v8a
+ cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/
+ cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so
+ echo -n "${{ env.CUSTOM }}" | cat > ./flutter/assets/custom.txt
+ convert ./res/icon.png ./flutter/assets/icon.svg
+ # build flutter
+ pushd flutter
+ flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-arm64 --split-per-abi
+ mv build/app/outputs/flutter-apk/app-arm64-v8a-${{ matrix.job.reltype }}.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk
+ # ;;
+ # armv7-linux-androideabi)
+ # mkdir -p ./flutter/android/app/src/main/jniLibs/armeabi-v7a
+ # cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/
+ # cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/librustdesk.so
+ # echo -n "${{ env.CUSTOM }}" | cat > ./flutter/android/app/src/main/custom.txt
+ # # build flutter
+ # pushd flutter
+ # flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-arm --split-per-abi
+ # mv build/app/outputs/flutter-apk/app-armeabi-v7a-${{ matrix.job.reltype }}.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk
+ # ;;
+ # x86_64-linux-android)
+ # mkdir -p ./flutter/android/app/src/main/jniLibs/x86_64
+ # cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/x86_64/
+ # cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86_64/librustdesk.so
+ # echo -n "${{ env.CUSTOM }}" | cat > ./flutter/android/app/src/main/custom.txt
+ # # build flutter
+ # pushd flutter
+ # flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-x64 --split-per-abi
+ # mv build/app/outputs/flutter-apk/app-x86_64-${{ matrix.job.reltype }}.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk
+ # ;;
+ # i686-linux-android)
+ # mkdir -p ./flutter/android/app/src/main/jniLibs/x86
+ # cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/x86/
+ # cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86/librustdesk.so
+ # echo -n "${{ env.CUSTOM }}" | cat > ./flutter/android/app/src/main/custom.txt
+ # # build flutter
+ # pushd flutter
+ # flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-x86 --split-per-abi
+ # mv build/app/outputs/flutter-apk/app-x86-${{ matrix.job.reltype }}.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk
+ # ;;
+ # esac
+ popd
+ mkdir -p signed-apk; pushd signed-apk
+ mv ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk ./${{ inputs.filename }}.apk
+ popd
+
+ - uses: r0adkll/sign-android-release@v1
+ name: Sign app APK
+ continue-on-error: true
+ if: env.ANDROID_SIGNING_KEY != null
+ id: sign-rustdesk
+ with:
+ releaseDirectory: ./signed-apk
+ signingKeyBase64: ${{ secrets.ANDROID_SIGNING_KEY }}
+ alias: ${{ secrets.ANDROID_ALIAS }}
+ keyStorePassword: ${{ secrets.ANDROID_KEY_STORE_PASSWORD }}
+ keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }}
+ env:
+ # override default build-tools version (29.0.3) -- optional
+ BUILD_TOOLS_VERSION: "30.0.2"
+
+ # - name: Upload Artifacts
+ # if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true'
+ # uses: actions/upload-artifact@master
+ # with:
+ # name: ${{ inputs.filename }}-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
+ # path: ${{steps.sign-rustdesk.outputs.signedReleaseFile}}
+
+ # - name: Publish signed apk package
+ # if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true'
+ # uses: softprops/action-gh-release@v1
+ # with:
+ # prerelease: true
+ # tag_name: ${{ env.TAG_NAME }}
+ # files: |
+ # ${{steps.sign-rustdesk.outputs.signedReleaseFile}}
+
+ # - name: Publish unsigned apk package
+ # if: env.ANDROID_SIGNING_KEY == null && env.UPLOAD_ARTIFACT == 'true'
+ # uses: softprops/action-gh-release@v1
+ # with:
+ # prerelease: true
+ # tag_name: ${{ env.TAG_NAME }}
+ # files: |
+ # signed-apk/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
+
+ - name: Upload to FTP
+ uses: SamKirkland/FTP-Deploy-Action@v4.3.5
+ with:
+ server: ${{ secrets.GEN_FTP_SERVER }}
+ username: ${{ secrets.GEN_FTP_USER }}
+ password: ${{ secrets.GEN_FTP_PASSWORD }}
+ local-dir: ./signed-apk/
+ server-dir: /root/rdgen/exe/${{ env.UUIDFOLDER }}/
+ exclude: |
+ *.idsig
+ *.jks
+ *aligned.apk
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}'
+
+ - name: failed
+ if: failure()
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation failed, try again"}'
+
+ - name: failed
+ if: cancelled()
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}'
\ No newline at end of file
diff --git a/.github/workflows/generator-linux.yml b/.github/workflows/generator-linux.yml
new file mode 100644
index 0000000..f902584
--- /dev/null
+++ b/.github/workflows/generator-linux.yml
@@ -0,0 +1,420 @@
+name: Custom Linux Client Generator
+run-name: Custom Linux Client Generator
+on:
+ workflow_dispatch:
+ inputs:
+ server:
+ description: 'Rendezvous Server'
+ required: true
+ default: ''
+ type: string
+ key:
+ description: 'Public Key'
+ required: true
+ default: ''
+ type: string
+ apiServer:
+ description: 'API Server'
+ required: true
+ default: ''
+ type: string
+ custom:
+ description: "Custom JSON"
+ required: true
+ default: ''
+ type: string
+ uuid:
+ description: "uuid of request"
+ required: true
+ default: ''
+ type: string
+ iconbase64:
+ description: "icon in base64"
+ required: false
+ default: ''
+ type: string
+ logobase64:
+ description: "logo in base64"
+ required: false
+ default: ''
+ type: string
+ appname:
+ description: "app name"
+ required: true
+ default: 'rustdesk'
+ type: string
+ filename:
+ description: "Filename"
+ required: true
+ default: 'rustdesk'
+ type: string
+ extras:
+ description: "extra inputs in json"
+ required: true
+ default: '{}'
+ type: string
+
+env:
+ SCITER_RUST_VERSION: "1.75" # https://github.com/rustdesk/rustdesk/discussions/7503, also 1.78 has ABI change which causes our sciter version not working, https://blog.rust-lang.org/2024/03/30/i128-layout-update.html
+ RUST_VERSION: "1.75" # sciter failed on m1 with 1.78 because of https://blog.rust-lang.org/2024/03/30/i128-layout-update.html
+ CARGO_NDK_VERSION: "3.1.2"
+ SCITER_ARMV7_CMAKE_VERSION: "3.29.7"
+ SCITER_NASM_DEBVERSION: "2.14-1"
+ LLVM_VERSION: "15.0.6"
+ FLUTTER_VERSION: "3.19.6"
+ ANDROID_FLUTTER_VERSION: "3.13.9" # >= 3.16 is very slow on my android phone, but work well on most of others. We may switch to new flutter after changing to texture rendering (I believe it can solve my problem).
+ FLUTTER_RUST_BRIDGE_VERSION: "1.80.1"
+ # for arm64 linux because official Dart SDK does not work
+ FLUTTER_ELINUX_VERSION: "3.16.9"
+ TAG_NAME: "${{ inputs.upload-tag }}"
+ VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
+ # vcpkg version: 2024.07.12
+ VCPKG_COMMIT_ID: "1de2026f28ead93ff1773e6e680387643e914ea1"
+ VERSION: "1.3.1"
+ NDK_VERSION: "r27"
+ #signing keys env variable checks
+ ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}"
+ MACOS_P12_BASE64: "${{ secrets.MACOS_P12_BASE64 }}"
+ # To make a custom build with your own servers set the below secret values
+ RS_PUB_KEY: "${{ inputs.key }}"
+ RENDEZVOUS_SERVER: "${{ inputs.server }}"
+ CUSTOM: "${{ inputs.custom }}"
+ UUIDFOLDER: "${{ inputs.uuid }}"
+ API_SERVER: "${{ inputs.apiServer }}"
+ UPLOAD_ARTIFACT: 'true'
+ SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}"
+ ICONBASE64: "$${{ inputs.iconbase64 }}"
+
+
+jobs:
+ generate-bridge-linux:
+ uses: ./.github/workflows/bridge.yml
+
+ build-rustdesk-linux:
+ needs: [generate-bridge-linux]
+ name: build rustdesk linux ${{ matrix.job.target }}
+ runs-on: ${{ matrix.job.on }}
+ strategy:
+ fail-fast: false
+ matrix:
+ # use a high level qemu-user-static
+ job:
+ - {
+ arch: x86_64,
+ target: x86_64-unknown-linux-gnu,
+ distro: ubuntu18.04,
+ on: ubuntu-20.04,
+ deb_arch: amd64,
+ vcpkg-triplet: x64-linux,
+ }
+ - {
+ arch: aarch64,
+ target: aarch64-unknown-linux-gnu,
+ distro: ubuntu18.04,
+ on: [self-hosted, Linux, ARM64],
+ deb_arch: arm64,
+ vcpkg-triplet: arm64-linux,
+ }
+ steps:
+ - name: Export GitHub Actions cache environment variables
+ uses: actions/github-script@v6
+ with:
+ script: |
+ core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
+ core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
+
+ - name: Maximize build space
+ if: ${{ matrix.job.arch == 'x86_64' }}
+ run: |
+ # sudo rm -rf /opt/ghc
+ # sudo rm -rf /usr/local/lib/android
+ # sudo rm -rf /usr/share/dotnet
+ sudo apt-get update -y
+ sudo apt-get install -y nasm qemu-user-static
+
+ - name: Checkout source code
+ uses: actions/checkout@v4
+ with:
+ repository: rustdesk/rustdesk
+
+ # - name: Set Swap Space
+ # if: ${{ matrix.job.arch == 'x86_64' }}
+ # uses: pierotofy/set-swap-space@master
+ # with:
+ # swap-size-gb: 12
+
+ # - name: Free Space
+ # run: |
+ # df -h
+ # free -m
+
+ - name: Install Rust toolchain
+ uses: dtolnay/rust-toolchain@v1
+ if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
+ with:
+ toolchain: ${{ env.RUST_VERSION }}
+ targets: ${{ matrix.job.target }}
+ components: "rustfmt"
+
+ - name: Save Rust toolchain version
+ run: |
+ RUST_TOOLCHAIN_VERSION=$(cargo --version | awk '{print $2}')
+ echo "RUST_TOOLCHAIN_VERSION=$RUST_TOOLCHAIN_VERSION" >> $GITHUB_ENV
+
+ - name: Disable rust bridge build
+ run: |
+ # only build cdylib
+ sed -i "s/\[\"cdylib\", \"staticlib\", \"rlib\"\]/\[\"cdylib\"\]/g" Cargo.toml
+
+ - name: Restore bridge files
+ if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
+ uses: actions/download-artifact@master
+ with:
+ name: bridge-artifact
+ path: ./
+
+ - name: Setup vcpkg with Github Actions binary cache
+ if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
+ uses: lukka/run-vcpkg@v11
+ with:
+ vcpkgDirectory: /opt/artifacts/vcpkg
+ vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
+ doNotCache: false
+
+ - name: Install vcpkg dependencies
+ if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
+ run: |
+ if ! $VCPKG_ROOT/vcpkg \
+ install \
+ --triplet ${{ matrix.job.vcpkg-triplet }} \
+ --x-install-root="$VCPKG_ROOT/installed"; then
+ find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
+ echo "$_1:"
+ echo "======"
+ cat "$_1"
+ echo "======"
+ echo ""
+ done
+ exit 1
+ fi
+ shell: bash
+
+ - name: Restore bridge files
+ if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
+ uses: actions/download-artifact@master
+ with:
+ name: bridge-artifact
+ path: ./
+
+ - uses: rustdesk-org/run-on-arch-action@amd64-support
+ name: Build rustdesk
+ id: vcpkg
+ if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
+ with:
+ arch: ${{ matrix.job.arch }}
+ distro: ${{ matrix.job.distro }}
+ githubToken: ${{ github.token }}
+ setup: |
+ ls -l "${PWD}"
+ ls -l /opt/artifacts/vcpkg/installed
+ dockerRunArgs: |
+ --volume "${PWD}:/workspace"
+ --volume "/opt/artifacts:/opt/artifacts"
+ shell: /bin/bash
+ install: |
+ apt-get update -y
+ echo -e "installing deps"
+ apt-get install -y \
+ build-essential \
+ clang \
+ cmake \
+ curl \
+ gcc \
+ git \
+ g++ \
+ libappindicator3-dev \
+ libasound2-dev \
+ libclang-10-dev \
+ libgstreamer1.0-dev \
+ libgstreamer-plugins-base1.0-dev \
+ libgtk-3-dev \
+ libpam0g-dev \
+ libpulse-dev \
+ libva-dev \
+ libvdpau-dev \
+ libxcb-randr0-dev \
+ libxcb-shape0-dev \
+ libxcb-xfixes0-dev \
+ libxdo-dev \
+ libxfixes-dev \
+ llvm-10-dev \
+ nasm \
+ ninja-build \
+ pkg-config \
+ tree \
+ python3 \
+ rpm \
+ unzip \
+ wget \
+ xz-utils
+ # we have libopus compiled by us.
+ apt-get remove -y libopus-dev || true
+ # output devs
+ ls -l ./
+ tree -L 3 /opt/artifacts/vcpkg/installed
+ run: |
+ # disable git safe.directory
+ git config --global --add safe.directory "*"
+ # rust
+ pushd /opt
+ # do not use rustup, because memory overflow in qemu
+ wget -O rust.tar.gz https://static.rust-lang.org/dist/rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }}.tar.gz
+ tar -zxvf rust.tar.gz > /dev/null && rm rust.tar.gz
+ cd rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }} && ./install.sh
+ rm -rf rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }}
+ # edit config
+ mkdir -p ~/.cargo/
+ echo """
+ [source.crates-io]
+ registry = 'https://github.com/rust-lang/crates.io-index'
+ """ > ~/.cargo/config
+ cat ~/.cargo/config
+ # start build
+ pushd /workspace
+ export VCPKG_ROOT=/opt/artifacts/vcpkg
+ if [[ "${{ matrix.job.arch }}" == "aarch64" ]]; then
+ export JOBS="--jobs 3"
+ else
+ export JOBS=""
+ fi
+ echo $JOBS
+ cargo build --lib $JOBS --features hwcodec,flutter --release
+ rm -rf target/release/deps target/release/build
+ rm -rf ~/.cargo
+
+ # Setup Flutter
+ # disable git safe.directory
+ git config --global --add safe.directory "*"
+ pushd /workspace
+ case ${{ matrix.job.arch }} in
+ aarch64)
+ export PATH=/opt/flutter-elinux/bin:$PATH
+ sed -i "s/flutter build linux --release/flutter-elinux build linux --verbose/g" ./build.py
+ sed -i "s/x64\/release/arm64\/release/g" ./build.py
+ ;;
+ x86_64)
+ export PATH=/opt/flutter/bin:$PATH
+ ;;
+ esac
+ popd
+ pushd /opt
+ wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${{ env.FLUTTER_VERSION }}-stable.tar.xz
+ tar xf flutter_linux_${{ env.FLUTTER_VERSION }}-stable.tar.xz
+ case ${{ matrix.job.arch }} in
+ aarch64)
+ # clone repo and reset to flutter ${{ env.FLUTTER_VERSION }}
+ git clone https://github.com/sony/flutter-elinux.git || true
+ pushd flutter-elinux
+ git fetch
+ git reset --hard ${{ env.FLUTTER_VERSION }}
+ bin/flutter-elinux doctor -v
+ bin/flutter-elinux precache --linux
+ popd
+ cp -R flutter/bin/cache/artifacts/engine/linux-x64/shader_lib flutter-elinux/flutter/bin/cache/artifacts/engine/linux-arm64
+ rm -rf flutter
+ ;;
+ x86_64)
+ flutter doctor -v
+ ;;
+ esac
+
+ # build flutter
+ pushd /workspace
+ mkdir output
+ chmod 777 output -R
+ export CARGO_INCREMENTAL=0
+ export DEB_ARCH=${{ matrix.job.deb_arch }}
+ python3 ./build.py --flutter --skip-cargo
+ for name in rustdesk*??.deb; do
+ mv "$name" /workspace/output/"${{ inputs.filename }}-${{ matrix.job.arch }}.deb"
+ done
+
+ # rpm package
+ echo -e "start packaging fedora package"
+ pushd /workspace
+ case ${{ matrix.job.arch }} in
+ aarch64)
+ sed -i "s/linux\/x64/linux\/arm64/g" ./res/rpm-flutter.spec
+ ;;
+ esac
+ HBB=`pwd` rpmbuild ./res/rpm-flutter.spec -bb
+ pushd ~/rpmbuild/RPMS/${{ matrix.job.arch }}
+ for name in rustdesk*??.rpm; do
+ mv "$name" /workspace/output/"${{ inputs.filename }}.rpm"
+ done
+
+ # rpm suse package
+ echo -e "start packaging suse package"
+ pushd /workspace
+ case ${{ matrix.job.arch }} in
+ aarch64)
+ sed -i "s/linux\/x64/linux\/arm64/g" ./res/rpm-flutter-suse.spec
+ ;;
+ esac
+ HBB=`pwd` rpmbuild ./res/rpm-flutter-suse.spec -bb
+ pushd ~/rpmbuild/RPMS/${{ matrix.job.arch }}
+ for name in rustdesk*??.rpm; do
+ mv "$name" /workspace/output/"${{ inputs.filename }}-suse.rpm"
+ done
+
+ # - name: Publish debian/rpm package
+ # if: env.UPLOAD_ARTIFACT == 'true'
+ # uses: softprops/action-gh-release@v1
+ # with:
+ # prerelease: true
+ # tag_name: ${{ env.TAG_NAME }}
+ # files: |
+ # rustdesk-*.deb
+ # rustdesk-*.rpm
+
+ - name: Upload to FTP
+ uses: SamKirkland/FTP-Deploy-Action@v4.3.5
+ with:
+ server: ${{ secrets.FTP_SERVER }}
+ username: ${{ secrets.FTP_USERNAME }}
+ password: ${{ secrets.FTP_PASSWORD }}
+ local-dir: output/
+ server-dir: /root/rdgen/exe/${{ env.UUIDFOLDER }}/
+
+ - name: Upload deb
+ uses: actions/upload-artifact@master
+ if: env.UPLOAD_ARTIFACT == 'true'
+ with:
+ name: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.deb
+ path: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.deb
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}'
+
+ - name: failed
+ if: failure()
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation failed, try again"}'
+
+ - name: failed
+ if: cancelled()
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}'
\ No newline at end of file
diff --git a/.github/workflows/generator-windows.yml b/.github/workflows/generator-windows.yml
new file mode 100644
index 0000000..85d7853
--- /dev/null
+++ b/.github/workflows/generator-windows.yml
@@ -0,0 +1,492 @@
+name: Custom Windows Client Generator
+run-name: Custom Windows Client Generator
+on:
+ workflow_dispatch:
+ inputs:
+ server:
+ description: 'Rendezvous Server'
+ required: true
+ default: ''
+ type: string
+ key:
+ description: 'Public Key'
+ required: true
+ default: ''
+ type: string
+ apiServer:
+ description: 'API Server'
+ required: true
+ default: ''
+ type: string
+ custom:
+ description: "Custom JSON"
+ required: true
+ default: ''
+ type: string
+ uuid:
+ description: "uuid of request"
+ required: true
+ default: ''
+ type: string
+ iconbase64:
+ description: "icon in base64"
+ required: false
+ default: ''
+ type: string
+ logobase64:
+ description: "logo in base64"
+ required: false
+ default: ''
+ type: string
+ appname:
+ description: "app name"
+ required: true
+ default: 'rustdesk'
+ type: string
+ filename:
+ description: "Filename"
+ required: true
+ default: 'rustdesk'
+ type: string
+ extras:
+ description: "extra inputs in json"
+ required: true
+ default: '{}'
+ type: string
+
+
+env:
+ SCITER_RUST_VERSION: "1.75" # https://github.com/rustdesk/rustdesk/discussions/7503, also 1.78 has ABI change which causes our sciter version not working, https://blog.rust-lang.org/2024/03/30/i128-layout-update.html
+ RUST_VERSION: "1.75" # sciter failed on m1 with 1.78 because of https://blog.rust-lang.org/2024/03/30/i128-layout-update.html
+ CARGO_NDK_VERSION: "3.1.2"
+ SCITER_ARMV7_CMAKE_VERSION: "3.29.7"
+ SCITER_NASM_DEBVERSION: "2.14-1"
+ LLVM_VERSION: "15.0.6"
+ FLUTTER_VERSION: "3.19.6"
+ ANDROID_FLUTTER_VERSION: "3.13.9" # >= 3.16 is very slow on my android phone, but work well on most of others. We may switch to new flutter after changing to texture rendering (I believe it can solve my problem).
+ FLUTTER_RUST_BRIDGE_VERSION: "1.80.1"
+ # for arm64 linux because official Dart SDK does not work
+ FLUTTER_ELINUX_VERSION: "3.16.9"
+ TAG_NAME: "${{ inputs.upload-tag }}"
+ VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
+ # vcpkg version: 2024.07.12
+ VCPKG_COMMIT_ID: "1de2026f28ead93ff1773e6e680387643e914ea1"
+ VERSION: "1.3.1"
+ NDK_VERSION: "r27"
+ #signing keys env variable checks
+ ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}"
+ MACOS_P12_BASE64: "${{ secrets.MACOS_P12_BASE64 }}"
+ # To make a custom build with your own servers set the below secret values
+ RS_PUB_KEY: "${{ inputs.key }}"
+ RENDEZVOUS_SERVER: "${{ inputs.server }}"
+ CUSTOM: "${{ inputs.custom }}"
+ UUIDFOLDER: "${{ inputs.uuid }}"
+ API_SERVER: "${{ inputs.apiServer }}"
+ UPLOAD_ARTIFACT: 'true'
+ SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}"
+
+
+jobs:
+ # build-RustDeskTempTopMostWindow:
+ # uses: ./.github/workflows/third-party-RustDeskTempTopMostWindow.yml
+ # with:
+ # upload-artifact: true
+ # target: windows-2022
+ # configuration: Release
+ # platform: x64
+ # target_version: Windows10
+ # strategy:
+ # fail-fast: false
+
+ build-for-windows-flutter:
+ name: Build Windows
+ #needs: [build-RustDeskTempTopMostWindow]
+ runs-on: [self-hosted, windows]
+ strategy:
+ fail-fast: false
+ matrix:
+ job:
+ # - { target: i686-pc-windows-msvc , os: windows-2022 }
+ # - { target: x86_64-pc-windows-gnu , os: windows-2022 }
+ - {
+ target: x86_64-pc-windows-msvc,
+ os: windows-2022,
+ arch: x86_64,
+ vcpkg-triplet: x64-windows-static,
+ }
+ # - { target: aarch64-pc-windows-msvc, os: windows-2022, arch: aarch64 }
+ steps:
+ - name: Export GitHub Actions cache environment variables
+ uses: actions/github-script@v6
+ with:
+ script: |
+ core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
+ core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "5% complete"}'
+
+ - name: Checkout source code
+ uses: actions/checkout@v4
+ with:
+ repository: rustdesk/rustdesk
+
+ # - name: Install LLVM and Clang
+ # uses: KyleMayes/install-llvm-action@v1
+ # with:
+ # version: ${{ env.LLVM_VERSION }}
+
+ # - name: Install flutter
+ # uses: subosito/flutter-action@v2.12.0 #https://github.com/subosito/flutter-action/issues/277
+ # with:
+ # channel: "stable"
+ # flutter-version: ${{ env.FLUTTER_VERSION }}
+ # cache: true
+
+ # - name: Install Rust toolchain
+ # uses: dtolnay/rust-toolchain@v1
+ # with:
+ # toolchain: ${{ env.SCITER_RUST_VERSION }}
+ # targets: ${{ matrix.job.target }}
+ # components: "rustfmt"
+
+ # - uses: Swatinem/rust-cache@v2
+ # with:
+ # prefix-key: ${{ matrix.job.os }}
+
+ # - name: Install flutter rust bridge deps
+ # run: |
+ # git config --global core.longpaths true
+ # cargo install flutter_rust_bridge_codegen --version ${{ env.FLUTTER_RUST_BRIDGE_VERSION }} --features "uuid"
+ # Push-Location flutter ; flutter pub get ; Pop-Location
+ # ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
+
+ # - name: Setup vcpkg with Github Actions binary cache
+ # uses: lukka/run-vcpkg@v11
+ # with:
+ # vcpkgDirectory: C:\vcpkg
+ # vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
+ # doNotCache: false
+
+ # - name: Install vcpkg dependencies
+ # env:
+ # VCPKG_DEFAULT_HOST_TRIPLET: ${{ matrix.job.vcpkg-triplet }}
+ # run: |
+ # if ! $VCPKG_ROOT/vcpkg \
+ # install \
+ # --triplet ${{ matrix.job.vcpkg-triplet }} \
+ # --x-install-root="$VCPKG_ROOT/installed"; then
+ # find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
+ # echo "$_1:"
+ # echo "======"
+ # cat "$_1"
+ # echo "======"
+ # echo ""
+ # done
+ # exit 1
+ # fi
+ # shell: bash
+
+ - name: icon stuff
+ continue-on-error: true
+ shell: bash
+ run: |
+ mv ./res/icon.ico ./res/icon.ico.bak
+ mv ./res/icon.png ./res/icon.png.bak
+ mv ./res/tray-icon.ico ./res/tray-icon.ico.bak
+ echo "${{ inputs.iconbase64 }}" | base64 -d > ./res/icon.png
+
+ - name: magick stuff
+ continue-on-error: true
+ run: |
+ mv ./res/32x32.png ./res/32x32.png.bak
+ mv ./res/64x64.png ./res/64x64.png.bak
+ mv ./res/128x128.png ./res/128x128.png.bak
+ mv ./res/128x128@2x.png ./res/128x128@2x.png.bak
+ magick ./res/icon.png -define icon:auto-resize=256,64,48,32,16 ./res/icon.ico
+ cp ./res/icon.ico ./res/tray-icon.ico
+ magick ./res/icon.png -resize 32x32 ./res/32x32.png
+ magick ./res/icon.png -resize 64x64 ./res/64x64.png
+ magick ./res/icon.png -resize 128x128 ./res/128x128.png
+ magick ./res/128x128.png -resize 200% ./res/128x128@2x.png
+
+
+ - name: ui.rs icon
+ continue-on-error: true
+ shell: bash
+ run: |
+ cp ./src/ui.rs ./src/ui.rs.bak
+ sed -i -e 's|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|${{ inputs.iconbase64 }}|' ./src/ui.rs
+
+ - name: cargo.toml, runner.rc name, en.rs
+ continue-on-error: true
+ shell: bash
+ run: |
+ cp ./Cargo.toml ./Cargo.toml.bak
+ sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./Cargo.toml
+ sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./Cargo.toml
+ cp ./libs/portable/Cargo.toml ./libs/portable/Cargo.toml.bak
+ sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
+ sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./libs/portable/Cargo.toml
+ cp ./flutter/windows/runner/Runner.rc ./flutter/windows/runner/Runner.rc.bak
+ sed -i -e 's|"RustDesk Remote Desktop"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ inputs.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"Copyright © 2024 Purslane Ltd. All rights reserved."|"Copyright © 2024"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"rustdesk.exe"|"${{ inputs.filename }}"|' ./flutter/windows/runner/Runner.rc
+ sed -i -e 's|"RustDesk"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc
+ cp ./src/lang/en.rs ./src/lang/en.rs.bak
+ sed -i -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/en.rs
+ sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py
+ sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ fromJson(inputs.extras).urlLink }}'));|" ./flutter/lib/common.dart
+ sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
+ sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart
+ sed -i -e '/const KEY:/,/};/d' ./src/common.rs
+ sed -i -e '/let Ok(data) = sign::verify(&data, &pk)/,/};/d' ./src/common.rs
+
+ - name: fix connection delay
+ continue-on-error: true
+ if: ${{ fromJson(inputs.extras).delayFix == 'true' }}
+ shell: bash
+ run: |
+ sed -i -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs
+
+ - name: run as admin
+ continue-on-error: true
+ if: ${{ fromJson(inputs.extras).runasadmin == 'true' }}
+ shell: bash
+ run: |
+ echo "SET_TARGET_PROPERTIES(\${BINARY_NAME} PROPERTIES LINK_FLAGS \"/MANIFESTUAC:\\\"level='requireAdministrator' uiAccess='false'\\\" /SUBSYSTEM:WINDOWS\")" >> ./flutter/windows/runner/CMakeLists.txt
+ sed -i '/administrator/d' res/manifest.xml
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "15% complete"}'
+
+ - name: replace flutter icons
+ run: |
+ cd ./flutter
+ flutter pub run flutter_launcher_icons
+ cd ..
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "30% complete"}'
+
+ - name: generate rustbridge
+ run: |
+ ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "50% complete, this step takes about 5 minutes, be patient."}'
+
+ - name: Build rustdesk
+ run: |
+ python .\build.py --portable --flutter --skip-portable-pack
+ mv ./flutter/build/windows/x64/runner/Release ./rustdesk
+
+ - name: logo stuff
+ continue-on-error: true
+ shell: bash
+ run: |
+ echo "${{ inputs.logobase64 }}" | base64 -d > ./rustdesk/data/flutter_assets/assets/logo.png
+
+ - name: icon stuff
+ continue-on-error: true
+ run: |
+ mv ./rustdesk/data/flutter_assets/assets/icon.svg ./rustdesk/data/flutter_assets/assets/icon.svg.bak
+ magick ./res/icon.png ./rustdesk/data/flutter_assets/assets/icon.svg
+
+
+ #lines removed from above:
+ #Invoke-WebRequest -Uri https://github.com/rustdesk-org/rdev/releases/download/usbmmidd_v2/usbmmidd_v2.zip -OutFile usbmmidd_v2.zip
+ #Expand-Archive usbmmidd_v2.zip -DestinationPath . -Force
+ #Remove-Item -Path usbmmidd_v2\Win32 -Recurse
+ #Remove-Item -Path "usbmmidd_v2\deviceinstaller64.exe", "usbmmidd_v2\deviceinstaller.exe", "usbmmidd_v2\usbmmidd.bat"
+ #mv -Force .\usbmmidd_v2 ./rustdesk
+
+ - name: find Runner.res
+ # Windows: find Runner.res (compiled from ./flutter/windows/runner/Runner.rc), copy to ./Runner.res
+ # Runner.rc does not contain actual version, but Runner.res does
+ continue-on-error: true
+ shell: bash
+ run: |
+ runner_res=$(find . -name "Runner.res");
+ if [ "$runner_res" == "" ]; then
+ echo "Runner.res: not found";
+ else
+ echo "Runner.res: $runner_res";
+ cp $runner_res ./libs/portable/Runner.res;
+ echo "list ./libs/portable/Runner.res";
+ ls -l ./libs/portable/Runner.res;
+ fi
+
+ # - name: Download RustDeskTempTopMostWindow artifacts
+ # uses: actions/download-artifact@master
+ # if: env.UPLOAD_ARTIFACT == 'true'
+ # with:
+ # name: topmostwindow-artifacts
+ # path: "./rustdesk"
+
+ - name: Upload unsigned
+ if: env.UPLOAD_ARTIFACT == 'true'
+ uses: actions/upload-artifact@master
+ with:
+ name: rustdesk-unsigned-windows-${{ matrix.job.arch }}
+ path: rustdesk
+
+ # - name: Sign rustdesk files
+ # if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != ''
+ # shell: bash
+ # run: |
+ # pip3 install requests argparse
+ # BASE_URL=${{ secrets.SIGN_BASE_URL }} SECRET_KEY=${{ secrets.SIGN_SECRET_KEY }} python3 res/job.py sign_files ./rustdesk/
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "70% complete, this step takes about 5 minutes, be patient."}'
+
+ - name: Sign rustdesk files
+ uses: GermanBluefox/code-sign-action@v7
+ if: env.UPLOAD_ARTIFACT == 'true'
+ with:
+ certificate: '${{ secrets.WINDOWS_PFX_BASE64 }}'
+ password: '${{ secrets.WINDOWS_PFX_PASSWORD }}'
+ certificatesha1: '${{ secrets.WINDOWS_PFX_SHA1_THUMBPRINT }}'
+ # certificatename: '${{ secrets.CERTNAME }}'
+ folder: './rustdesk/'
+ recursive: true
+
+ - name: Create custom.txt file
+ shell: bash
+ run: |
+ echo -n "${{ env.CUSTOM }}" | cat > ./rustdesk/custom.txt
+
+ #if [ "${{ env.DIRECTION }}" = "Incoming" ]; then echo -n "eyJjb25uLXR5cGUiOiJpbmNvbWluZyJ9" | cat > ./rustdesk/custom.txt; fi
+ #if [ "${{ env.DIRECTION }}" = "Outgoing" ]; then echo -n "eyJjb25uLXR5cGUiOiJvdXRnb2luZyJ9" | cat > ./rustdesk/custom.txt; fi
+
+ - name: Build self-extracted executable
+ shell: bash
+ if: env.UPLOAD_ARTIFACT == 'true'
+ run: |
+ mv "./rustdesk/rustdesk.exe" "./rustdesk/${{ inputs.appname }}.exe"
+ sed -i '/dpiAware/d' res/manifest.xml
+ pushd ./libs/portable
+ pip3 install -r requirements.txt
+ python ./generate.py -f ../../rustdesk/ -o . -e "../../rustdesk/${{ inputs.appname }}.exe"
+ popd
+ mkdir -p ./SignOutput
+ mv ./target/release/rustdesk-portable-packer.exe "./SignOutput/rustdesk.exe"
+
+ # - name: Add MSBuild to PATH
+ # uses: microsoft/setup-msbuild@v2
+
+ # - name: Build msi
+ # if: env.UPLOAD_ARTIFACT == 'true'
+ # run: |
+ # pushd ./res/msi
+ # python preprocess.py --arp -d ../../rustdesk
+ # nuget restore msi.sln
+ # msbuild msi.sln -p:Configuration=Release -p:Platform=x64 /p:TargetVersion=Windows10
+ # cp ./Package/bin/x64/Release/en-us/Package.msi ../../SignOutput/rustdesk-latest.msi
+ # mv ./Package/bin/x64/Release/en-us/Package.msi ../../SignOutput/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.msi
+ # sha256sum ../../SignOutput/rustdesk-*.msi
+
+ # - name: Sign rustdesk self-extracted file
+ # if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != ''
+ # shell: bash
+ # run: |
+ # BASE_URL=${{ secrets.SIGN_BASE_URL }} SECRET_KEY=${{ secrets.SIGN_SECRET_KEY }} python3 res/job.py sign_files ./SignOutput
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "85% complete"}'
+
+ - name: Sign rustdesk self-extracted file
+ uses: GermanBluefox/code-sign-action@v7
+ if: env.UPLOAD_ARTIFACT == 'true'
+ with:
+ certificate: '${{ secrets.WINDOWS_PFX_BASE64 }}'
+ password: '${{ secrets.WINDOWS_PFX_PASSWORD }}'
+ certificatesha1: '${{ secrets.WINDOWS_PFX_SHA1_THUMBPRINT }}'
+ # certificatename: '${{ secrets.WINDOWS_PFX_NAME }}'
+ folder: './SignOutput'
+ recursive: false
+
+ # - name: Publish Release
+ # uses: softprops/action-gh-release@v1
+ # if: env.UPLOAD_ARTIFACT == 'true'
+ # with:
+ # prerelease: true
+ # tag_name: ${{ env.TAG_NAME }}
+ # files: |
+ # ./SignOutput/rustdesk-*.msi
+ # ./SignOutput/rustdesk-*.exe
+
+ - name: rename rustdesk.exe to filename.exe
+ run: |
+ mv ./SignOutput/rustdesk.exe "./SignOutput/${{ inputs.filename }}.exe"
+
+ - name: Upload to FTP
+ uses: SamKirkland/FTP-Deploy-Action@v4.3.5
+ with:
+ server: ${{ secrets.GEN_FTP_SERVER }}
+ username: ${{ secrets.GEN_FTP_USER }}
+ password: ${{ secrets.GEN_FTP_PASSWORD }}
+ local-dir: ./SignOutput/
+ server-dir: /root/rdgen/exe/${{ env.UUIDFOLDER }}/
+
+ - name: Report Status
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}'
+
+ - name: failed
+ if: failure()
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation failed, try again"}'
+
+ - name: failed
+ if: cancelled()
+ uses: fjogeleit/http-request-action@v1
+ with:
+ url: ${{ secrets.GENURL }}/updategh
+ method: 'POST'
+ customHeaders: '{"Content-Type": "application/json"}'
+ data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}'
diff --git a/rdgenerator/templates/generated.html b/rdgenerator/templates/generated.html
index 8af93ea..6e2ecff 100644
--- a/rdgenerator/templates/generated.html
+++ b/rdgenerator/templates/generated.html
@@ -1 +1,11 @@
-{{filename}}
\ No newline at end of file
+{% if platform == 'windows' %}
+{{filename}}.exe
+{% elif platform == 'linux' %}
+{{filename}}.deb
+{{filename}}.rpm
+{{filename}}-suse.rpm
+{% elif platform == 'android' %}
+{{filename}}.apk
+{% else %}
+Error, no file generated
+{% endif %}
\ No newline at end of file
diff --git a/rdgenerator/templates/waiting.html b/rdgenerator/templates/waiting.html
index a54d4a5..1c13564 100644
--- a/rdgenerator/templates/waiting.html
+++ b/rdgenerator/templates/waiting.html
@@ -8,7 +8,7 @@
Status: {{status}}