Merge pull request #178 from bryangerlach/master

merge master into dev
This commit is contained in:
Bryan
2026-01-10 18:48:38 -06:00
committed by GitHub
19 changed files with 1422 additions and 212 deletions

63
.github/patches/allowCustom.py vendored Normal file
View File

@@ -0,0 +1,63 @@
import os
import shutil
def remove_line_block(filepath, start_phrase, lines_to_remove_after_start):
"""
Removes a starting line and a fixed number of lines immediately following it.
:param filepath: The path to the file to modify.
:param start_phrase: The unique string to identify the first line of the block.
:param lines_to_remove_after_start: The number of lines to remove after the starting line.
"""
# 1. Configuration for the removal logic
# The starting line is: const KEY: &str = "5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=";
# The block contains this line plus 8 following lines, so we want to skip 9 lines in total.
total_lines_to_skip = 1 + lines_to_remove_after_start # 1 (start line) + 8 (following lines) = 9
lines_to_keep = []
skip_count = 0
# 2. Read and filter the file content
try:
with open(filepath, 'r') as file:
for line in file:
# If we are currently in the process of skipping lines, decrement the counter and continue
if skip_count > 0:
skip_count -= 1
continue
# Check if the line matches the start phrase (we use .strip() to ignore indentation/whitespace)
if line.strip().startswith(start_phrase.strip()):
# Start skipping the block (including the current line)
skip_count = total_lines_to_skip - 1
# Note: We subtract 1 because the 'continue' will handle the first line removal immediately
continue
# If we are not skipping, keep the line, but change custom.txt to custom_.txt
line = line.replace("custom.txt", "custom_.txt")
lines_to_keep.append(line)
except FileNotFoundError:
print(f"Error: File not found at {filepath}")
return
# 3. Write the remaining lines back to the file
try:
with open(filepath, 'w') as file:
file.writelines(lines_to_keep)
print(f"Success! Removed the 9-line block starting with '{start_phrase.strip()}' from {filepath}.")
except IOError as e:
print(f"An error occurred while writing to the file: {e}")
def main():
file_path = 'src/common.rs'
start_phrase = 'const KEY: &str = "5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=";'
lines_to_remove_after_start = 8
remove_line_block(file_path, start_phrase, lines_to_remove_after_start)
if __name__ == "__main__":
main()

View File

