17 Commits

Author SHA1 Message Date
dijunkun
911dce2e71 [feat] optimize certificate selection table 2025-10-24 17:39:25 +08:00
dijunkun
9f80d4f69d Merge branch 'self-hosted-server' into run-in-bg 2025-10-24 14:16:18 +08:00
dijunkun
cba644f055 [fix] fix TURN server authentication credentials, fixes #8 2025-10-24 11:41:23 +08:00
dijunkun
f733fe9e49 Merge branch 'self-hosted-server' into run-in-bg 2025-10-24 11:05:07 +08:00
dijunkun
27263fe1db [ci] fix permission issue in close inactive issues script by updating token usage 2025-10-24 10:57:11 +08:00
dijunkun
698bf72a6c Merge branch 'self-hosted-server' into run-in-bg 2025-10-24 10:05:54 +08:00
dijunkun
0bd27d0b17 [ci] use GITHUB_SHORT_SHA instead of build number in version 2025-10-24 02:09:50 +08:00
dijunkun
ee5612da8b [ci] resolve compilation issue 2025-10-23 23:30:52 +08:00
dijunkun
c7a2023c88 [ci] add build ID to version number 2025-10-23 23:18:44 +08:00
dijunkun
c031a8c145 [fix] adjust settings window height for different platforms 2025-10-23 23:04:31 +08:00
dijunkun
0bf83f07ad [fix] correct version display in about window 2025-10-23 23:01:38 +08:00
dijunkun
3638b712bd [ci] update close-issue.yml 2025-10-23 21:20:10 +08:00
dijunkun
17f9536476 [chore] update README 2025-10-23 10:37:45 +08:00
dijunkun
0ef51e3faf [feat] add FAQ.md 2025-10-23 10:33:39 +08:00
dijunkun
cccf5dadb2 Merge branch 'run-in-bg' into self-hosted-server 2025-10-22 17:23:08 +08:00
dijunkun
c7411b59f1 [chore] update README 2025-10-21 22:51:21 +08:00
dijunkun
8222782522 [chore] update README 2025-10-21 20:54:37 +08:00
13 changed files with 2857 additions and 2736 deletions

View File

@@ -34,10 +34,11 @@ jobs:
shell: bash
id: set_deb_version
run: |
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
if [[ ! "${VERSION_NUM}" =~ ^[0-9] ]]; then
LEGAL_VERSION="0.0.0-${VERSION_NUM}"
LEGAL_VERSION="0.0.0-${VERSION_NUM}-${SHORT_SHA}"
else
LEGAL_VERSION="${VERSION_NUM}"
LEGAL_VERSION="${VERSION_NUM}-${SHORT_SHA}"
fi
echo "LEGAL_VERSION=${LEGAL_VERSION}" >> $GITHUB_ENV
@@ -52,6 +53,7 @@ jobs:
XMAKE_GLOBALDIR: /data
run: |
ls -la $XMAKE_GLOBALDIR
xmake f --CROSSDESK_VERSION=${LEGAL_VERSION} --root -y
xmake b -vy --root crossdesk
- name: Decode and save certificate
@@ -96,10 +98,11 @@ jobs:
shell: bash
id: set_deb_version
run: |
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
if [[ ! "${VERSION_NUM}" =~ ^[0-9] ]]; then
LEGAL_VERSION="0.0.0-${VERSION_NUM}"
LEGAL_VERSION="0.0.0-${VERSION_NUM}-${SHORT_SHA}"
else
LEGAL_VERSION="${VERSION_NUM}"
LEGAL_VERSION="${VERSION_NUM}-${SHORT_SHA}"
fi
echo "LEGAL_VERSION=${LEGAL_VERSION}" >> $GITHUB_ENV
@@ -113,6 +116,7 @@ jobs:
CUDA_PATH: /usr/local/cuda
XMAKE_GLOBALDIR: /data
run: |
xmake f --CROSSDESK_VERSION=${LEGAL_VERSION} --root -y
xmake b -vy --root crossdesk
- name: Decode and save certificate
@@ -155,7 +159,8 @@ jobs:
id: version
run: |
VERSION="${GITHUB_REF##*/}"
VERSION_NUM="${VERSION#v}"
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
VERSION_NUM="${VERSION#v}-${SHORT_SHA}"
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_ENV
echo "VERSION_NUM=${VERSION_NUM}"
@@ -177,7 +182,9 @@ jobs:
run: git submodule update --init --recursive
- name: Build CrossDesk
run: xmake b -vy crossdesk
run: |
xmake f --CROSSDESK_VERSION=${VERSION_NUM} -y
xmake b -vy crossdesk
- name: Decode and save certificate
shell: bash
@@ -215,7 +222,8 @@ jobs:
$version = $ref -replace '^refs/(tags|heads)/', ''
$version = $version -replace '^v', ''
$version = $version -replace '/', '-'
echo "VERSION_NUM=$version" >> $env:GITHUB_ENV
$SHORT_SHA = $env:GITHUB_SHA.Substring(0,7)
echo "VERSION_NUM=$version-$SHORT_SHA" >> $env:GITHUB_ENV
- name: Cache xmake dependencies
uses: actions/cache@v4
@@ -281,8 +289,10 @@ jobs:
copy "${{ github.workspace }}\scripts\windows\nsProcess.dll" $nsisPluginDir
- name: Build CrossDesk
run: xmake b -vy crossdesk
run: |
xmake f --CROSSDESK_VERSION=${{ env.VERSION_NUM }} -y
xmake b -vy crossdesk
- name: Decode and save certificate
shell: powershell
run: |
@@ -321,7 +331,8 @@ jobs:
id: version
run: |
VERSION="${GITHUB_REF##*/}"
VERSION_NUM="${VERSION#v}"
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
VERSION_NUM="${VERSION#v}-${SHORT_SHA}"
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_OUTPUT
- name: Rename artifacts

