mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-02-18 14:39:08 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad0a24ba23 |
15
README.md
15
README.md
@@ -1,6 +1,6 @@
|
||||
# RustDesk | Your Remote Desktop Software
|
||||
### RustDesk | Your Remote Desktop Software
|
||||
|
||||
The best open source remote desktop software written with Rust, out of the box, no configuration required, great alternative of TeamViewer and AnyDesk. You have full control of your data, no concerns about security. You can use our rendezvous/relay server, or [set up your own](https://rustdesk.com/blog/id-relay-set/), or write your own rendezvous/relay server.
|
||||
The best open source remote desktop software written with Rust.
|
||||
|
||||
[**BINARY DOWNLOAD**](https://github.com/rustdesk/rustdesk/releases)
|
||||
|
||||
@@ -33,14 +33,3 @@ Desktop versions use [sciter](https://sciter.com/) for GUI, please download scit
|
||||
- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: start a peer connection
|
||||
- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: Communicate with [rustdesk-server](https://github.com/rustdesk/rustdesk-server), wait for remote direct (TCP hole punching) or relayed connection
|
||||
- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: platform specific code
|
||||
|
||||
## Snapshot
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
2
build.rs
2
build.rs
@@ -1,6 +1,6 @@
|
||||
#[cfg(windows)]
|
||||
fn build_windows() {
|
||||
cc::Build::new().file("src/windows.cc").compile("windows");
|
||||
cc::Build::new().file("windows.cc").compile("windows");
|
||||
// println!("cargo:rustc-link-lib=WtsApi32");
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rerun-if-changed=windows.cc");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "hbb_common"
|
||||
version = "0.1.0"
|
||||
authors = ["rustdesk<info@rustdesk.com>"]
|
||||
authors = ["open-trade <info@opentradesolutions.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
118
oboe.cc
Normal file
118
oboe.cc
Normal file
@@ -0,0 +1,118 @@
|
||||
#include <oboe/Oboe.h>
|
||||
#include <math.h>
|
||||
#include <deque>
|
||||
#include <pthread.h>
|
||||
|
||||
// I got link problem with std::mutex, so use pthread instead
|
||||
class CThreadLock
|
||||
{
|
||||
public:
|
||||
CThreadLock();
|
||||
virtual ~CThreadLock();
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
private:
|
||||
pthread_mutex_t mutexlock;
|
||||
};
|
||||
|
||||
CThreadLock::CThreadLock()
|
||||
{
|
||||
// init lock here
|
||||
pthread_mutex_init(&mutexlock, 0);
|
||||
}
|
||||
|
||||
CThreadLock::~CThreadLock()
|
||||
{
|
||||
// deinit lock here
|
||||
pthread_mutex_destroy(&mutexlock);
|
||||
}
|
||||
void CThreadLock::Lock()
|
||||
{
|
||||
// lock
|
||||
pthread_mutex_lock(&mutexlock);
|
||||
}
|
||||
void CThreadLock::Unlock()
|
||||
{
|
||||
// unlock
|
||||
pthread_mutex_unlock(&mutexlock);
|
||||
}
|
||||
|
||||
class Player : public oboe::AudioStreamDataCallback
|
||||
{
|
||||
public:
|
||||
Player(int channels, int sample_rate)
|
||||
{
|
||||
this->channels = channels;
|
||||
oboe::AudioStreamBuilder builder;
|
||||
// The builder set methods can be chained for convenience.
|
||||
builder.setSharingMode(oboe::SharingMode::Exclusive)
|
||||
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
|
||||
->setChannelCount(channels)
|
||||
->setSampleRate(sample_rate)
|
||||
->setFormat(oboe::AudioFormat::Float)
|
||||
->setDataCallback(this)
|
||||
->openManagedStream(outStream);
|
||||
// Typically, start the stream after querying some stream information, as well as some input from the user
|
||||
outStream->requestStart();
|
||||
}
|
||||
|
||||
~Player() {
|
||||
outStream->requestStop();
|
||||
}
|
||||
|
||||
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override
|
||||
{
|
||||
float *floatData = (float *)audioData;
|
||||
int i = 0;
|
||||
mtx.Lock();
|
||||
auto n = channels * numFrames;
|
||||
for (; i < n && i < (int)buffer.size(); ++i, ++floatData)
|
||||
{
|
||||
*floatData = buffer.front();
|
||||
buffer.pop_front();
|
||||
}
|
||||
mtx.Unlock();
|
||||
for (; i < n; ++i, ++floatData)
|
||||
{
|
||||
*floatData = 0;
|
||||
}
|
||||
return oboe::DataCallbackResult::Continue;
|
||||
}
|
||||
|
||||
void push(const float *v, int n)
|
||||
{
|
||||
mtx.Lock();
|
||||
for (auto i = 0; i < n; ++i, ++v)
|
||||
buffer.push_back(*v);
|
||||
// in case memory overuse
|
||||
if (buffer.size() > 48 * 1024 * 120)
|
||||
buffer.clear();
|
||||
mtx.Unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
oboe::ManagedStream outStream;
|
||||
int channels;
|
||||
std::deque<float> buffer;
|
||||
CThreadLock mtx;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void *create_oboe_player(int channels, int sample_rate)
|
||||
{
|
||||
return new Player(channels, sample_rate);
|
||||
}
|
||||
|
||||
void push_oboe_data(void *player, const float* v, int n)
|
||||
{
|
||||
static_cast<Player *>(player)->push(v, n);
|
||||
}
|
||||
|
||||
void destroy_oboe_player(void *player)
|
||||
{
|
||||
delete static_cast<Player *>(player);
|
||||
}
|
||||
}
|
||||
@@ -634,20 +634,19 @@ fn get_error() -> String {
|
||||
}
|
||||
|
||||
pub fn get_active_username() -> String {
|
||||
use std::os::windows::process::CommandExt;
|
||||
let name = crate::username();
|
||||
if name != "SYSTEM" {
|
||||
return name;
|
||||
}
|
||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||
let mut cmd = std::process::Command::new("query");
|
||||
cmd.arg("user");
|
||||
cmd.creation_flags(CREATE_NO_WINDOW);
|
||||
if let Ok(output) = cmd.output() {
|
||||
if let Ok(output) = std::process::Command::new("query").arg("user").output() {
|
||||
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
||||
if let Some(name) = line.split_whitespace().next() {
|
||||
if name.starts_with(">") {
|
||||
return name.replace(">", "");
|
||||
if line.contains("Active") {
|
||||
if let Some(name) = line.split_whitespace().next() {
|
||||
if name.starts_with(">") {
|
||||
return name.replace(">", "");
|
||||
} else {
|
||||
return name.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class PortForward: Reactor.Component {
|
||||
});
|
||||
return <div #file-transfer><section>
|
||||
{pfs.length ? <div style="background: green; color: white; text-align: center; padding: 0.5em;">
|
||||
<span style="font-size: 1.2em">Listening ...</span><br/>
|
||||
<span style="font-size: 1.2em">Listenning ...</span><br/>
|
||||
<span style="font-size: 0.8em; color: #ddd">Don't close this window while your are using tunnel</span>
|
||||
</div> : ""}
|
||||
<table #port-forward>
|
||||
|
||||
@@ -1582,7 +1582,7 @@ impl Interface for Handler {
|
||||
pi_sciter.set_item("sas_enabled", pi.sas_enabled);
|
||||
if self.is_file_transfer() {
|
||||
if pi.username.is_empty() {
|
||||
self.on_error("No active user logged on, please connect and logon first.");
|
||||
self.on_error("No active console user logged on, please connect and logon first.");
|
||||
return;
|
||||
}
|
||||
} else if !self.is_port_forward() {
|
||||
|
||||
Reference in New Issue
Block a user