@@ -1,8 +1,8 @@
diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart
index 839ea1a81..9cee52263 100644 index bc3757f1e..ba6509802 100644
--- a/flutter/lib/desktop/widgets/remote_toolbar.dart --- a/flutter/lib/desktop/widgets/remote_toolbar.dart
+++ b/flutter/lib/desktop/widgets/remote_toolbar.dart +++ b/flutter/lib/desktop/widgets/remote_toolbar.dart
@@ -437,6 +437,7 @@ class _RemoteToolbarState extends State<RemoteToolbar> { @@ -317,6 +317,7 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
borderRadius: borderRadius, borderRadius: borderRadius,
child: _DraggableShowHide( child: _DraggableShowHide(
id: widget.id, id: widget.id,
@@ -10,7 +10,7 @@ index 839ea1a81..9cee52263 100644
sessionId: widget.ffi.sessionId, sessionId: widget.ffi.sessionId,
dragging: _dragging, dragging: _dragging,
fractionX: _fractionX, fractionX: _fractionX,
@@ -2234,6 +2235,7 @@ class RdoMenuButton<T> extends StatelessWidget { @@ -2460,6 +2461,7 @@ class RdoMenuButton<T> extends StatelessWidget {
class _DraggableShowHide extends StatefulWidget { class _DraggableShowHide extends StatefulWidget {
final String id; final String id;
@@ -18,7 +18,7 @@ index 839ea1a81..9cee52263 100644
final SessionID sessionId; final SessionID sessionId;
final RxDouble fractionX; final RxDouble fractionX;
final RxBool dragging; final RxBool dragging;
@@ -2246,6 +2248,7 @@ class _DraggableShowHide extends StatefulWidget { @@ -2472,6 +2474,7 @@ class _DraggableShowHide extends StatefulWidget {
const _DraggableShowHide({ const _DraggableShowHide({
Key? key, Key? key,
required this.id, required this.id,
@@ -26,7 +26,7 @@ index 839ea1a81..9cee52263 100644
required this.sessionId, required this.sessionId,
required this.fractionX, required this.fractionX,
required this.dragging, required this.dragging,
@@ -2357,6 +2360,7 @@ class _DraggableShowHideState extends State<_DraggableShowHide> { @@ -2583,6 +2586,7 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
_buildDraggable(context), _buildDraggable(context),
@@ -34,9 +34,9 @@ index 839ea1a81..9cee52263 100644
Obx(() => buttonWrapper( Obx(() => buttonWrapper(
() { () {
widget.setFullscreen(!isFullscreen.value); widget.setFullscreen(!isFullscreen.value);
@@ -2463,3 +2467,50 @@ Widget _buildPointerTrackWidget(Widget child, FFI? ffi) { @@ -2742,3 +2746,50 @@ class EdgeThicknessControl extends StatelessWidget {
), return slider;
); }
} }
+ +
+class _CycleMonitorMenu extends StatelessWidget { +class _CycleMonitorMenu extends StatelessWidget {

View File

@@ -26,7 +26,7 @@ jobs:
job: job:
- { - {
target: x86_64-unknown-linux-gnu, target: x86_64-unknown-linux-gnu,
os: ubuntu-20.04, os: ubuntu-24.04,
extra-build-args: "", extra-build-args: "",
} }
steps: steps:
@@ -56,9 +56,9 @@ jobs:
gcc \ gcc \
git \ git \
g++ \ g++ \
libclang-10-dev \ libclang-dev \
libgtk-3-dev \ libgtk-3-dev \
llvm-10-dev \ llvm-dev \
nasm \ nasm \
ninja-build \ ninja-build \
pkg-config \ pkg-config \

69
.github/workflows/build-web.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: Build web
on:
workflow_dispatch:
env:
FLUTTER_VERSION: "3.24.5"
TAG_NAME: "nightly"
VERSION: "1.3.9"
jobs:
build-rustdesk-web:
name: build-rustdesk-web
runs-on: ubuntu-24.04
strategy:
fail-fast: false
env:
RELEASE_NAME: web-basic
steps:
- name: Checkout source code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Prepare env
run: |
sudo apt-get update -y
sudo apt-get install -y wget npm
- 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 }}
# https://rustdesk.com/docs/en/dev/build/web/
- name: Build web
shell: bash
run: |
pushd flutter/web/v2
npm install yarn -g
npm install typescript -g
npm install protoc -g
# Install protoc first, see: https://google.github.io/proto-lens/installing-protoc.html
npm install ts-proto
# Only works with vite <= 2.8, see: https://github.com/vitejs/vite/blob/main/docs/guide/build.md#chunking-strategy
npm install vite@2.8
yarn install && yarn build
popd
pushd flutter/web/v2
wget https://github.com/rustdesk/doc.rustdesk.com/releases/download/console/web_deps.tar.gz
tar xzf web_deps.tar.gz
popd
pushd flutter
flutter build web --release
cd build
#cp ../web/README.md web
# TODO: Remove the following line when the web is almost complete.
#echo -e "\n\nThis build is for preview and not full functionality." >> web/README.md
dir_name="rustdesk-${{ env.VERSION }}-${{ env.RELEASE_NAME }}"
mv web "${dir_name}" && tar czf "${dir_name}".tar.gz "${dir_name}"
sha256sum "${dir_name}".tar.gz
popd
- name: Upload APK artifact
uses: actions/upload-artifact@v4
with:
name: web
path: flutter/build/rustdesk-${{ env.VERSION }}-${{ env.RELEASE_NAME }}.tar.gz

View File

@@ -20,6 +20,9 @@ jobs:
elif [[ "${{ github.ref_type }}" == "tag" ]]; then elif [[ "${{ github.ref_type }}" == "tag" ]]; then
echo "IMAGE_TAG=${{ github.ref_name }}" >> "$GITHUB_ENV" echo "IMAGE_TAG=${{ github.ref_name }}" >> "$GITHUB_ENV"
echo "CREATE_IMAGE=true" >> "$GITHUB_ENV" echo "CREATE_IMAGE=true" >> "$GITHUB_ENV"
elif [[ "${{ github.ref }}" == "refs/heads/master" ]]; then
echo "IMAGE_TAG=latest" >> "$GITHUB_ENV"
echo "CREATE_IMAGE=true" >> "$GITHUB_ENV"
else else
echo "CREATE_IMAGE=false" >> "$GITHUB_ENV" echo "CREATE_IMAGE=false" >> "$GITHUB_ENV"
fi fi

View File

@@ -69,7 +69,8 @@ env:
TAG_NAME: "${{ inputs.upload-tag }}" TAG_NAME: "${{ inputs.upload-tag }}"
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
# vcpkg version: 2024.07.12 # vcpkg version: 2024.07.12
VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836" VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b"
ARMV7_VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836"
VERSION: "${{ fromJson(inputs.extras).version }}" VERSION: "${{ fromJson(inputs.extras).version }}"
NDK_VERSION: "r27c" NDK_VERSION: "r27c"
#signing keys env variable checks #signing keys env variable checks
@@ -96,21 +97,21 @@ jobs:
- { - {
arch: aarch64, arch: aarch64,
target: aarch64-linux-android, target: aarch64-linux-android,
os: ubuntu-20.04, os: ubuntu-24.04,
reltype: release, reltype: release,
suffix: "", suffix: "",
} }
- { - {
arch: armv7, arch: armv7,
target: armv7-linux-androideabi, target: armv7-linux-androideabi,
os: ubuntu-20.04, os: ubuntu-24.04,
reltype: release, reltype: release,
suffix: "", suffix: "",
} }
- { - {
arch: x86_64, arch: x86_64,
target: x86_64-linux-android, target: x86_64-linux-android,
os: ubuntu-20.04, os: ubuntu-24.04,
reltype: release, reltype: release,
suffix: "", suffix: "",
} }
@@ -145,6 +146,7 @@ jobs:
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
@@ -166,7 +168,8 @@ jobs:
libayatana-appindicator3-dev \ libayatana-appindicator3-dev \
libasound2-dev \ libasound2-dev \
libc6-dev \ libc6-dev \
libclang-10-dev \ libclang-dev \
libunwind-dev \
libgstreamer1.0-dev \ libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \ libgstreamer-plugins-base1.0-dev \
libgtk-3-dev \ libgtk-3-dev \
@@ -179,7 +182,7 @@ jobs:
libxcb-xfixes0-dev \ libxcb-xfixes0-dev \
libxdo-dev \ libxdo-dev \
libxfixes-dev \ libxfixes-dev \
llvm-10-dev \ llvm-dev \
nasm \ nasm \
ninja-build \ ninja-build \
openjdk-17-jdk-headless \ openjdk-17-jdk-headless \
@@ -187,6 +190,11 @@ jobs:
tree \ tree \
wget wget
- name: Install dependencies
continue-on-error: true
run: |
sudo apt-get install -y potrace
- name: Checkout source code - name: Checkout source code
if: ${{ env.VERSION != 'master' }} if: ${{ env.VERSION != 'master' }}
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -228,19 +236,11 @@ jobs:
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }} vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
doNotCache: false doNotCache: false
- name: Report Status
uses: fjogeleit/http-request-action@v1
with:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "15% complete"}'
- name: Install vcpkg dependencies - name: Install vcpkg dependencies
run: | run: |
case ${{ matrix.job.target }} in case ${{ matrix.job.target }} in
aarch64-linux-android) aarch64-linux-android)
ANDROID_TARGET=arm64-v8a ANDROID_TARGET=arm64-v8a
;; ;;
armv7-linux-androideabi) armv7-linux-androideabi)
ANDROID_TARGET=armeabi-v7a ANDROID_TARGET=armeabi-v7a
@@ -365,8 +365,16 @@ jobs:
sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/desktop/pages/desktop_setting_page.dart sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./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 "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart
sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/mobile/pages/settings_page.dart sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/mobile/pages/settings_page.dart
sed -i -e "s|child: Text('rustdesk.com',|child: Text('${{ fromJson(inputs.extras).urlLink }}',|" ./flutter/lib/mobile/pages/settings_page.dart
sed -i -e "s|https://rustdesk.com/privacy.html|${{ fromJson(inputs.extras).urlLink }}/privacy.html|" ./flutter/lib/desktop/pages/install_page.dart sed -i -e "s|https://rustdesk.com/privacy.html|${{ fromJson(inputs.extras).urlLink }}/privacy.html|" ./flutter/lib/desktop/pages/install_page.dart
- name: change app id to custom
if: fromJson(inputs.extras).androidappid != 'com.carriez.flutter_hbb'
continue-on-error: true
shell: bash
run: |
sed -i -e 's|com.carriez.flutter_hbb|${{ fromJson(inputs.extras).androidappid }}|' ./flutter/android/app/build.gradle
- name: change download link to custom - name: change download link to custom
if: fromJson(inputs.extras).downloadLink != 'https://rustdesk.com/download' if: fromJson(inputs.extras).downloadLink != 'https://rustdesk.com/download'
continue-on-error: true continue-on-error: true
@@ -389,7 +397,7 @@ jobs:
if: ${{ fromJson(inputs.extras).delayFix == 'true' }} if: ${{ fromJson(inputs.extras).delayFix == 'true' }}
shell: bash shell: bash
run: | run: |
sed -i -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs sed -i -e 's|!key.is_empty()|false|' ./src/client.rs
- name: add cycle monitors to toolbar - name: add cycle monitors to toolbar
continue-on-error: true continue-on-error: true
@@ -417,9 +425,11 @@ jobs:
if: fromJson(inputs.extras).removeNewVersionNotif == 'true' if: fromJson(inputs.extras).removeNewVersionNotif == 'true'
run: | run: |
sed -i -e 's|updateUrl.isNotEmpty|false|' ./flutter/lib/desktop/pages/desktop_home_page.dart sed -i -e 's|updateUrl.isNotEmpty|false|' ./flutter/lib/desktop/pages/desktop_home_page.dart
sed -i '/let (request, url) =/,/Ok(())/{/Ok(())/!d}' ./src/common.rs
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
@@ -474,6 +484,7 @@ jobs:
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
@@ -495,6 +506,8 @@ jobs:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64 JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
run: | run: |
export PATH=/usr/lib/jvm/java-17-openjdk-amd64/bin:$PATH export PATH=/usr/lib/jvm/java-17-openjdk-amd64/bin:$PATH
# Increase Gradle JVM memory for CI builds
sed -i "s/org.gradle.jvmargs=-Xmx1024M/org.gradle.jvmargs=-Xmx2g/g" ./flutter/android/gradle.properties
# temporary use debug sign config # temporary use debug sign config
sed -i "s/signingConfigs.release/signingConfigs.debug/g" ./flutter/android/app/build.gradle sed -i "s/signingConfigs.release/signingConfigs.debug/g" ./flutter/android/app/build.gradle
case ${{ matrix.job.target }} in case ${{ matrix.job.target }} in
@@ -502,8 +515,8 @@ jobs:
mkdir -p ./flutter/android/app/src/main/jniLibs/arm64-v8a 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 ${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 cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so
echo -n "${{ inputs.custom }}" | cat > ./flutter/assets/custom.txt echo -n "${{ inputs.custom }}" | cat > ./flutter/assets/custom_.txt
#sed -i '/^ - assets\//a\ - assets/custom.txt' ./flutter/pubspec.yaml #sed -i '/^ - assets\//a\ - assets/custom_.txt' ./flutter/pubspec.yaml
# build flutter # build flutter
pushd flutter pushd flutter
flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-arm64 --split-per-abi flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-arm64 --split-per-abi
@@ -513,8 +526,8 @@ jobs:
mkdir -p ./flutter/android/app/src/main/jniLibs/armeabi-v7a 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 ${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 cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/librustdesk.so
echo -n "${{ inputs.custom }}" | cat > ./flutter/assets/custom.txt echo -n "${{ inputs.custom }}" | cat > ./flutter/assets/custom_.txt
#sed -i '/^ - assets\//a\ - assets/custom.txt' ./flutter/pubspec.yaml #sed -i '/^ - assets\//a\ - assets/custom_.txt' ./flutter/pubspec.yaml
# build flutter # build flutter
pushd flutter pushd flutter
flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-arm --split-per-abi flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-arm --split-per-abi
@@ -524,8 +537,8 @@ jobs:
mkdir -p ./flutter/android/app/src/main/jniLibs/x86_64 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 ${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 cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86_64/librustdesk.so
echo -n "${{ inputs.custom }}" | cat > ./flutter/assets/custom.txt echo -n "${{ inputs.custom }}" | cat > ./flutter/assets/custom_.txt
#sed -i '/^ - assets\//a\ - assets/custom.txt' ./flutter/pubspec.yaml #sed -i '/^ - assets\//a\ - assets/custom_.txt' ./flutter/pubspec.yaml
# build flutter # build flutter
pushd flutter pushd flutter
flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-x64 --split-per-abi flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-x64 --split-per-abi
@@ -535,8 +548,8 @@ jobs:
mkdir -p ./flutter/android/app/src/main/jniLibs/x86 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 ${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 cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86/librustdesk.so
echo -n "${{ inputs.custom }}" | cat > ./flutter/assets/custom.txt echo -n "${{ inputs.custom }}" | cat > ./flutter/assets/custom_.txt
#sed -i '/^ - assets\//a\ - assets/custom.txt' ./flutter/pubspec.yaml #sed -i '/^ - assets\//a\ - assets/custom_.txt' ./flutter/pubspec.yaml
# build flutter # build flutter
pushd flutter pushd flutter
flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-x86 --split-per-abi flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-x86 --split-per-abi
@@ -550,6 +563,7 @@ jobs:
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
@@ -585,6 +599,7 @@ jobs:
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'

View File

@@ -69,7 +69,8 @@ env:
TAG_NAME: "${{ inputs.upload-tag }}" TAG_NAME: "${{ inputs.upload-tag }}"
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
# vcpkg version: 2024.07.12 # vcpkg version: 2024.07.12
VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836" VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b"
ARMV7_VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836"
VERSION: "${{ fromJson(inputs.extras).version }}" VERSION: "${{ fromJson(inputs.extras).version }}"
NDK_VERSION: "r27c" NDK_VERSION: "r27c"
#signing keys env variable checks #signing keys env variable checks
@@ -98,18 +99,18 @@ jobs:
arch: x86_64, arch: x86_64,
target: x86_64-unknown-linux-gnu, target: x86_64-unknown-linux-gnu,
distro: ubuntu18.04, distro: ubuntu18.04,
on: ubuntu-20.04, on: ubuntu-22.04,
deb_arch: amd64, deb_arch: amd64,
vcpkg-triplet: x64-linux, vcpkg-triplet: x64-linux,
} }
# - { - {
# arch: aarch64, arch: aarch64,
# target: aarch64-unknown-linux-gnu, target: aarch64-unknown-linux-gnu,
# distro: ubuntu18.04, distro: ubuntu18.04,
# on: [self-hosted, Linux, ARM64], on: ubuntu-22.04-arm,
# deb_arch: arm64, deb_arch: arm64,
# vcpkg-triplet: arm64-linux, vcpkg-triplet: arm64-linux,
# } }
steps: steps:
- name: Export GitHub Actions cache environment variables - name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6 uses: actions/github-script@v6
@@ -130,6 +131,7 @@ jobs:
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
@@ -137,13 +139,15 @@ jobs:
data: '{"uuid": "${{ inputs.uuid }}", "status": "5% complete"}' data: '{"uuid": "${{ inputs.uuid }}", "status": "5% complete"}'
- name: Maximize build space - name: Maximize build space
if: ${{ matrix.job.arch == 'x86_64' }}
run: | run: |
sudo rm -rf /opt/ghc sudo rm -rf /opt/ghc
sudo rm -rf /usr/local/lib/android sudo rm -rf /usr/local/lib/android
sudo rm -rf /usr/share/dotnet sudo rm -rf /usr/share/dotnet
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install -y nasm qemu-user-static sudo apt-get install -y nasm
if [[ "${{ matrix.job.arch }}" == "x86_64" ]]; then
sudo apt-get install -y qemu-user-static
fi
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -196,6 +200,7 @@ jobs:
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
@@ -220,7 +225,7 @@ jobs:
- name: Install vcpkg dependencies - name: Install vcpkg dependencies
if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true' if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
run: | run: |
sudo apt install -y libva-dev libvdpau-dev sudo apt install -y libva-dev && apt show libva-dev
if ! $VCPKG_ROOT/vcpkg \ if ! $VCPKG_ROOT/vcpkg \
install \ install \
--triplet ${{ matrix.job.vcpkg-triplet }} \ --triplet ${{ matrix.job.vcpkg-triplet }} \
@@ -297,7 +302,7 @@ jobs:
git apply allowCustom.diff git apply allowCustom.diff
wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/removeSetupServerTip.diff wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/removeSetupServerTip.diff
git apply removeSetupServerTip.diff git apply removeSetupServerTip.diff
echo -n "${{ inputs.custom }}" | cat > ./custom.txt echo -n "${{ inputs.custom }}" | cat > ./custom_.txt
# sed -i '/intl:/a \ \ archive: ^3.6.1' ./flutter/pubspec.yaml # sed -i '/intl:/a \ \ archive: ^3.6.1' ./flutter/pubspec.yaml
sed -i -e 's|https://admin.rustdesk.com|${{ inputs.apiServer }}|' ./src/common.rs sed -i -e 's|https://admin.rustdesk.com|${{ inputs.apiServer }}|' ./src/common.rs
@@ -328,7 +333,7 @@ jobs:
if: ${{ fromJson(inputs.extras).delayFix == 'true' }} if: ${{ fromJson(inputs.extras).delayFix == 'true' }}
shell: bash shell: bash
run: | run: |
sed -i -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs sed -i -e 's|!key.is_empty()|false|' ./src/client.rs
- name: add cycle monitors to toolbar - name: add cycle monitors to toolbar
continue-on-error: true continue-on-error: true
@@ -356,6 +361,7 @@ jobs:
if: fromJson(inputs.extras).removeNewVersionNotif == 'true' if: fromJson(inputs.extras).removeNewVersionNotif == 'true'
run: | run: |
sed -i -e 's|updateUrl.isNotEmpty|false|' ./flutter/lib/desktop/pages/desktop_home_page.dart sed -i -e 's|updateUrl.isNotEmpty|false|' ./flutter/lib/desktop/pages/desktop_home_page.dart
sed -i '/let (request, url) =/,/Ok(())/{/Ok(())/!d}' ./src/common.rs
- name: Restore bridge files - name: Restore bridge files
if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true' if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
@@ -366,6 +372,7 @@ jobs:
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
@@ -408,7 +415,6 @@ jobs:
libpam0g-dev \ libpam0g-dev \
libpulse-dev \ libpulse-dev \
libva-dev \ libva-dev \
libvdpau-dev \
libxcb-randr0-dev \ libxcb-randr0-dev \
libxcb-shape0-dev \ libxcb-shape0-dev \
libxcb-xfixes0-dev \ libxcb-xfixes0-dev \
@@ -423,7 +429,8 @@ jobs:
rpm \ rpm \
unzip \ unzip \
wget \ wget \
xz-utils xz-utils \
libssl-dev
# we have libopus compiled by us. # we have libopus compiled by us.
apt-get remove -y libopus-dev || true apt-get remove -y libopus-dev || true
# output devs # output devs
@@ -514,8 +521,8 @@ jobs:
chmod 777 output -R chmod 777 output -R
export CARGO_INCREMENTAL=0 export CARGO_INCREMENTAL=0
export DEB_ARCH=${{ matrix.job.deb_arch }} export DEB_ARCH=${{ matrix.job.deb_arch }}
mkdir -p flutter/tmpdeb/usr/lib/rustdesk mkdir -p flutter/tmpdeb/usr/share/rustdesk
cp ./custom.txt ./flutter/tmpdeb/usr/lib/rustdesk/custom.txt cp ./custom_.txt ./flutter/tmpdeb/usr/share/rustdesk/custom_.txt
if [[ "${{ inputs.logolink }}" != "false" ]]; then if [[ "${{ inputs.logolink }}" != "false" ]]; then
wget -O ./flutter/assets/logo.png ${{ fromJson(inputs.logolink).url }}/get_png?filename=${{ fromJson(inputs.logolink).file }}"&"uuid=${{ fromJson(inputs.logolink).uuid }} wget -O ./flutter/assets/logo.png ${{ fromJson(inputs.logolink).url }}/get_png?filename=${{ fromJson(inputs.logolink).file }}"&"uuid=${{ fromJson(inputs.logolink).uuid }}
fi fi
@@ -525,13 +532,16 @@ jobs:
convert ./res/128x128.png -resize 200% ./flutter/assets/128x128@2x.png || true convert ./res/128x128.png -resize 200% ./flutter/assets/128x128@2x.png || true
cp ./flutter/assets/icon.svg ./res/scalable.svg cp ./flutter/assets/icon.svg ./res/scalable.svg
pushd ./flutter pushd ./flutter
if [[ "${{ matrix.job.arch }}" == "aarch64" ]]; then
export PATH="/opt/flutter-elinux/flutter/bin:$PATH"
fi
flutter pub get flutter pub get
dart run flutter_launcher_icons dart run flutter_launcher_icons
popd popd
fi fi
python3 ./build.py --flutter --skip-cargo python3 ./build.py --flutter --skip-cargo
for name in rustdesk*??.deb; do for name in rustdesk*??.deb; do
mv "$name" /workspace/output/"${{ inputs.filename }}.deb" mv "$name" /workspace/output/"${{ inputs.filename }}-${{ matrix.job.arch }}.deb"
done done
# rpm package # rpm package
@@ -545,7 +555,7 @@ jobs:
HBB=`pwd` rpmbuild ./res/rpm-flutter.spec -bb HBB=`pwd` rpmbuild ./res/rpm-flutter.spec -bb
pushd ~/rpmbuild/RPMS/${{ matrix.job.arch }} pushd ~/rpmbuild/RPMS/${{ matrix.job.arch }}
for name in rustdesk*??.rpm; do for name in rustdesk*??.rpm; do
mv "$name" /workspace/output/"${{ inputs.filename }}.rpm" mv "$name" /workspace/output/"${{ inputs.filename }}-${{ matrix.job.arch }}.rpm"
done done
# rpm suse package # rpm suse package
@@ -559,7 +569,7 @@ jobs:
HBB=`pwd` rpmbuild ./res/rpm-flutter-suse.spec -bb HBB=`pwd` rpmbuild ./res/rpm-flutter-suse.spec -bb
pushd ~/rpmbuild/RPMS/${{ matrix.job.arch }} pushd ~/rpmbuild/RPMS/${{ matrix.job.arch }}
for name in rustdesk*??.rpm; do for name in rustdesk*??.rpm; do
mv "$name" /workspace/output/"${{ inputs.filename }}-suse.rpm" mv "$name" /workspace/output/"${{ inputs.filename }}-suse-${{ matrix.job.arch }}.rpm"
done done
# only x86_64 for arch since we can not find newest arm64 docker image to build # only x86_64 for arch since we can not find newest arm64 docker image to build
@@ -587,33 +597,41 @@ jobs:
continue-on-error: true continue-on-error: true
if: matrix.job.arch == 'x86_64' && env.UPLOAD_ARTIFACT == 'true' && env.VERSION != 'master' if: matrix.job.arch == 'x86_64' && env.UPLOAD_ARTIFACT == 'true' && env.VERSION != 'master'
run: | run: |
cp ./res/rustdesk-${{ env.VERSION }}-0-x86_64.pkg.tar.zst ./output/${{ inputs.filename }}.pkg.tar.zst cp ./res/rustdesk-${{ env.VERSION }}-0-x86_64.pkg.tar.zst ./output/${{ inputs.filename }}-${{ matrix.job.arch }}.pkg.tar.zst
- name: send file to rdgen server - name: send file to rdgen server
if: ${{ fromJson(inputs.extras).rdgen == 'true' }} if: ${{ fromJson(inputs.extras).rdgen == 'true' }}
shell: bash shell: bash
run: | run: |
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}.deb" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-${{ matrix.job.arch }}.deb" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}.rpm" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-${{ matrix.job.arch }}.rpm" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-suse.rpm" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-suse-${{ matrix.job.arch }}.rpm" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}.pkg.tar.zst" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client || true curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-${{ matrix.job.arch }}.pkg.tar.zst" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client || true
- name: send file to api server - name: send file to api server
if: ${{ fromJson(inputs.extras).rdgen == 'false' }} if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
shell: bash shell: bash
run: | run: |
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}.deb" ${{ inputs.apiServer }}/api/save_custom_client curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-${{ matrix.job.arch }}.deb" ${{ inputs.apiServer }}/api/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}.rpm" ${{ inputs.apiServer }}/api/save_custom_client curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-${{ matrix.job.arch }}.rpm" ${{ inputs.apiServer }}/api/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-suse.rpm" ${{ inputs.apiServer }}/api/save_custom_client curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-suse-${{ matrix.job.arch }}.rpm" ${{ inputs.apiServer }}/api/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}.pkg.tar.zst" ${{ inputs.apiServer }}/api/save_custom_client || true curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./output/${{ inputs.filename }}-${{ matrix.job.arch }}.pkg.tar.zst" ${{ inputs.apiServer }}/api/save_custom_client || true
- name: Upload deb
uses: actions/upload-artifact@master
if: env.UPLOAD_ARTIFACT == 'true'
with:
name: ${{ inputs.filename }}-${{ matrix.job.arch }}.deb
path: ./output/${{ inputs.filename }}-${{ matrix.job.arch }}.deb
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
continue-on-error: true
with: with:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
customHeaders: '{"Content-Type": "application/json"}' customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}' data: '{"uuid": "${{ inputs.uuid }}", "status": "Finished ${{ matrix.job.arch }}"}'
- name: failed - name: failed
if: failure() if: failure()
@@ -631,4 +649,188 @@ jobs:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
customHeaders: '{"Content-Type": "application/json"}' customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}' data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}'
build-appimage:
name: Build appimage ${{ matrix.job.target }}
needs: [build-rustdesk-linux]
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
job:
- { target: x86_64-unknown-linux-gnu, arch: x86_64 }
- { target: aarch64-unknown-linux-gnu, arch: aarch64 }
steps:
- name: Checkout source code
if: ${{ env.VERSION != 'master' }}
uses: actions/checkout@v4
with:
repository: rustdesk/rustdesk
ref: refs/tags/${{ env.VERSION }}
submodules: recursive
- name: Checkout source code
if: ${{ env.VERSION == 'master' }}
uses: actions/checkout@v4
with:
repository: rustdesk/rustdesk
submodules: recursive
- name: Download Binary
uses: actions/download-artifact@master
with:
name: ${{ inputs.filename }}-${{ matrix.job.arch }}.deb
path: .
- name: Rename Binary
run: |
mv ${{ inputs.filename }}-${{ matrix.job.arch }}.deb appimage/rustdesk.deb
- name: Build appimage package
shell: bash
run: |
# install libarchive-tools for bsdtar command used in AppImageBuilder.yml
sudo apt-get update -y
sudo apt-get install -y libarchive-tools libfuse2
# set-up appimage-builder
sudo pip3 install git+https://github.com/rustdesk-org/appimage-builder.git
# run appimage-builder
pushd appimage
sudo appimage-builder --skip-tests --recipe ./AppImageBuilder-${{ matrix.job.arch }}.yml
sudo mv ./rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.AppImage ./${{ inputs.filename }}-${{ matrix.job.arch }}.AppImage
- name: send file to rdgen server
if: ${{ fromJson(inputs.extras).rdgen == 'true' }}
shell: bash
run: |
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./appimage/${{ inputs.filename }}-${{ matrix.job.arch }}.AppImage" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client
- name: send file to api server
if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
shell: bash
run: |
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./appimage/${{ inputs.filename }}-${{ matrix.job.arch }}.AppImage" ${{ inputs.apiServer }}/api/save_custom_client
build-flatpak:
name: Build flatpak ${{ matrix.job.target }}${{ matrix.job.suffix }}
needs:
- build-rustdesk-linux
runs-on: ${{ matrix.job.on }}
strategy:
fail-fast: false
matrix:
job:
- {
target: x86_64-unknown-linux-gnu,
distro: ubuntu18.04,
on: ubuntu-22.04,
arch: x86_64,
suffix: "",
}
- {
target: aarch64-unknown-linux-gnu,
# try out newer flatpak since error of "error: Nothing matches org.freedesktop.Platform in remote flathub"
distro: ubuntu22.04,
on: ubuntu-22.04-arm,
arch: aarch64,
suffix: "",
}
steps:
- name: Checkout source code
if: ${{ env.VERSION != 'master' }}
uses: actions/checkout@v4
with:
repository: rustdesk/rustdesk
ref: refs/tags/${{ env.VERSION }}
submodules: recursive
- name: Checkout source code
if: ${{ env.VERSION == 'master' }}
uses: actions/checkout@v4
with:
repository: rustdesk/rustdesk
submodules: recursive
- name: Download Binary
uses: actions/download-artifact@master
with:
name: ${{ inputs.filename }}-${{ matrix.job.arch }}.deb
path: .
- name: Rename Binary
run: |
mv ${{ inputs.filename }}-${{ matrix.job.arch }}.deb flatpak/rustdesk.deb
- uses: rustdesk-org/run-on-arch-action@amd64-support
name: Build rustdesk flatpak package for ${{ matrix.job.arch }}
continue-on-error: true
timeout-minutes: 30
id: flatpak
with:
arch: ${{ matrix.job.arch }}
distro: ${{ matrix.job.distro }}
githubToken: ${{ github.token }}
setup: |
ls -l "${PWD}"
dockerRunArgs: |
--volume "${PWD}:/workspace"
shell: /bin/bash
install: |
apt-get update -y
apt-get install -y git flatpak flatpak-builder
run: |
# disable git safe.directory
git config --global --add safe.directory "*"
pushd /workspace
# flatpak deps
flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
# package
pushd flatpak
git clone https://github.com/flathub/shared-modules.git --depth=1
flatpak-builder --user --install-deps-from=flathub -y --force-clean --repo=repo ./build ./rustdesk.json
flatpak build-bundle ./repo ${{ inputs.filename }}-${{ matrix.job.arch }}.flatpak com.rustdesk.RustDesk
- name: send file to rdgen server
if: ${{ fromJson(inputs.extras).rdgen == 'true' }}
continue-on-error: true
shell: bash
run: |
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./flatpak/${{ inputs.filename }}-${{ matrix.job.arch }}.flatpak" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client
- name: send file to api server
if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
continue-on-error: true
shell: bash
run: |
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./flatpak/${{ inputs.filename }}-${{ matrix.job.arch }}.flatpak" ${{ inputs.apiServer }}/api/save_custom_client
deploy:
needs: [build-rustdesk-linux,build-flatpak,build-appimage]
runs-on: ubuntu-latest
steps:
- name: Set rdgen value
if: ${{ fromJson(inputs.extras).rdgen == 'true' }}
run: |
echo "STATUS_URL=${{ secrets.GENURL }}/updategh" >> $GITHUB_ENV
- name: Set rdgen value
if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
run: |
echo "STATUS_URL=${{ inputs.apiServer }}/api/updategh" >> $GITHUB_ENV
- name: Report Status
uses: fjogeleit/http-request-action@v1
with:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}'
- uses: geekyeggo/delete-artifact@v5
continue-on-error: true
with:
name: ${{ inputs.filename }}-*.deb

View File

@@ -69,7 +69,8 @@ env:
TAG_NAME: "${{ inputs.upload-tag }}" TAG_NAME: "${{ inputs.upload-tag }}"
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
# vcpkg version: 2024.07.12 # vcpkg version: 2024.07.12
VCPKG_COMMIT_ID: "b2cb0da531c2f1f740045bfe7c4dac59f0b2b69c" VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b"
ARMV7_VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836"
VERSION: "${{ fromJson(inputs.extras).version }}" VERSION: "${{ fromJson(inputs.extras).version }}"
NDK_VERSION: "r27c" NDK_VERSION: "r27c"
#signing keys env variable checks #signing keys env variable checks
@@ -77,7 +78,6 @@ env:
MACOS_P12_BASE64: "${{ secrets.MACOS_P12_BASE64 }}" MACOS_P12_BASE64: "${{ secrets.MACOS_P12_BASE64 }}"
UPLOAD_ARTIFACT: 'true' UPLOAD_ARTIFACT: 'true'
SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}" SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}"
STATUS_URL: "${{ secrets.GENURL }}/updategh"
jobs: jobs:
generate-bridge: generate-bridge:
@@ -85,29 +85,31 @@ jobs:
with: with:
version: ${{ fromJson(inputs.extras).version }} version: ${{ fromJson(inputs.extras).version }}
build-for-macos-flutter: build-for-macos:
name: Build macOS name: ${{ matrix.job.target }}
runs-on: macos-latest runs-on: ${{ matrix.job.os }}
needs: [generate-bridge] needs: [generate-bridge]
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
job: job:
# - { - {
# target: x86_64-apple-darwin, target: x86_64-apple-darwin,
# os: macos-13, #macos-latest or macos-14 use M1 now, https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#:~:text=14%20GB-,macos%2Dlatest%20or%20macos%2D14,-The%20macos%2Dlatestlabel os: macos-13, #macos-latest or macos-14 use M1 now, https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#:~:text=14%20GB-,macos%2Dlatest%20or%20macos%2D14,-The%20macos%2Dlatestlabel
# extra-build-args: "", extra-build-args: "",
# arch: x86_64, arch: x86_64,
# vcpkg-triplet: x64-osx, vcpkg-triplet: x64-osx,
# } }
- { - {
target: aarch64-apple-darwin, target: aarch64-apple-darwin,
os: macos-latest, os: macos-14,
# extra-build-args: "--disable-flutter-texture-render", # disable this for mac, because we see a lot of users reporting flickering both on arm and x64, and we can not confirm if texture rendering has better performance if htere is no vram, https://github.com/rustdesk/rustdesk/issues/6296 # extra-build-args: "--disable-flutter-texture-render", # disable this for mac, because we see a lot of users reporting flickering both on arm and x64, and we can not confirm if texture rendering has better performance if htere is no vram, https://github.com/rustdesk/rustdesk/issues/6296
extra-build-args: "--screencapturekit", extra-build-args: "--screencapturekit",
arch: aarch64, arch: aarch64,
vcpkg-triplet: arm64-osx, vcpkg-triplet: arm64-osx,
} }
env:
STATUS_URL: ${{ fromJson(inputs.extras).rdgen == 'true' && format('{0}/updategh', secrets.GENURL) || format('{0}/api/updategh', inputs.apiServer) }}
steps: steps:
- name: Export GitHub Actions cache environment variables - name: Export GitHub Actions cache environment variables
@@ -117,16 +119,6 @@ jobs:
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || ''); core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Set rdgen value
if: ${{ fromJson(inputs.extras).rdgen == 'true' }}
run: |
echo "STATUS_URL=${{ secrets.GENURL }}/updategh" >> $env:GITHUB_ENV
- name: Set rdgen value
if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
run: |
echo "STATUS_URL=${{ inputs.apiServer }}/api/updategh" >> $env:GITHUB_ENV
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
with: with:
@@ -150,12 +142,6 @@ jobs:
repository: rustdesk/rustdesk repository: rustdesk/rustdesk
submodules: recursive submodules: recursive
- name: Restore bridge files
uses: actions/download-artifact@master
with:
name: bridge-artifact
path: ./
- name: Install imagemagick and potrace and nasm and and - name: Install imagemagick and potrace and nasm and and
shell: bash shell: bash
run: | run: |
@@ -205,7 +191,7 @@ jobs:
find ./src/lang -name "*.rs" -exec sed -i '' -e 's|RustDesk|${{ inputs.appname }}|' {} \; find ./src/lang -name "*.rs" -exec sed -i '' -e 's|RustDesk|${{ inputs.appname }}|' {} \;
sed -i '' -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/nl.rs sed -i '' -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/nl.rs
sed -i '' -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py sed -i '' -e 's|https://rustdesk.com|${{ 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|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|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
sed -i '' -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/desktop/pages/desktop_setting_page.dart sed -i '' -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
@@ -258,27 +244,35 @@ jobs:
url: ${{ env.STATUS_URL }} url: ${{ env.STATUS_URL }}
method: 'POST' method: 'POST'
customHeaders: '{"Content-Type": "application/json"}' customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "10% complete"}' data: '{"uuid": "${{ inputs.uuid }}", "status": "10% complete"}'
- name: Install build runtime
run: |
brew install llvm create-dmg nasm
# pkg-config is handled in a separate step, because it may be already installed by `macos-latest`(14.7.1) runner
if command -v pkg-config &>/dev/null; then
echo "pkg-config is already installed"
else
brew install pkg-config
fi
- name: Install flutter - name: Install flutter
uses: subosito/flutter-action@v2.12.0 uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }} flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Patch flutter - name: Patch flutter
continue-on-error: true continue-on-error: true
run: | run: |
cp .github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff $(dirname $(dirname $(which flutter)))
cd $(dirname $(dirname $(which flutter))) cd $(dirname $(dirname $(which flutter)))
[[ "3.24.4" == 3.24.5 ]] && git apply flutter_3.24.4_dropdown_menu_enableFilter.diff [[ "3.24.5" == ${{env.FLUTTER_VERSION}} ]] && git apply ${{ github.workspace }}/.github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff
- name: Workaround for flutter issue - name: Workaround for flutter issue
shell: bash shell: bash
run: | run: |
cd "$(dirname "$(which flutter)")" cd "$(dirname "$(which flutter)")"
# https://github.com/flutter/flutter/issues/1.3.43 # https://github.com/flutter/flutter/issues/133533
sed -i -e 's/_setFramesEnabledState(false);/\/\/_setFramesEnabledState(false);/g' ../packages/flutter/lib/src/scheduler/binding.dart sed -i -e 's/_setFramesEnabledState(false);/\/\/_setFramesEnabledState(false);/g' ../packages/flutter/lib/src/scheduler/binding.dart
grep -n '_setFramesEnabledState(false);' ../packages/flutter/lib/src/scheduler/binding.dart grep -n '_setFramesEnabledState(false);' ../packages/flutter/lib/src/scheduler/binding.dart
@@ -289,7 +283,6 @@ jobs:
targets: ${{ matrix.job.target }} targets: ${{ matrix.job.target }}
components: "rustfmt" components: "rustfmt"
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: with:
prefix-key: ${{ matrix.job.os }} prefix-key: ${{ matrix.job.os }}
@@ -445,7 +438,7 @@ jobs:
if: ${{ fromJson(inputs.extras).delayFix == 'true' }} if: ${{ fromJson(inputs.extras).delayFix == 'true' }}
shell: bash shell: bash
run: | run: |
sed -i '' -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs sed -i -e 's|!key.is_empty()|false|' ./src/client.rs
- name: add cycle monitors to toolbar - name: add cycle monitors to toolbar
continue-on-error: true continue-on-error: true
@@ -473,19 +466,7 @@ jobs:
if: fromJson(inputs.extras).removeNewVersionNotif == 'true' if: fromJson(inputs.extras).removeNewVersionNotif == 'true'
run: | run: |
sed -i -e 's|updateUrl.isNotEmpty|false|' ./flutter/lib/desktop/pages/desktop_home_page.dart sed -i -e 's|updateUrl.isNotEmpty|false|' ./flutter/lib/desktop/pages/desktop_home_page.dart
sed -i '/let (request, url) =/,/Ok(())/{/Ok(())/!d}' ./src/common.rs
- name: Report Status
uses: fjogeleit/http-request-action@v1
with:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "15% complete"}'
- uses: Swatinem/rust-cache@v2
with:
prefix-key: ${{ matrix.job.os }}
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
@@ -495,12 +476,18 @@ jobs:
customHeaders: '{"Content-Type": "application/json"}' customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "20% complete"}' data: '{"uuid": "${{ inputs.uuid }}", "status": "20% complete"}'
- name: Restore bridge files
uses: actions/download-artifact@master
with:
name: bridge-artifact
path: ./
- name: Setup vcpkg with Github Actions binary cache - name: Setup vcpkg with Github Actions binary cache
uses: lukka/run-vcpkg@v11 uses: lukka/run-vcpkg@v11
with: with:
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }} vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
doNotCache: false doNotCache: false
- name: Install vcpkg dependencies - name: Install vcpkg dependencies
run: | run: |
if ! $VCPKG_ROOT/vcpkg \ if ! $VCPKG_ROOT/vcpkg \
@@ -515,6 +502,7 @@ jobs:
done done
exit 1 exit 1
fi fi
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
- name: Report Status - name: Report Status
uses: fjogeleit/http-request-action@v1 uses: fjogeleit/http-request-action@v1
@@ -538,7 +526,7 @@ jobs:
sed -i -e "s/MACOSX_DEPLOYMENT_TARGET = [0-9]*.[0-9]*;/MACOSX_DEPLOYMENT_TARGET = ${MIN_MACOS_VERSION};/" flutter/macos/Runner.xcodeproj/project.pbxproj sed -i -e "s/MACOSX_DEPLOYMENT_TARGET = [0-9]*.[0-9]*;/MACOSX_DEPLOYMENT_TARGET = ${MIN_MACOS_VERSION};/" flutter/macos/Runner.xcodeproj/project.pbxproj
fi fi
sed -i -e "s/RustDesk.app/\"${{ inputs.appname }}.app\"/" build.py sed -i -e "s/RustDesk.app/\"${{ inputs.appname }}.app\"/" build.py
./build.py --flutter --hwcodec ${{ matrix.job.extra-build-args }} ./build.py --flutter --hwcodec --unix-file-copy-paste ${{ matrix.job.extra-build-args }}
# - name: Copy service file # - name: Copy service file
# run: | # run: |
@@ -727,8 +715,8 @@ jobs:
if [ -n "$DMG_FILE" ]; then if [ -n "$DMG_FILE" ]; then
echo "Found DMG file: $DMG_FILE" echo "Found DMG file: $DMG_FILE"
mv "$DMG_FILE" "${{ inputs.filename }}.dmg" mv "$DMG_FILE" "${{ inputs.filename }}-${{ matrix.job.arch }}.dmg"
echo "Renamed to ${{ inputs.filename }}.dmg" echo "Renamed to ${{ inputs.filename }}-${{ matrix.job.arch }}.dmg"
else else
echo "No DMG file found matching the pattern" echo "No DMG file found matching the pattern"
exit 1 exit 1
@@ -741,7 +729,7 @@ jobs:
curl -i -X POST \ curl -i -X POST \
-H "Content-Type: multipart/form-data" \ -H "Content-Type: multipart/form-data" \
-H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" \ -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" \
-F "file=@$GITHUB_WORKSPACE/${{ inputs.filename }}.dmg" \ -F "file=@$GITHUB_WORKSPACE/${{ inputs.filename }}-${{ matrix.job.arch }}.dmg" \
-F "uuid=${{ inputs.uuid }}" \ -F "uuid=${{ inputs.uuid }}" \
"${{ secrets.GENURL }}/save_custom_client" "${{ secrets.GENURL }}/save_custom_client"
@@ -753,7 +741,7 @@ jobs:
curl -i -X POST \ curl -i -X POST \
-H "Content-Type: multipart/form-data" \ -H "Content-Type: multipart/form-data" \
-H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" \ -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" \
-F "file=@$GITHUB_WORKSPACE/${{ inputs.filename }}.dmg" \ -F "file=@$GITHUB_WORKSPACE/${{ inputs.filename }}-${{ matrix.job.arch }}.dmg" \
"${{ inputs.apiServer }}/api/save_custom_client" "${{ inputs.apiServer }}/api/save_custom_client"
- name: Report Status - name: Report Status

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
services: services:
rdgen: rdgen:
# use bryangerlach/rdgen:dev for the latest dev build # use bryangerlach/rdgen:latest for the latest build
image: bryangerlach/rdgen:v0.3.1 image: bryangerlach/rdgen:latest
restart: unless-stopped restart: unless-stopped
environment: environment:
SECRET_KEY: "django-insecure-!(t-!f#6g#sr%yfded9(xha)g+=!6craeez^cp+*&bz_7vdk61" SECRET_KEY: "django-insecure-!(t-!f#6g#sr%yfded9(xha)g+=!6craeez^cp+*&bz_7vdk61"