View File

@@ -17,26 +17,51 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
per_page: 100,
});
const now = new Date().getTime();
const inactivePeriod = 7 * 24 * 60 * 60 * 1000; // 7 days
for (const issue of issues) {
const lastUpdated = new Date(issue.updated_at).getTime();
// if the issue hasn't been updated in the past week, close it
if (now - lastUpdated > inactivePeriod && issue.labels.length === 0) {
console.log(`Closing inactive issue: ${issue.number} (No labels)`);
// skip pull requests (they are also returned by listForRepo)
if (issue.pull_request) continue;
// skip labeled issues
if (issue.labels.length > 0) {
console.log(`Skipping issue #${issue.number} (Has labels).`);
continue;
}
// fetch comments for this issue
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
per_page: 100,
});
// determine the "last activity" time
let lastActivityTime;
if (comments.length > 0) {
const lastComment = comments[comments.length - 1];
lastActivityTime = new Date(lastComment.updated_at).getTime();
} else {
lastActivityTime = new Date(issue.created_at).getTime();
}
// check inactivity
if (now - lastActivityTime > inactivePeriod) {
console.log(`Closing inactive issue: #${issue.number} (No recent replies for 7 days)`);
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed',
});
} else if (issue.labels.length === 0) {
console.log(`Skipping issue ${issue.number} (No labels) as it has been recently updated.`);
} else {
console.log(`Skipping issue ${issue.number} (Has labels).`);
console.log(`Skipping issue #${issue.number} (Active within 7 days).`);
}
}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -15,8 +15,9 @@ jobs:
- name: Set version number
id: version
run: |
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
VERSION_NUM="${GITHUB_REF##*/}"
VERSION_NUM="${VERSION_NUM#v}"
VERSION_NUM="${VERSION_NUM#v}-${SHORT_SHA}"
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_ENV
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_OUTPUT

View File

