mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2026-01-30 19:15:17 +01:00
Compare commits
5 Commits
release-pr
...
v0.3.5-tor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27a14d1c32 | ||
|
|
a1b98efe3d | ||
|
|
510013d4fa | ||
|
|
fe4f295fcd | ||
|
|
1f809063ef |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -120,8 +120,8 @@ jobs:
|
||||
APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }}
|
||||
NO_STRIP: true
|
||||
with:
|
||||
tagName: v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version.
|
||||
releaseName: "Auto-release v__VERSION__"
|
||||
tagName: ${{ github.ref_name }} # the action automatically replaces \_\_VERSION\_\_ with the app version.
|
||||
releaseName: "Auto-release ${{ github.ref_name }}"
|
||||
releaseBody: "See the assets to download this version and install. This release was created automatically."
|
||||
releaseDraft: false
|
||||
prerelease: true
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
>
|
||||
<dt>
|
||||
<DisclosureButton
|
||||
class="flex w-full items-center justify-between text-left text-gray-900 dark:text-white"
|
||||
class="flex w-full items-center justify-between text-left text-white"
|
||||
>
|
||||
<span class="text-sm font-semibold font-display">{{
|
||||
nav.name
|
||||
@@ -73,9 +73,9 @@
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div class="truncate inline-flex items-center gap-x-2">
|
||||
<div class="flex flex-col gap-x-2">
|
||||
<p
|
||||
class="text-sm whitespace-nowrap font-display font-semibold"
|
||||
class="truncate text-sm whitespace-nowrap font-display font-semibold"
|
||||
>
|
||||
{{ item.label }}
|
||||
</p>
|
||||
|
||||
2
src-tauri/Cargo.lock
generated
2
src-tauri/Cargo.lock
generated
@@ -1339,7 +1339,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "drop-app"
|
||||
version = "0.3.4"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"atomic-instant-full",
|
||||
"bitcode",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[package]
|
||||
name = "drop-app"
|
||||
version = "0.3.4"
|
||||
description = "The client application for the open-source, self-hosted game distribution platform Drop"
|
||||
authors = ["Drop OSS"]
|
||||
edition = "2024"
|
||||
|
||||
@@ -57,7 +57,7 @@ impl Display for ApplicationDownloadError {
|
||||
format_size(*required, BINARY),
|
||||
format_size(*available, BINARY),
|
||||
),
|
||||
ApplicationDownloadError::Communication(error) => write!(f, "{error}"),
|
||||
ApplicationDownloadError::Communication(error) => write!(f, "{error:?}"),
|
||||
ApplicationDownloadError::Lock => write!(
|
||||
f,
|
||||
"failed to acquire lock. Something has gone very wrong internally. Please restart the application"
|
||||
|
||||
@@ -36,7 +36,7 @@ use crate::downloads::validate::validate_game_chunk;
|
||||
use crate::library::{on_game_complete, push_game_update, set_partially_installed};
|
||||
use crate::state::GameStatusManager;
|
||||
|
||||
use super::download_logic::download_game_bucket;
|
||||
use super::download_logic::download_game_chunk;
|
||||
use super::drop_data::DropData;
|
||||
|
||||
static RETRY_COUNT: usize = 3;
|
||||
@@ -283,6 +283,7 @@ impl GameDownloadAgent {
|
||||
for (index, length) in chunk.lengths.iter().enumerate() {
|
||||
let drop = DownloadDrop {
|
||||
filename: raw_path.to_string(),
|
||||
id: chunk.ids[index].clone(),
|
||||
start: file_running_offset,
|
||||
length: *length,
|
||||
checksum: chunk.checksums[index].clone(),
|
||||
@@ -465,7 +466,7 @@ impl GameDownloadAgent {
|
||||
// 3 attempts
|
||||
for i in 0..RETRY_COUNT {
|
||||
let loop_progress_handle = progress_handle.clone();
|
||||
match download_game_bucket(
|
||||
match download_game_chunk(
|
||||
&bucket,
|
||||
download_context,
|
||||
&self.control_flag,
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::io::Read;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::{
|
||||
fs::{File, OpenOptions},
|
||||
io::{self, BufWriter, Seek, SeekFrom, Write},
|
||||
@@ -105,7 +105,8 @@ impl<'a> DropDownloadPipeline<'a, Response, File> {
|
||||
})
|
||||
}
|
||||
|
||||
fn copy(&mut self) -> Result<bool, io::Error> {
|
||||
fn copy(&mut self) -> Result<(bool, usize), io::Error> {
|
||||
let mut total_copied = 0;
|
||||
let mut copy_buffer = [0u8; MAX_PACKET_LENGTH];
|
||||
for (index, drop) in self.drops.iter().enumerate() {
|
||||
let destination = self
|
||||
@@ -127,13 +128,14 @@ impl<'a> DropDownloadPipeline<'a, Response, File> {
|
||||
})?;
|
||||
remaining -= size;
|
||||
last_bump += size;
|
||||
// total_copied += size;
|
||||
|
||||
destination.write_all(©_buffer[0..size])?;
|
||||
|
||||
if last_bump > BUMP_SIZE {
|
||||
last_bump -= BUMP_SIZE;
|
||||
if self.control_flag.get() == DownloadThreadControlFlag::Stop {
|
||||
return Ok(false);
|
||||
return Ok((false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,11 +145,11 @@ impl<'a> DropDownloadPipeline<'a, Response, File> {
|
||||
}
|
||||
|
||||
if self.control_flag.get() == DownloadThreadControlFlag::Stop {
|
||||
return Ok(false);
|
||||
return Ok((false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
Ok((true, total_copied))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -167,7 +169,7 @@ impl<'a> DropDownloadPipeline<'a, Response, File> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn download_game_bucket(
|
||||
pub fn download_game_chunk(
|
||||
bucket: &DownloadBucket,
|
||||
ctx: &DownloadContext,
|
||||
control_flag: &DownloadThreadControl,
|
||||
@@ -183,14 +185,13 @@ pub fn download_game_bucket(
|
||||
|
||||
let header = generate_authorization_header();
|
||||
|
||||
let url = generate_url(&["/api/v2/client/chunk"], &[])
|
||||
.map_err(ApplicationDownloadError::Communication)?;
|
||||
|
||||
let body = ChunkBody::create(ctx, &bucket.drops);
|
||||
let mut bits = vec!["/api/v1/depot/", &bucket.game_id, &bucket.version];
|
||||
bits.extend(bucket.drops.iter().map(|v| v.id.as_str()));
|
||||
let url = generate_url(&bits, &[]).unwrap();
|
||||
|
||||
let response = DROP_CLIENT_SYNC
|
||||
.post(url)
|
||||
.json(&body)
|
||||
.get(url)
|
||||
//.json(&body)
|
||||
.header("Authorization", header)
|
||||
.send()
|
||||
.map_err(|e| ApplicationDownloadError::Communication(e.into()))?;
|
||||
@@ -210,7 +211,6 @@ pub fn download_game_bucket(
|
||||
RemoteAccessError::UnparseableResponse(raw_res),
|
||||
));
|
||||
}
|
||||
|
||||
let lengths = response
|
||||
.headers()
|
||||
.get("Content-Lengths")
|
||||
@@ -232,9 +232,7 @@ pub fn download_game_bucket(
|
||||
RemoteAccessError::InvalidResponse(DropServerError {
|
||||
status_code: 400,
|
||||
status_message: "Server Error".to_owned(),
|
||||
message: format!(
|
||||
"invalid number of Content-Lengths recieved: {i}, {lengths}"
|
||||
),
|
||||
message: format!("invalid number of Content-Lengths recieved: {i}, {lengths}"),
|
||||
}),
|
||||
));
|
||||
};
|
||||
@@ -264,7 +262,7 @@ pub fn download_game_bucket(
|
||||
DropDownloadPipeline::new(response, bucket.drops.clone(), control_flag, progress)
|
||||
.map_err(|e| ApplicationDownloadError::IoError(Arc::new(e)))?;
|
||||
|
||||
let completed = pipeline
|
||||
let (completed, _) = pipeline
|
||||
.copy()
|
||||
.map_err(|e| ApplicationDownloadError::IoError(Arc::new(e)))?;
|
||||
if !completed {
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::path::PathBuf;
|
||||
// Drops go in buckets
|
||||
pub struct DownloadDrop {
|
||||
pub index: usize,
|
||||
pub id: String,
|
||||
pub filename: String,
|
||||
pub path: PathBuf,
|
||||
pub start: usize,
|
||||
|
||||
@@ -10,7 +10,7 @@ use download_manager::{
|
||||
progress_object::ProgressHandle,
|
||||
},
|
||||
};
|
||||
use log::debug;
|
||||
use log::{debug, info};
|
||||
use md5::Context;
|
||||
|
||||
use crate::downloads::manifest::DropValidateContext;
|
||||
@@ -52,6 +52,7 @@ pub fn validate_game_chunk(
|
||||
|
||||
let res = hex::encode(hasher.finalize().0);
|
||||
if res != ctx.checksum {
|
||||
info!("{} doesn't match", ctx.path.display());
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use remote::{
|
||||
utils::DROP_CLIENT_SYNC,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::remove_dir_all;
|
||||
use std::fs::{exists, remove_dir_all};
|
||||
use std::thread::spawn;
|
||||
use tauri::AppHandle;
|
||||
use utils::app_emit;
|
||||
@@ -154,7 +154,7 @@ pub fn uninstall_game_logic(meta: DownloadableMetadata, app_handle: &AppHandle)
|
||||
|
||||
let app_handle = app_handle.clone();
|
||||
spawn(move || {
|
||||
if let Err(e) = remove_dir_all(install_dir) {
|
||||
if exists(install_dir.clone()).unwrap_or(false) && let Err(e) = remove_dir_all(install_dir) {
|
||||
error!("{e}");
|
||||
} else {
|
||||
let mut db_handle = borrow_db_mut_checked();
|
||||
|
||||
@@ -106,8 +106,8 @@ pub fn auth_initiate_logic(mode: String) -> Result<String, RemoteAccessError> {
|
||||
name: format!("{} (Desktop)", hostname.display()),
|
||||
platform: env::consts::OS.to_string(),
|
||||
capabilities: HashMap::from([
|
||||
("PeerAPI".to_owned(), CapabilityConfiguration {}),
|
||||
("CloudSaves".to_owned(), CapabilityConfiguration {}),
|
||||
("peerAPI".to_owned(), CapabilityConfiguration {}),
|
||||
("cloudSaves".to_owned(), CapabilityConfiguration {}),
|
||||
]),
|
||||
mode,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
use database::{DB, interface::DatabaseImpls};
|
||||
use log::info;
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
@@ -9,10 +11,10 @@ pub fn generate_url<T: AsRef<str>>(
|
||||
path_components: &[T],
|
||||
query: &[(T, T)],
|
||||
) -> Result<Url, RemoteAccessError> {
|
||||
let mut base_url = DB.fetch_base_url();
|
||||
for endpoint in path_components {
|
||||
base_url = base_url.join(endpoint.as_ref())?;
|
||||
}
|
||||
let components = path_components.iter().map(|v| v.as_ref()).map(|v| v.trim_matches('/')).collect::<Vec<&str>>();
|
||||
let mut base_url = DB
|
||||
.fetch_base_url()
|
||||
.join(&components.join("/"))?;
|
||||
{
|
||||
let mut queries = base_url.query_pairs_mut();
|
||||
for (param, val) in query {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::Read,
|
||||
sync::LazyLock,
|
||||
sync::LazyLock, time::Duration,
|
||||
};
|
||||
|
||||
use database::db::DATA_ROOT_DIR;
|
||||
@@ -91,6 +91,7 @@ pub fn get_client_sync() -> reqwest::blocking::Client {
|
||||
}
|
||||
client
|
||||
.use_rustls_tls()
|
||||
.connect_timeout(Duration::from_millis(1500))
|
||||
.build()
|
||||
.expect("Failed to build synchronous client")
|
||||
}
|
||||
|
||||
@@ -224,11 +224,6 @@ pub async fn fetch_game_version_options_logic(
|
||||
return Err(RemoteAccessError::InvalidResponse(err));
|
||||
}
|
||||
|
||||
let raw = response.text().await?;
|
||||
info!("{}", raw);
|
||||
|
||||
return Err(RemoteAccessError::CorruptedState);
|
||||
|
||||
let data: Vec<GameVersion> = response.json().await?;
|
||||
|
||||
let state_lock = state.lock();
|
||||
|
||||
Reference in New Issue
Block a user