View File

@@ -131,3 +131,5 @@ STATIC_URL = 'static/'
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DATA_UPLOAD_MAX_MEMORY_SIZE = None

View File

@@ -3,8 +3,8 @@ from PIL import Image
class GenerateForm(forms.Form): class GenerateForm(forms.Form):
#Platform #Platform
platform = forms.ChoiceField(choices=[('windows','Windows'),('linux','Linux (currently unavailable)'),('android','Android'),('macos','macOS')], initial='windows') platform = forms.ChoiceField(choices=[('windows','Windows 64Bit'),('windows-x86','Windows 32Bit'),('linux','Linux'),('android','Android'),('macos','macOS')], initial='windows')
version = forms.ChoiceField(choices=[('master','nightly'),('1.3.8','1.3.8'),('1.3.7','1.3.7'),('1.3.6','1.3.6'),('1.3.5','1.3.5'),('1.3.4','1.3.4'),('1.3.3','1.3.3')], initial='1.3.8') version = forms.ChoiceField(choices=[('master','nightly'),('1.4.5','1.4.5'),('1.4.4','1.4.4'),('1.4.3','1.4.3'),('1.4.2','1.4.2'),('1.4.1','1.4.1'),('1.4.0','1.4.0'),('1.3.9','1.3.9'),('1.3.8','1.3.8'),('1.3.7','1.3.7'),('1.3.6','1.3.6'),('1.3.5','1.3.5'),('1.3.4','1.3.4'),('1.3.3','1.3.3')], initial='1.4.5')
help_text="'master' is the development version (nightly build) with the latest features but may be less stable" help_text="'master' is the development version (nightly build) with the latest features but may be less stable"
delayFix = forms.BooleanField(initial=True, required=False) delayFix = forms.BooleanField(initial=True, required=False)
@@ -24,6 +24,7 @@ class GenerateForm(forms.Form):
('settingsY', 'No, enable settings'), ('settingsY', 'No, enable settings'),
('settingsN', 'Yes, DISABLE settings') ('settingsN', 'Yes, DISABLE settings')
], initial='settingsY') ], initial='settingsY')
androidappid = forms.CharField(label="Custom Android App ID (replaces 'com.carriez.flutter_hbb')", required=False)
#Custom Server #Custom Server
serverIP = forms.CharField(label="Host", required=False) serverIP = forms.CharField(label="Host", required=False)
@@ -48,7 +49,7 @@ class GenerateForm(forms.Form):
#Security #Security
passApproveMode = forms.ChoiceField(choices=[('password','Accept sessions via password'),('click','Accept sessions via click'),('password-click','Accepts sessions via both')],initial='password-click') passApproveMode = forms.ChoiceField(choices=[('password','Accept sessions via password'),('click','Accept sessions via click'),('password-click','Accepts sessions via both')],initial='password-click')
permanentPassword = forms.CharField(widget=forms.PasswordInput(), required=False) permanentPassword = forms.CharField(widget=forms.PasswordInput(), required=False)
runasadmin = forms.ChoiceField(choices=[('false','No'),('true','Yes')], initial='false') #runasadmin = forms.ChoiceField(choices=[('false','No'),('true','Yes')], initial='false')
denyLan = forms.BooleanField(initial=False, required=False) denyLan = forms.BooleanField(initial=False, required=False)
enableDirectIP = forms.BooleanField(initial=False, required=False) enableDirectIP = forms.BooleanField(initial=False, required=False)
#ipWhitelist = forms.BooleanField(initial=False, required=False) #ipWhitelist = forms.BooleanField(initial=False, required=False)
@@ -66,6 +67,10 @@ class GenerateForm(forms.Form):
enableRecording = forms.BooleanField(initial=True, required=False) enableRecording = forms.BooleanField(initial=True, required=False)
enableBlockingInput = forms.BooleanField(initial=True, required=False) enableBlockingInput = forms.BooleanField(initial=True, required=False)
enableRemoteModi = forms.BooleanField(initial=False, required=False) enableRemoteModi = forms.BooleanField(initial=False, required=False)
hidecm = forms.BooleanField(initial=False, required=False)
enablePrinter = forms.BooleanField(initial=True, required=False)
enableCamera = forms.BooleanField(initial=True, required=False)
enableTerminal = forms.BooleanField(initial=True, required=False)
#Other #Other
removeWallpaper = forms.BooleanField(initial=True, required=False) removeWallpaper = forms.BooleanField(initial=True, required=False)
@@ -76,7 +81,6 @@ class GenerateForm(forms.Form):
#custom added features #custom added features
cycleMonitor = forms.BooleanField(initial=False, required=False) cycleMonitor = forms.BooleanField(initial=False, required=False)
xOffline = forms.BooleanField(initial=False, required=False) xOffline = forms.BooleanField(initial=False, required=False)
hidecm = forms.BooleanField(initial=False, required=False)
removeNewVersionNotif = forms.BooleanField(initial=False, required=False) removeNewVersionNotif = forms.BooleanField(initial=False, required=False)
def clean_iconfile(self): def clean_iconfile(self):