@@ -3,7 +3,7 @@
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)]()
[![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
[![GitHub last commit](https://img.shields.io/github/last-commit/kunkundi/crossdesk)](https://github.com/kunkundi/crossdesk/commits/self-hosted-server)
[![Build Status](https://github.com/kunkundi/crossdesk/actions/workflows/build.yaml/badge.svg)](https://github.com/kunkundi/crossdesk/actions)
[![Build Status](https://github.com/kunkundi/crossdesk/actions/workflows/build.yml/badge.svg)](https://github.com/kunkundi/crossdesk/actions)
[![Docker Pulls](https://img.shields.io/docker/pulls/crossdesk/crossdesk-server)](https://hub.docker.com/r/crossdesk/crossdesk-server/tags)
[![GitHub issues](https://img.shields.io/github/issues/kunkundi/crossdesk.svg)]()
[![GitHub stars](https://img.shields.io/github/stars/kunkundi/crossdesk.svg?style=social)]()
@@ -65,7 +65,7 @@ xmake r crossdesk
### 无 CUDA 环境下的开发支持
对于未安装 **CUDA 环境** 的 Linux 开发者,这里提供了预配置的 [Ubuntu 22.04 Docker 镜像](https://hub.docker.com/r/crossdesk/ubuntu22.04)。该镜像内置必要的构建依赖,可在容器中开箱即用,无需额外配置即可直接编译项目。
对于**未安装 CUDA 环境的 Linux 开发者**,这里提供了预配置的 [Ubuntu 22.04 Docker 镜像](https://hub.docker.com/r/crossdesk/ubuntu22.04)。该镜像内置必要的构建依赖,可在容器中开箱即用,无需额外配置即可直接编译项目。
进入容器,下载工程后执行:
```
@@ -75,7 +75,7 @@ export XMAKE_GLOBALDIR=/data
xmake b --root -vy crossdesk
```
对于未安装 **CUDA 环境** 的 Windows 开发者,执行下面的命令安装 CUDA 编译环境:
对于**未安装 CUDA 环境的 Windows 开发者**,执行下面的命令安装 CUDA 编译环境:
```
xmake require -vy "cuda 12.6.3"
```
@@ -295,3 +295,6 @@ Generation complete. Deployment files::
7. 勾选使用**自托管服务器配置**,点击确认配置生效。<br><br>
<img width="600" height="160" alt="image" src="https://github.com/user-attachments/assets/1e455dc3-4087-4f37-a544-1ff9f8789383" /><br><br>
# 常见问题
见 [常见问题](https://github.com/kunkundi/crossdesk/blob/self-hosted-server/docs/FAQ.md) 。

View File

@@ -3,7 +3,7 @@
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)]()
[![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
[![GitHub last commit](https://img.shields.io/github/last-commit/kunkundi/crossdesk)](https://github.com/kunkundi/crossdesk/commits/self-hosted-server)
[![Build Status](https://github.com/kunkundi/crossdesk/actions/workflows/build.yaml/badge.svg)](https://github.com/kunkundi/crossdesk/actions)
[![Build Status](https://github.com/kunkundi/crossdesk/actions/workflows/build.yml/badge.svg)](https://github.com/kunkundi/crossdesk/actions)
[![Docker Pulls](https://img.shields.io/docker/pulls/crossdesk/crossdesk-server)](https://hub.docker.com/r/crossdesk/crossdesk-server/tags)
[![GitHub issues](https://img.shields.io/github/issues/kunkundi/crossdesk.svg)]()
[![GitHub stars](https://img.shields.io/github/stars/kunkundi/crossdesk.svg?style=social)]()
@@ -65,7 +65,7 @@ xmake r crossdesk
#### Development Without CUDA Environment
For **Linux** developers who do not have a **CUDA environment** installed, a preconfigured [Ubuntu 22.04 Docker image](https://hub.docker.com/r/crossdesk/ubuntu22.04) is provided.
For **Linux developers who do not have a CUDA environment** installed, a preconfigured [Ubuntu 22.04 Docker image](https://hub.docker.com/r/crossdesk/ubuntu22.04) is provided.
This image comes with all required build dependencies and allows you to build the project directly inside the container without any additional setup.
After entering the container, download the project and run:
@@ -76,7 +76,7 @@ export XMAKE_GLOBALDIR=/data
xmake b --root -vy crossdesk
```
For **Windows** developers without a **CUDA environment** installed, run the following command to install the CUDA build environment:
For **Windows developers without a CUDA environment** installed, run the following command to install the CUDA build environment:
```
xmake require -vy "cuda 12.6.3"
```
@@ -300,3 +300,6 @@ Place **crossdesk.cn.key** and **crossdesk.cn_bundle.crt** into the **/path/to/y
4. Check the option to use **Self-Hosted Server Configuration**.<br><br>
<img width="600" height="160" alt="image" src="https://github.com/user-attachments/assets/1e455dc3-4087-4f37-a544-1ff9f8789383" /><br><br>
# FAQ
See [FAQ](https://github.com/kunkundi/crosssesk/blob/self-hosted-server/docs/FAQ.md) .

33
docs/FAQ.md Normal file
View File

@@ -0,0 +1,33 @@
# 常见问题FAQ
欢迎来到 **CrossDesk 常见问题** 页面!
这里整理了用户和开发者最常见的一些疑问。如果你没有找到答案,欢迎在 [Issues](https://github.com/kunkundi/crossdesk/issues) 中反馈。
---
### Q1. 对等连接失败
**A:**
打开设置,勾选 **启用中继服务** 选项,尝试重新发起连接。
<img width="396" height="306" alt="Image" src="https://github.com/user-attachments/assets/fd8db148-c782-4f4d-b874-8f1b2a7ec7d6" />
由于公共中继服务器带宽较小,连接的清晰度流畅度可能会下降,建议自建服务器。 [Issue #8](https://github.com/kunkundi/crossdesk/issues/8)
### Q2. Windows 无 CUDA 环境下编译
**A:**
运行下面的命令安装 CUDA 编译环境。
```
xmake require -vy "cuda 12.6.3"
```
安装完成后执行
```
xmake require --info "cuda 12.6.3"
```
输出如下
<img width="860" height="226" alt="Image" src="https://github.com/user-attachments/assets/999ac365-581a-4b9a-806e-05eb3e4cf44d" />
根据上述输出获取到 CUDA 的安装目录,即 installdir 指向的位置。将 CUDA_PATH 加入系统环境变量,或在终端中输入 set CUDA_PATH=path_to_cuda_installdir重新执行 xmake b -vy crossdesk 即可。
[Issue #6](https://github.com/kunkundi/crossdesk/issues/6)
---

File diff suppressed because it is too large Load Diff

View File

@@ -20,8 +20,13 @@
#define INPUT_WINDOW_PADDING_EN 96
#define SETTINGS_WINDOW_WIDTH_CN 202
#define SETTINGS_WINDOW_WIDTH_EN 248
#if _WIN32
#define SETTINGS_WINDOW_HEIGHT_CN 345
#define SETTINGS_WINDOW_HEIGHT_EN 345
#else
#define SETTINGS_WINDOW_HEIGHT_CN 315
#define SETTINGS_WINDOW_HEIGHT_EN 315
#endif
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_CN 228
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_WIDTH_EN 275
#define SELF_HOSTED_SERVER_CONFIG_WINDOW_HEIGHT_CN 165

View File

@@ -453,10 +453,10 @@ int Render::CreateConnectionPeer() {
sizeof(params_.turn_server_ip) - 1);
params_.turn_server_ip[sizeof(params_.turn_server_ip) - 1] = '\0';
params_.turn_server_port = 3478;
strncpy((char*)params_.turn_server_username, "dijunkun",
strncpy((char*)params_.turn_server_username, "crossdesk",
sizeof(params_.turn_server_username) - 1);
params_.turn_server_username[sizeof(params_.turn_server_username) - 1] = '\0';
strncpy((char*)params_.turn_server_password, "dijunkunpw",
strncpy((char*)params_.turn_server_password, "crossdeskpw",
sizeof(params_.turn_server_password) - 1);
params_.turn_server_password[sizeof(params_.turn_server_password) - 1] = '\0';
strncpy(params_.tls_cert_path, server_cert_path.c_str(),

View File

@@ -341,8 +341,8 @@ class Render {
float connection_status_window_height_ = 150;
float notification_window_width_ = 200;
float notification_window_height_ = 80;
float about_window_width_ = 200;
float about_window_height_ = 150;
float about_window_width_ = 300;
float about_window_height_ = 170;
int screen_width_ = 1280;
int screen_height_ = 720;
int selected_display_ = 0;
@@ -458,6 +458,7 @@ class Render {
bool self_hosted_server_config_window_pos_reset_ = true;
std::string selected_current_file_path_ = "";
std::string selected_file_ = "";
bool show_file_browser_ = true;
/* ------ main window property end ------ */
/* ------ sub stream window property start ------ */

View File

@@ -27,15 +27,21 @@ int Render::AboutWindow() {
ImGui::SetWindowFontScale(0.5f);
std::string version;
#ifdef RD_VERSION
version = RD_VERSION;
#ifdef CROSSDESK_VERSION
version = CROSSDESK_VERSION;
#else
version = "Unknown";
#endif
std::string text =
localization::version[localization_language_index_] + ": " + version;
std::string text = localization::version[localization_language_index_] +
": CrossDesk v" + version;
ImGui::Text("%s", text.c_str());
ImGui::Text("");
std::string copyright_text = "© 2025 by JUNKUN DI. All rights reserved.";
std::string license_text = "Licensed under GNU LGPL v3.";
ImGui::Text("%s", copyright_text.c_str());
ImGui::Text("%s", license_text.c_str());
ImGui::SetCursorPosX(about_window_width_ * 0.42f);
ImGui::SetCursorPosY(about_window_height_ * 0.75f);

View File

@@ -28,6 +28,11 @@ std::vector<std::string> GetRootEntries() {
int Render::ShowSimpleFileBrowser() {
std::string display_text;
if (selected_current_file_path_.empty()) {
selected_current_file_path_ = std::filesystem::current_path().string();
}
if (!selected_file_.empty()) {
display_text = std::filesystem::path(selected_file_).filename().string();
} else if (selected_current_file_path_ != "Root") {
@@ -43,62 +48,70 @@ int Render::ShowSimpleFileBrowser() {
localization::select_a_file[localization_language_index_].c_str();
}
// 设置固定宽度
// ImGui::SetNextItemWidth(SELF_HOSTED_SERVER_INPUT_WINDOW_WIDTH);
if (show_file_browser_) {
ImGui::PushItemFlag(ImGuiItemFlags_AutoClosePopups, false);
float fixed_width = 130.0f;
ImGui::SetNextItemWidth(fixed_width);
ImGui::SetNextWindowSizeConstraints(ImVec2(fixed_width, 0),
ImVec2(fixed_width, 100.0f));
if (ImGui::BeginCombo("##select_a_file", display_text.c_str(), 0)) {
bool file_selected = false;
ImGui::PushItemFlag(ImGuiItemFlags_AutoClosePopups, false); // 禁用自动关闭
if (ImGui::BeginCombo("##select_a_file", display_text.c_str())) {
bool file_selected = false;
if (selected_current_file_path_ == "Root" ||
!std::filesystem::exists(selected_current_file_path_) ||
!std::filesystem::is_directory(selected_current_file_path_)) {
auto roots = GetRootEntries();
for (const auto& root : roots) {
if (ImGui::Selectable(root.c_str())) {
selected_current_file_path_ = root;
selected_file_.clear();
}
}
} else {
std::filesystem::path p(selected_current_file_path_);
if (ImGui::Selectable("..")) {
if (p.has_parent_path() && p != p.root_path())
selected_current_file_path_ = p.parent_path().string();
else
selected_current_file_path_ = "Root";
selected_file_.clear();
}
try {
for (const auto& entry :
std::filesystem::directory_iterator(selected_current_file_path_)) {
std::string name = entry.path().filename().string();
if (entry.is_directory()) {
if (ImGui::Selectable(name.c_str())) {
selected_current_file_path_ = entry.path().string();
selected_file_.clear();
}
} else {
if (ImGui::Selectable(name.c_str())) {
selected_file_ = entry.path().string();
file_selected = true; // 记录选中文件
}
if (selected_current_file_path_ == "Root" ||
!std::filesystem::exists(selected_current_file_path_) ||
!std::filesystem::is_directory(selected_current_file_path_)) {
for (const auto& root : roots) {
if (ImGui::Selectable(root.c_str())) {
selected_current_file_path_ = root;
selected_file_.clear();
}
}
} catch (const std::exception& e) {
ImGui::TextColored(ImVec4(1, 0, 0, 1), "Error: %s", e.what());
}
}
} else {
std::filesystem::path p(selected_current_file_path_);
// 如果选中了文件,则自动关闭下拉框
if (file_selected) {
ImGui::EndCombo(); // 关闭下拉框
} else {
ImGui::EndCombo(); // 保持下拉框开启
if (ImGui::Selectable("..")) {
if (std::find(roots.begin(), roots.end(),
selected_current_file_path_) != roots.end()) {
selected_current_file_path_ = "Root";
} else if (p.has_parent_path()) {
selected_current_file_path_ = p.parent_path().string();
} else {
selected_current_file_path_ = "Root";
}
selected_file_.clear();
}
try {
for (const auto& entry : std::filesystem::directory_iterator(
selected_current_file_path_)) {
std::string name = entry.path().filename().string();
if (entry.is_directory()) {
if (ImGui::Selectable(name.c_str())) {
selected_current_file_path_ = entry.path().string();
selected_file_.clear();
}
} else {
if (ImGui::Selectable(name.c_str())) {
selected_file_ = entry.path().string();
file_selected = true;
show_file_browser_ = false;
}
}
}
} catch (const std::exception& e) {
ImGui::TextColored(ImVec4(1, 0, 0, 1), "Error: %s", e.what());
}
}
ImGui::EndCombo();
}
ImGui::PopItemFlag();
} else {
show_file_browser_ = true;
}
ImGui::PopItemFlag(); // 恢复默认行为
return 0;
}

View File

@@ -1,8 +1,11 @@
set_project("crossdesk")
set_license("LGPL-3.0")
set_version("0.0.1")
add_defines("RD_VERSION=\"0.0.1\"");
option("CROSSDESK_VERSION")
set_default("0.0.0")
set_showmenu(true)
set_description("Set CROSSDESK_VERSION for build")
option_end()
add_rules("mode.release", "mode.debug")
set_languages("c++17")
@@ -143,6 +146,7 @@ target("assets")
target("gui")
set_kind("object")
add_packages("libyuv")
add_defines("CROSSDESK_VERSION=\"" .. (get_config("CROSSDESK_VERSION") or "Unknown") .. "\"")
add_deps("rd_log", "common", "assets", "config_center", "minirtc",
"path_manager", "screen_capturer", "speaker_capturer",
"device_controller", "thumbnail")