View File

@@ -129,17 +129,28 @@
{% if platform == 'windows' %} {% if platform == 'windows' %}
<a href='/download?filename={{filename}}.exe&uuid={{uuid}}' class="download-link">Download {{filename}}.exe</a> <a href='/download?filename={{filename}}.exe&uuid={{uuid}}' class="download-link">Download {{filename}}.exe</a>
<a href='/download?filename={{filename}}.msi&uuid={{uuid}}' class="download-link">Download {{filename}}.msi</a> <a href='/download?filename={{filename}}.msi&uuid={{uuid}}' class="download-link">Download {{filename}}.msi</a>
{% elif platform == 'windows-x86' %}
<a href='/download?filename={{filename}}.exe&uuid={{uuid}}' class="download-link">Download {{filename}}.exe</a>
{% elif platform == 'linux' %} {% elif platform == 'linux' %}
<a href='/download?filename={{filename}}.deb&uuid={{uuid}}' class="download-link">Download {{filename}}.deb</a> <a href='/download?filename={{filename}}-x86_64.deb&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.deb</a>
<a href='/download?filename={{filename}}.rpm&uuid={{uuid}}' class="download-link">Download {{filename}}.rpm</a> <a href='/download?filename={{filename}}-x86_64.rpm&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.rpm</a>
<a href='/download?filename={{filename}}-suse.rpm&uuid={{uuid}}' class="download-link">Download {{filename}}-suse.rpm</a> <a href='/download?filename={{filename}}-suse-x86_64.rpm&uuid={{uuid}}' class="download-link">Download {{filename}}-suse-x86_64.rpm</a>
<a href='/download?filename={{filename}}.pkg.tar.zst&uuid={{uuid}}' class="download-link">Download {{filename}}.pkg.tar.zst</a> <a href='/download?filename={{filename}}-x86_64.pkg.tar.zst&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.pkg.tar.zst</a>
<a href='/download?filename={{filename}}-aarch64.deb&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.deb</a>
<a href='/download?filename={{filename}}-aarch64.rpm&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.rpm</a>
<a href='/download?filename={{filename}}-suse-aarch64.rpm&uuid={{uuid}}' class="download-link">Download {{filename}}-suse-aarch64.rpm</a>
<a href='/download?filename={{filename}}-aarch64.pkg.tar.zst&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.pkg.tar.zst</a>
<a href='/download?filename={{filename}}-x86_64.AppImage&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.AppImage</a>
<a href='/download?filename={{filename}}-aarch64.AppImage&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.AppImage</a>
<a href='/download?filename={{filename}}-x86_64.flatpak&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.flatpak</a>
<a href='/download?filename={{filename}}-aarch64.flatpak&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.flatpak</a>
{% elif platform == 'android' %} {% elif platform == 'android' %}
<a href='/download?filename={{filename}}-aarch64.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.apk</a> <a href='/download?filename={{filename}}-aarch64.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.apk</a>
<a href='/download?filename={{filename}}-x86_64.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.apk</a> <a href='/download?filename={{filename}}-x86_64.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.apk</a>
<a href='/download?filename={{filename}}-armv7.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-armv7.apk</a> <a href='/download?filename={{filename}}-armv7.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-armv7.apk</a>
{% elif platform == 'macos' %} {% elif platform == 'macos' %}
<a href='/download?filename={{filename}}.dmg&uuid={{uuid}}' class="download-link">Download {{filename}}.dmg</a> <a href='/download?filename={{filename}}-x86_64.dmg&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.dmg</a>
<a href='/download?filename={{filename}}-aarch64.dmg&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.dmg</a>
{% else %} {% else %}
<p>Error: No file generated</p> <p>Error: No file generated</p>
{% endif %} {% endif %}
@@ -168,7 +179,7 @@
platformLogos.macos.style.display = 'block'; platformLogos.macos.style.display = 'block';
platformNote.textContent = 'Note: For macOS, you may need to adjust security settings to run the application.'; platformNote.textContent = 'Note: For macOS, you may need to adjust security settings to run the application.';
platformNote.style.display = 'block'; platformNote.style.display = 'block';
} else if (platform === 'windows') { } else if (platform === 'windows' || platform === 'windows-x86') {
document.getElementById('pageTitle').textContent = 'Windows Build Generated'; document.getElementById('pageTitle').textContent = 'Windows Build Generated';
platformLogos.windows.style.display = 'block'; platformLogos.windows.style.display = 'block';
platformNote.textContent = 'Note: You might need to disable SmartScreen or adjust Windows security settings.'; platformNote.textContent = 'Note: You might need to disable SmartScreen or adjust Windows security settings.';
@@ -190,4 +201,4 @@
updatePlatformUI(); updatePlatformUI();
</script> </script>
</body> </body>
</html>{{ ... }} </html>{{ ... }}

View File

@@ -90,7 +90,26 @@
transition: color 0.3s ease; transition: color 0.3s ease;
} }
.platform-icon:hover, .platform-icon.active { .platform-icon:hover, .platform-icon.active {
color: #fff; color: #2e52f7;
}
.text-64 {
font-size: 0.5em;
font-weight: bold;
bottom: -0.2em;
right: -0.2em;
position: absolute;
color: white;
transform: translate(-50%, -50%);
}
.text-32 {
font-size: 0.5em;
font-weight: bold;
bottom: -0.2em;
right: -0.2em;
position: absolute;
color: white;
transform: translate(-50%, -50%);
} }
.checkbox-group { .checkbox-group {
display: grid; display: grid;
@@ -150,6 +169,58 @@
border-radius: 4px; border-radius: 4px;
display: inline-block; display: inline-block;
margin-left: 10px; margin-left: 10px;
}
.password-requirement {
display: none; /* Hidden by default */
color: orange;
font-size: 0.9em;
margin-top: 5px;
}
.sponsor-button {
display: inline-flex;
align-items: center;
background: linear-gradient(135deg, #00457C 0%, #0079C1 100%);
color: white;
padding: 12px 28px;
border-radius: 50px;
text-decoration: none;
font-weight: 600;
font-size: 16px;
letter-spacing: 0.5px;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(0, 69, 124, 0.2);
border: 2px solid rgba(255, 255, 255, 0.1);
text-transform: uppercase;
}
.sponsor-button:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 69, 124, 0.3);
background: linear-gradient(135deg, #005AA7 0%, #0095EA 100%);
border-color: rgba(255, 255, 255, 0.2);
}
.sponsor-button i {
margin-right: 12px;
font-size: 20px;
background: white;
color: #00457C;
padding: 8px;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.sponsor-button:hover i {
transform: rotate(360deg);
color: #0095EA;
}
</style> </style>
</head> </head>
<body> <body>
@@ -175,13 +246,21 @@
<div class="platform"> <div class="platform">
<h2><i class="fas fa-desktop"></i> Select Platform</h2> <h2><i class="fas fa-desktop"></i> Select Platform</h2>
<div class="platform-icons"> <div class="platform-icons">
<i class="fab fa-windows platform-icon active" data-platform="windows"></i> <span class="fa-stack fa-lg">
<i class="fab fa-windows fa-stack-2x platform-icon active" data-platform="windows"></i>
<strong class="fa-stack-1x text-64">64</strong>
</span>
<span class="fa-stack fa-lg">
<i class="fab fa-windows fa-stack-2x platform-icon" data-platform="windows-x86"></i>
<strong class="fa-stack-1x text-32">32</strong>
</span>
<i class="fab fa-linux platform-icon" data-platform="linux"></i> <i class="fab fa-linux platform-icon" data-platform="linux"></i>
<i class="fab fa-android platform-icon" data-platform="android"></i> <i class="fab fa-android platform-icon" data-platform="android"></i>
<i class="fab fa-apple platform-icon" data-platform="macos"></i> <i class="fab fa-apple platform-icon" data-platform="macos"></i>
</div> </div>
<select name="platform" id="id_platform"> <select name="platform" id="id_platform">
<option value="windows" selected>Windows</option> <option value="windows" selected>Windows 64Bit</option>
<option value="windows-x86">Windows 32Bit</option>
<option value="linux">Linux</option> <option value="linux">Linux</option>
<option value="android">Android</option> <option value="android">Android</option>
<option value="macos">macOS</option> <option value="macos">macOS</option>
@@ -208,6 +287,8 @@
{{ form.installation }}<br><br> {{ form.installation }}<br><br>
<label for="{{ form.settings.id_for_label }}">Disable Settings:</label> <label for="{{ form.settings.id_for_label }}">Disable Settings:</label>
{{ form.settings }}<br><br> {{ form.settings }}<br><br>
<label for="{{ form.androidappid.id_for_label }}">Custom Android App ID (replaces 'com.carriez.flutter_hbb', leave blank to use default):</label>
{{ form.androidappid }}<br><br>
</div> </div>
<div class="section"> <div class="section">
@@ -229,10 +310,9 @@
<div class="container"> <div class="container">
<div class="section"> <div class="section">
<h2><i class="fas fa-shield-alt"></i> Security</h2> <h2><i class="fas fa-shield-alt"></i> Security</h2>
<label for="{{ form.runasadmin.id_for_label }}">Always run as Administrator?</label>
{{ form.runasadmin }}<br><br>
<label for="{{ form.passApproveMode.id_for_label }}">Password Approve mode:</label> <label for="{{ form.passApproveMode.id_for_label }}">Password Approve mode:</label>
{{ form.passApproveMode }}<br><br> {{ form.passApproveMode }}<br><br>
<div id="passwordRequirement" class="password-requirement">To use the hide connection window feature, please set a permanent password.</div>
<label for="{{ form.permanentPassword.id_for_label }}">Set Permanent Password:</label> <label for="{{ form.permanentPassword.id_for_label }}">Set Permanent Password:</label>
{{ form.permanentPassword }} *The password is used as default, but can be changed by the client<br><br> {{ form.permanentPassword }} *The password is used as default, but can be changed by the client<br><br>
@@ -241,7 +321,9 @@
<label for="{{ form.enableDirectIP.id_for_label }}">{{ form.enableDirectIP }} Enable direct IP access</label><br> <label for="{{ form.enableDirectIP.id_for_label }}">{{ form.enableDirectIP }} Enable direct IP access</label><br>
<label for="{{ form.autoClose.id_for_label }}">{{ form.autoClose }} Automatically close incoming sessions on user inactivity</label><br> <label for="{{ form.autoClose.id_for_label }}">{{ form.autoClose }} Automatically close incoming sessions on user inactivity</label><br>
<label for="{{ form.hidecm.id_for_label }}">{{ form.hidecm }} Allow hiding the connection window from remote screen.</label><br>
</div> </div>
<div class="section"> <div class="section">
@@ -263,7 +345,7 @@
<div class="container"> <div class="container">
<div class="section"> <div class="section">
<h2><i class="fas fa-lock"></i> Permissions</h2> <h2><i class="fas fa-lock"></i> Permissions</h2>
The following Permissions can be set as default (the user can change the settins) or override (the settings cannot be changed).<br> The following Permissions can be set as default (the user can change the settings) or override (the settings cannot be changed).<br>
{{ form.permissionsDorO }} {{ form.permissionsDorO }}
<label for="{{ form.permissionsType.id_for_label }}">Permission type:</label> <label for="{{ form.permissionsType.id_for_label }}">Permission type:</label>
{{ form.permissionsType }}<br><br> {{ form.permissionsType }}<br><br>
@@ -277,17 +359,20 @@
<label for="{{ form.enableRecording.id_for_label }}">{{ form.enableRecording }} Enable recording session</label> <label for="{{ form.enableRecording.id_for_label }}">{{ form.enableRecording }} Enable recording session</label>
<label for="{{ form.enableBlockingInput.id_for_label }}">{{ form.enableBlockingInput }} Enable blocking user input</label> <label for="{{ form.enableBlockingInput.id_for_label }}">{{ form.enableBlockingInput }} Enable blocking user input</label>
<label for="{{ form.enableRemoteModi.id_for_label }}">{{ form.enableRemoteModi }} Enable remote configuration modification</label> <label for="{{ form.enableRemoteModi.id_for_label }}">{{ form.enableRemoteModi }} Enable remote configuration modification</label>
<label for="{{ form.enablePrinter.id_for_label }}">{{ form.enablePrinter }} Enable remote printer</label>
<label for="{{ form.enableCamera.id_for_label }}">{{ form.enableCamera }} Enable remote camera</label>
<label for="{{ form.enableTerminal.id_for_label }}">{{ form.enableTerminal }} Enable remote terminal</label>
</div><br> </div><br>
<h2><i class="fas fa-code"></i> Code Changes</h2> <h2><i class="fas fa-code"></i> Code Changes</h2>
<label for="{{ form.cycleMonitor.id_for_label }}">{{ form.cycleMonitor }} Add a button to cycle through available monitors to the minimized toolbar.</label><br> <label for="{{ form.cycleMonitor.id_for_label }}">{{ form.cycleMonitor }} Add a button to cycle through available monitors to the minimized toolbar.</label><br>
<label for="{{ form.xOffline.id_for_label }}">{{ form.xOffline }} Display an X for offline devices in the addressbook.</label><br> <label for="{{ form.xOffline.id_for_label }}">{{ form.xOffline }} Display an X for offline devices in the addressbook.</label><br>
<label for="{{ form.hidecm.id_for_label }}">{{ form.hidecm }} Allow hiding the connection window from remote screen.</label><br>
<label for="{{ form.removeNewVersionNotif.id_for_label }}">{{ form.removeNewVersionNotif }} Remove notification for new versions.</label><br> <label for="{{ form.removeNewVersionNotif.id_for_label }}">{{ form.removeNewVersionNotif }} Remove notification for new versions.</label><br>
</div> </div>
<div class="section"> <div class="section">
<h2><i class="fas fa-cog"></i> Other</h2> <h2><i class="fas fa-cog"></i> Other</h2>
<label for="{{ form.removeWallpaper.id_for_label }}">{{ form.removeWallpaper }} Remove wallpaper during incoming sessions</label><br> <label for="{{ form.removeWallpaper.id_for_label }}">{{ form.removeWallpaper }} Remove wallpaper during incoming sessions</label><br>
<a href="https://rustdesk.com/docs/en/self-host/client-configuration/advanced-settings/">Click here for a list of Default/Override settings</a>
<label for="{{ form.defaultManual.id_for_label }}">Default settings</label><br> <label for="{{ form.defaultManual.id_for_label }}">Default settings</label><br>
{{ form.defaultManual }}<br><br> {{ form.defaultManual }}<br><br>
<label for="{{ form.overrideManual.id_for_label }}">Override settings</label><br> <label for="{{ form.overrideManual.id_for_label }}">Override settings</label><br>
@@ -297,10 +382,24 @@
<div class="platform"> <div class="platform">
<div class="section"> <div class="section">
<button type="submit"><i class="fas fa-rocket"></i> Generate Custom Client</button> <button type="submit"><i class="fas fa-rocket"></i> Generate Custom Client</button>
<a href="https://github.com/bryangerlach/rdgen">Source Code on github</a>
<iframe src="https://github.com/sponsors/bryangerlach/button" title="Sponsor bryangerlach" height="32" width="114" style="border: 0; border-radius: 6px;"></iframe>
</div> </div>
</div> </div>
<div style="text-align: center; margin: 30px 0;">
<a href="https://github.com/bryangerlach/rdgen"
target="_blank"
class="sponsor-button">
<i class="fab fa-github"></i>
Source Code on Github
</a>
</div>
<div style="text-align: center; margin: 30px 0;">
<a href="https://github.com/sponsors/bryangerlach?o=esb"
target="_blank"
class="sponsor-button">
<i class="fab fa-github"></i>
Donate
</a>
</div>
</form> </form>
<script> <script>
document.querySelectorAll('.platform-icon').forEach(icon => { document.querySelectorAll('.platform-icon').forEach(icon => {
@@ -316,6 +415,98 @@
document.getElementById("{{ form.logofile.id_for_label }}").addEventListener('change', function(event) { document.getElementById("{{ form.logofile.id_for_label }}").addEventListener('change', function(event) {
previewImage(event.target, 'logo-preview'); previewImage(event.target, 'logo-preview');
}); });
document.getElementById("{{ form.hidecm.id_for_label }}").addEventListener('change',function() {
if (this.checked) {
document.getElementById("passwordRequirement").style.display = 'block';
document.getElementById("{{ form.permanentPassword.id_for_label }}").focus();
document.getElementById("{{ form.passApproveMode.id_for_label }}").value = 'password';
} else {
document.getElementById("passwordRequirement").style.display = 'none';
document.getElementById("{{ form.passApproveMode.id_for_label }}").value = 'password-click';
}
});
const enableKeyboard = document.getElementById("{{ form.enableKeyboard.id_for_label }}");
const enableClipboard = document.getElementById("{{ form.enableClipboard.id_for_label }}");
const enableFileTransfer = document.getElementById("{{ form.enableFileTransfer.id_for_label }}");
const enableAudio = document.getElementById("{{ form.enableAudio.id_for_label }}");
const enableTCP = document.getElementById("{{ form.enableTCP.id_for_label }}");
const enableRemoteRestart = document.getElementById("{{ form.enableRemoteRestart.id_for_label }}");
const enableRecording = document.getElementById("{{ form.enableRecording.id_for_label }}");
const enableBlockingInput = document.getElementById("{{ form.enableBlockingInput.id_for_label }}");
const enableRemoteModi = document.getElementById("{{ form.enableRemoteModi.id_for_label }}");
const enablePrinter = document.getElementById("{{ form.enablePrinter.id_for_label }}");
const enableCamera = document.getElementById("{{ form.enableCamera.id_for_label }}");
const enableTerminal = document.getElementById("{{ form.enableTerminal.id_for_label }}");
document.getElementById("{{ form.permissionsType.id_for_label }}").addEventListener('change', function() {
if (this.value === 'full') {
enableKeyboard.checked = true;
enableClipboard.checked = true;
enableFileTransfer.checked = true;
enableAudio.checked = true;
enableTCP.checked = true;
enableRemoteRestart.checked = true;
enableRecording.checked = true;
enableBlockingInput.checked = true;
enableRemoteModi.checked = true;
enablePrinter.checked = true;
enableCamera.checked = true;
enableTerminal.checked = true;
enableKeyboard.disabled = true;
enableClipboard.disabled = true;
enableFileTransfer.disabled = true;
enableAudio.disabled = true;
enableTCP.disabled = true;
enableRemoteRestart.disabled = true;
enableRecording.disabled = true;
enableBlockingInput.disabled = true;
enableRemoteModi.disabled = true;
enablePrinter.disabled = true;
enableCamera.disabled = true;
enableTerminal.disable = true;
} else if (this.value === 'view') {
enableKeyboard.checked = false;
enableClipboard.checked = false;
enableFileTransfer.checked = false;
enableAudio.checked = false;
enableTCP.checked = false;
enableRemoteRestart.checked = false;
enableRecording.checked = false;
enableBlockingInput.checked = false;
enableRemoteModi.checked = false;
enablePrinter.checked = false;
enableCamera.checked = false;
enableTerminal.checked = false;
enableKeyboard.disabled = true;
enableClipboard.disabled = true;
enableFileTransfer.disabled = true;
enableAudio.disabled = true;
enableTCP.disabled = true;
enableRemoteRestart.disabled = true;
enableRecording.disabled = true;
enableBlockingInput.disabled = true;
enableRemoteModi.disabled = true;
enablePrinter.disabled = true;
enableCamera.disabled = true;
enableTerminal.disable = true;
} else if (this.value === 'custom') {
enableKeyboard.disabled = false;
enableClipboard.disabled = false;
enableFileTransfer.disabled = false;
enableAudio.disabled = false;
enableTCP.disabled = false;
enableRemoteRestart.disabled = false;
enableRecording.disabled = false;
enableBlockingInput.disabled = false;
enableRemoteModi.disabled = false;
enablePrinter.checked = false;
enableCamera.checked = false;
enableTerminal.checked = false;
}
});
function previewImage(input, previewContainerId) { function previewImage(input, previewContainerId) {
if (input.files && input.files[0]) { if (input.files && input.files[0]) {
var reader = new FileReader(); var reader = new FileReader();

View File

@@ -0,0 +1,60 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Rustdesk Client Generator</title>
<style>
html, body {
height: 100%;
}
body {
background-color: #fff;
background: radial-gradient(circle at center, #fff 0%, #f8f8f8 75%, #ebebeb 100%);
color: #222;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
font-size: 1rem;
line-height: 1.5;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
main {
padding: 1rem;
text-align: center;
}
h1 {
font-size: 2.5rem;
line-height: 1.1;
margin: 0;
}
@media screen and (max-width: 480px) {
h1 {
font-size: 1.5rem;
}
}
h1::after {
content: "";
background-color: #ffe800;
background: repeating-linear-gradient(45deg, #ffe800, #ffe800 0.5rem, #222 0.5rem, #222 1.0rem);
display: block;
height: 0.5rem;
margin-top: 1rem;
}
img {
max-width: 100%;
height: auto;
}
p {
margin: 1rem 0 0 0;
}
</style>
</head>
<body>
<main>
<h1>Rustdesk Client Generator</h1>
<p>The Rustdesk Client Generator is currently under construction, please come back at a later time.</p>
</main>
</body>
</html>

View File

@@ -154,6 +154,7 @@
const platform = '{{platform}}'.toLowerCase(); const platform = '{{platform}}'.toLowerCase();
const platformLogos = { const platformLogos = {
'windows': document.getElementById('windowsLogo'), 'windows': document.getElementById('windowsLogo'),
'windows-x86': document.getElementById('windowsLogo'),
'macos': document.getElementById('macosLogo'), 'macos': document.getElementById('macosLogo'),
'linux': document.getElementById('linuxLogo'), 'linux': document.getElementById('linuxLogo'),
'android': document.getElementById('androidLogo') 'android': document.getElementById('androidLogo')
@@ -167,7 +168,7 @@
document.getElementById('pageTitle').textContent = 'Generating MacOS Build'; document.getElementById('pageTitle').textContent = 'Generating MacOS Build';
platformLogos.macos.style.display = 'block'; platformLogos.macos.style.display = 'block';
document.getElementById('macosNote').style.display = 'block'; document.getElementById('macosNote').style.display = 'block';
} else if (platform === 'windows') { } else if (platform === 'windows' | platform === 'windows-x86') {
document.getElementById('pageTitle').textContent = 'Generating Windows Build'; document.getElementById('pageTitle').textContent = 'Generating Windows Build';
platformLogos.windows.style.display = 'block'; platformLogos.windows.style.display = 'block';
} else if (platform === 'linux') { } else if (platform === 'linux') {
@@ -214,4 +215,4 @@
}, 5000); // 5000 milliseconds = 5 seconds }, 5000); // 5000 milliseconds = 5 seconds
</script> </script>
</body> </body>
</html> </html>

View File

@@ -15,6 +15,8 @@ from .forms import GenerateForm
from .models import GithubRun from .models import GithubRun
from PIL import Image from PIL import Image
from urllib.parse import quote from urllib.parse import quote
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
def generator_view(request): def generator_view(request):
if request.method == 'POST': if request.method == 'POST':
@@ -50,10 +52,14 @@ def generator_view(request):
compname = form.cleaned_data['compname'] compname = form.cleaned_data['compname']
if not compname: if not compname:
compname = "Purslane Ltd" compname = "Purslane Ltd"
androidappid = form.cleaned_data['androidappid']
if not androidappid:
androidappid = "com.carriez.flutter_hbb"
compname = compname.replace("&","\\&")
permPass = form.cleaned_data['permanentPassword'] permPass = form.cleaned_data['permanentPassword']
theme = form.cleaned_data['theme'] theme = form.cleaned_data['theme']
themeDorO = form.cleaned_data['themeDorO'] themeDorO = form.cleaned_data['themeDorO']
runasadmin = form.cleaned_data['runasadmin'] #runasadmin = form.cleaned_data['runasadmin']
passApproveMode = form.cleaned_data['passApproveMode'] passApproveMode = form.cleaned_data['passApproveMode']
denyLan = form.cleaned_data['denyLan'] denyLan = form.cleaned_data['denyLan']
enableDirectIP = form.cleaned_data['enableDirectIP'] enableDirectIP = form.cleaned_data['enableDirectIP']
@@ -73,6 +79,9 @@ def generator_view(request):
removeWallpaper = form.cleaned_data['removeWallpaper'] removeWallpaper = form.cleaned_data['removeWallpaper']
defaultManual = form.cleaned_data['defaultManual'] defaultManual = form.cleaned_data['defaultManual']
overrideManual = form.cleaned_data['overrideManual'] overrideManual = form.cleaned_data['overrideManual']
enablePrinter = form.cleaned_data['enablePrinter']
enableCamera = form.cleaned_data['enableCamera']
enableTerminal = form.cleaned_data['enableTerminal']
if all(char.isascii() for char in filename): if all(char.isascii() for char in filename):
filename = re.sub(r'[^\w\s-]', '_', filename).strip() filename = re.sub(r'[^\w\s-]', '_', filename).strip()
@@ -118,14 +127,18 @@ def generator_view(request):
decodedCustom['password'] = permPass decodedCustom['password'] = permPass
if theme != "system": if theme != "system":
if themeDorO == "default": if themeDorO == "default":
decodedCustom['default-settings']['theme'] = theme if platform == "windows-x86":
decodedCustom['default-settings']['allow-darktheme'] = 'Y' if theme == "dark" else 'N'
else:
decodedCustom['default-settings']['theme'] = theme
elif themeDorO == "override": elif themeDorO == "override":
decodedCustom['override-settings']['theme'] = theme if platform == "windows-x86":
decodedCustom['approve-mode'] = passApproveMode decodedCustom['override-settings']['allow-darktheme'] = 'Y' if theme == "dark" else 'N'
else:
decodedCustom['override-settings']['theme'] = theme
decodedCustom['enable-lan-discovery'] = 'N' if denyLan else 'Y' decodedCustom['enable-lan-discovery'] = 'N' if denyLan else 'Y'
decodedCustom['direct-server'] = 'Y' if enableDirectIP else 'N' #decodedCustom['direct-server'] = 'Y' if enableDirectIP else 'N'
decodedCustom['allow-auto-disconnect'] = 'Y' if autoClose else 'N' decodedCustom['allow-auto-disconnect'] = 'Y' if autoClose else 'N'
decodedCustom['allow-remove-wallpaper'] = 'Y' if removeWallpaper else 'N'
if permissionsDorO == "default": if permissionsDorO == "default":
decodedCustom['default-settings']['access-mode'] = permissionsType decodedCustom['default-settings']['access-mode'] = permissionsType
decodedCustom['default-settings']['enable-keyboard'] = 'Y' if enableKeyboard else 'N' decodedCustom['default-settings']['enable-keyboard'] = 'Y' if enableKeyboard else 'N'
@@ -137,6 +150,14 @@ def generator_view(request):
decodedCustom['default-settings']['enable-record-session'] = 'Y' if enableRecording else 'N' decodedCustom['default-settings']['enable-record-session'] = 'Y' if enableRecording else 'N'
decodedCustom['default-settings']['enable-block-input'] = 'Y' if enableBlockingInput else 'N' decodedCustom['default-settings']['enable-block-input'] = 'Y' if enableBlockingInput else 'N'
decodedCustom['default-settings']['allow-remote-config-modification'] = 'Y' if enableRemoteModi else 'N' decodedCustom['default-settings']['allow-remote-config-modification'] = 'Y' if enableRemoteModi else 'N'
decodedCustom['default-settings']['direct-server'] = 'Y' if enableDirectIP else 'N'
decodedCustom['default-settings']['verification-method'] = 'use-permanent-password' if hidecm else 'use-both-passwords'
decodedCustom['default-settings']['approve-mode'] = passApproveMode
decodedCustom['default-settings']['allow-hide-cm'] = 'Y' if hidecm else 'N'
decodedCustom['default-settings']['allow-remove-wallpaper'] = 'Y' if removeWallpaper else 'N'
decodedCustom['default-settings']['enable-remote-printer'] = 'Y' if enablePrinter else 'N'
decodedCustom['default-settings']['enable-camera'] = 'Y' if enableCamera else 'N'
decodedCustom['default-settings']['enable-terminal'] = 'Y' if enableTerminal else 'N'
else: else:
decodedCustom['override-settings']['access-mode'] = permissionsType decodedCustom['override-settings']['access-mode'] = permissionsType
decodedCustom['override-settings']['enable-keyboard'] = 'Y' if enableKeyboard else 'N' decodedCustom['override-settings']['enable-keyboard'] = 'Y' if enableKeyboard else 'N'
@@ -148,6 +169,14 @@ def generator_view(request):
decodedCustom['override-settings']['enable-record-session'] = 'Y' if enableRecording else 'N' decodedCustom['override-settings']['enable-record-session'] = 'Y' if enableRecording else 'N'
decodedCustom['override-settings']['enable-block-input'] = 'Y' if enableBlockingInput else 'N' decodedCustom['override-settings']['enable-block-input'] = 'Y' if enableBlockingInput else 'N'
decodedCustom['override-settings']['allow-remote-config-modification'] = 'Y' if enableRemoteModi else 'N' decodedCustom['override-settings']['allow-remote-config-modification'] = 'Y' if enableRemoteModi else 'N'
decodedCustom['override-settings']['direct-server'] = 'Y' if enableDirectIP else 'N'
decodedCustom['override-settings']['verification-method'] = 'use-permanent-password' if hidecm else 'use-both-passwords'
decodedCustom['override-settings']['approve-mode'] = passApproveMode
decodedCustom['override-settings']['allow-hide-cm'] = 'Y' if hidecm else 'N'
decodedCustom['override-settings']['allow-remove-wallpaper'] = 'Y' if removeWallpaper else 'N'
decodedCustom['override-settings']['enable-remote-printer'] = 'Y' if enablePrinter else 'N'
decodedCustom['override-settings']['enable-camera'] = 'Y' if enableCamera else 'N'
decodedCustom['override-settings']['enable-terminal'] = 'Y' if enableTerminal else 'N'
for line in defaultManual.splitlines(): for line in defaultManual.splitlines():
k, value = line.split('=') k, value = line.split('=')
@@ -166,7 +195,7 @@ def generator_view(request):
#github limits inputs to 10, so lump extras into one with json #github limits inputs to 10, so lump extras into one with json
extras = {} extras = {}
extras['genurl'] = _settings.GENURL extras['genurl'] = _settings.GENURL
extras['runasadmin'] = runasadmin #extras['runasadmin'] = runasadmin
extras['urlLink'] = urlLink extras['urlLink'] = urlLink
extras['downloadLink'] = downloadLink extras['downloadLink'] = downloadLink
extras['delayFix'] = 'true' if delayFix else 'false' extras['delayFix'] = 'true' if delayFix else 'false'
@@ -174,16 +203,18 @@ def generator_view(request):
extras['rdgen'] = 'true' extras['rdgen'] = 'true'
extras['cycleMonitor'] = 'true' if cycleMonitor else 'false' extras['cycleMonitor'] = 'true' if cycleMonitor else 'false'
extras['xOffline'] = 'true' if xOffline else 'false' extras['xOffline'] = 'true' if xOffline else 'false'
extras['hidecm'] = 'true' if hidecm else 'false'
extras['removeNewVersionNotif'] = 'true' if removeNewVersionNotif else 'false' extras['removeNewVersionNotif'] = 'true' if removeNewVersionNotif else 'false'
extras['compname'] = compname extras['compname'] = compname
extras['androidappid'] = androidappid
extra_input = json.dumps(extras) extra_input = json.dumps(extras)
####from here run the github action, we need user, repo, access token. ####from here run the github action, we need user, repo, access token.
if platform == 'windows': if platform == 'windows':
url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-windows.yml/dispatches' url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-windows.yml/dispatches'
if platform == 'windows-x86':
url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-windows-x86.yml/dispatches'
elif platform == 'linux': elif platform == 'linux':
url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-linux.yml/dispatches' url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-linux.yml/dispatches'
elif platform == 'android': elif platform == 'android':
url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-android.yml/dispatches' url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-android.yml/dispatches'
elif platform == 'macos': elif platform == 'macos':
@@ -200,8 +231,6 @@ def generator_view(request):
"apiServer":apiServer, "apiServer":apiServer,
"custom":encodedCustom, "custom":encodedCustom,
"uuid":myuuid, "uuid":myuuid,
#"iconbase64":iconbase64.decode("utf-8"),
#"logobase64":logobase64.decode("utf-8") if logobase64 else "",
"iconlink":iconlink, "iconlink":iconlink,
"logolink":logolink, "logolink":logolink,
"appname":appname, "appname":appname,
@@ -219,12 +248,13 @@ def generator_view(request):
create_github_run(myuuid) create_github_run(myuuid)
response = requests.post(url, json=data, headers=headers) response = requests.post(url, json=data, headers=headers)
print(response) print(response)
if response.status_code == 204: if response.status_code == 204 or response.status_code == 200:
return render(request, 'waiting.html', {'filename':filename, 'uuid':myuuid, 'status':"Starting generator...please wait", 'platform':platform}) return render(request, 'waiting.html', {'filename':filename, 'uuid':myuuid, 'status':"Starting generator...please wait", 'platform':platform})
else: else:
return JsonResponse({"error": "Something went wrong"}) return JsonResponse({"error": "Something went wrong"})
else: else:
form = GenerateForm() form = GenerateForm()
#return render(request, 'maintenance.html')
return render(request, 'generator.html', {'form': form}) return render(request, 'generator.html', {'form': form})
@@ -386,4 +416,4 @@ def save_custom_client(request):
for chunk in file.chunks(): for chunk in file.chunks():
f.write(chunk) f.write(chunk)
return HttpResponse("File saved successfully!") return HttpResponse("File saved successfully!")

View File

@@ -1,4 +1,5 @@
django django
requests requests
pillow pillow
gunicorn gunicorn
cryptography>=42.0.0