Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 107ee40f43 | |||
| ee2e3e5e32 | |||
| 9ce40297ea | |||
| 6a9d74ef84 | |||
| 581198f9e6 | |||
| 1a6b11df68 |
@@ -1,6 +0,0 @@
|
|||||||
/sites
|
|
||||||
/cli
|
|
||||||
/desktop
|
|
||||||
/backend # go backend
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
name: Droplet CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [develop]
|
|
||||||
paths:
|
|
||||||
- "libraries/droplet/**"
|
|
||||||
- "libraries/droplet_types/**"
|
|
||||||
- "libraries/libarchive/**"
|
|
||||||
- ".github/workflows/droplet-ci.yml"
|
|
||||||
pull_request:
|
|
||||||
branches: [develop]
|
|
||||||
paths:
|
|
||||||
- "libraries/droplet/**"
|
|
||||||
- "libraries/droplet_types/**"
|
|
||||||
- "libraries/libarchive/**"
|
|
||||||
- ".github/workflows/droplet-ci.yml"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
ci:
|
|
||||||
name: Build, Test, Lint
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: libraries/droplet
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@nightly
|
|
||||||
with:
|
|
||||||
components: rustfmt, clippy
|
|
||||||
|
|
||||||
- name: Rust cache
|
|
||||||
uses: swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
workspaces: "./libraries/droplet -> target"
|
|
||||||
|
|
||||||
- name: Install libarchive
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y libarchive-dev
|
|
||||||
|
|
||||||
- name: Check formatting
|
|
||||||
run: cargo fmt --all -- --check
|
|
||||||
|
|
||||||
- name: Run Clippy (lint)
|
|
||||||
run: cargo clippy --all-targets --all-features -- -D warnings
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: cargo test --all-features --all --verbose
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
name: Deploy website to GitHub Pages
|
|
||||||
|
|
||||||
on:
|
|
||||||
# Runs on pushes targeting the default branch
|
|
||||||
push:
|
|
||||||
branches: [develop]
|
|
||||||
paths:
|
|
||||||
- "sites/promo/**"
|
|
||||||
- "sites/docs/**"
|
|
||||||
- "package.json"
|
|
||||||
- "pnpm-lock.yaml"
|
|
||||||
- "pnpm-workspace.yaml"
|
|
||||||
- ".github/workflows/pages.yml"
|
|
||||||
|
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
# Allow only one concurrent deployment per the "pages" group, skipping runs queued
|
|
||||||
# between the in-progress run and the latest queued one. cancel-in-progress defaults
|
|
||||||
# to false, so in-flight production deployments are allowed to complete.
|
|
||||||
concurrency: "pages"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install pnpm
|
|
||||||
uses: pnpm/action-setup@v4
|
|
||||||
with:
|
|
||||||
run_install: false
|
|
||||||
|
|
||||||
- name: Install Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: "22"
|
|
||||||
cache: "pnpm"
|
|
||||||
|
|
||||||
# Only install the promo site (radiant) and docs site (docs-next) and their
|
|
||||||
# dependencies so the public website deploy stays decoupled from the
|
|
||||||
# server/desktop build pipelines.
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install --filter radiant... --filter docs-next...
|
|
||||||
|
|
||||||
- name: Setup Pages
|
|
||||||
id: setup_pages
|
|
||||||
uses: actions/configure-pages@v5
|
|
||||||
|
|
||||||
- name: Restore cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
sites/promo/.next/cache
|
|
||||||
# Generate a new cache whenever packages or source files change.
|
|
||||||
key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('sites/promo/**.[jt]s', 'sites/promo/**.[jt]sx') }}
|
|
||||||
# If source files changed but packages didn't, rebuild from a prior cache.
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-
|
|
||||||
|
|
||||||
- name: Build promo site with Next.js
|
|
||||||
working-directory: sites/promo
|
|
||||||
run: pnpm run build
|
|
||||||
env:
|
|
||||||
PAGES_BASE_PATH: ${{ steps.setup_pages.outputs.base_path }}
|
|
||||||
|
|
||||||
- name: Build docs site with Astro
|
|
||||||
working-directory: sites/docs
|
|
||||||
run: pnpm run build
|
|
||||||
|
|
||||||
# Nest the Starlight docs (built with base: "/docs") inside the promo export
|
|
||||||
# so both ship from a single GitHub Pages deployment at /docs.
|
|
||||||
- name: Assemble docs into /docs
|
|
||||||
run: |
|
|
||||||
rm -rf sites/promo/out/docs
|
|
||||||
mkdir -p sites/promo/out/docs
|
|
||||||
cp -r sites/docs/dist/. sites/promo/out/docs/
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-pages-artifact@v3
|
|
||||||
with:
|
|
||||||
path: sites/promo/out
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
environment:
|
|
||||||
name: github-pages
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: build
|
|
||||||
steps:
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
id: deployment
|
|
||||||
uses: actions/deploy-pages@v4
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
dist/
|
|
||||||
node_modules/
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
# syntax=docker/dockerfile:1
|
|
||||||
|
|
||||||
# Pinned to bookworm so the glibc here matches the torrential build stage
|
|
||||||
# and the libarchive runtime package is named `libarchive13` (trixie renames it to libarchive13t64).
|
|
||||||
FROM node:lts-bookworm-slim AS base
|
|
||||||
ENV PNPM_HOME="/pnpm"
|
|
||||||
ENV PATH="$PNPM_HOME:$PATH"
|
|
||||||
RUN corepack enable
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
## so corepack knows pnpm's version
|
|
||||||
COPY . .
|
|
||||||
## prevent prompt to download
|
|
||||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
|
||||||
## setup for offline
|
|
||||||
RUN corepack pack
|
|
||||||
## don't call out to network anymore
|
|
||||||
ENV COREPACK_ENABLE_NETWORK=0
|
|
||||||
|
|
||||||
### INSTALL DEPS ONCE
|
|
||||||
FROM base AS deps
|
|
||||||
RUN pnpm install --frozen-lockfile --ignore-scripts
|
|
||||||
|
|
||||||
### BUILD TORRENTIAL
|
|
||||||
# Bookworm-pinned to match the runtime image's glibc (a trixie build would not run on bookworm).
|
|
||||||
FROM rustlang/rust:nightly-bookworm-slim AS torrential-build
|
|
||||||
## libarchive-dev + pkg-config let libarchive3-sys link libarchive dynamically (glibc).
|
|
||||||
## protobuf-compiler is kept for parity (torrential's build.rs uses a vendored protoc).
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
pkg-config \
|
|
||||||
libarchive-dev \
|
|
||||||
protobuf-compiler \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
WORKDIR /build
|
|
||||||
COPY . .
|
|
||||||
RUN cargo build --release --manifest-path ./torrential/Cargo.toml
|
|
||||||
|
|
||||||
### BUILD APP
|
|
||||||
FROM base AS build-system
|
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
ENV NUXT_TELEMETRY_DISABLED=1
|
|
||||||
|
|
||||||
## add git so drop can determine its git ref at build
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends git \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
## copy deps and rest of project files
|
|
||||||
COPY . .
|
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
|
||||||
|
|
||||||
|
|
||||||
ARG BUILD_DROP_VERSION
|
|
||||||
ARG BUILD_GIT_REF
|
|
||||||
|
|
||||||
## build
|
|
||||||
RUN pnpm run --filter=drop postinstall && pnpm run --filter=drop build
|
|
||||||
|
|
||||||
|
|
||||||
# create run environment for Drop
|
|
||||||
FROM base AS run-system
|
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
ENV NUXT_TELEMETRY_DISABLED=1
|
|
||||||
|
|
||||||
# The base stage's `COPY . .` puts the whole repo into the runtime WORKDIR (/app),
|
|
||||||
# but at runtime only the artifacts copied explicitly below are needed. Drop the
|
|
||||||
# inherited `torrential` source dir: the service resolves the binary by scanning
|
|
||||||
# the cwd for `torrential`, and a directory there is spawned as ./torrential and
|
|
||||||
# fails with EACCES. With it gone, resolution falls through to the `torrential`
|
|
||||||
# binary installed on PATH (/usr/bin/torrential) below.
|
|
||||||
RUN rm -rf /app/torrential
|
|
||||||
|
|
||||||
# RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn add --network-timeout 1000000 --no-lockfile --ignore-scripts prisma@6.11.1
|
|
||||||
## runtime deps:
|
|
||||||
## - libarchive13: torrential now links libarchive dynamically (glibc build)
|
|
||||||
## - p7zip-full: provides the 7z CLI
|
|
||||||
## - nginx: front-end proxy
|
|
||||||
## - openssl + ca-certificates: required by Prisma's query engine on Debian
|
|
||||||
## pnpm itself is provided by corepack (enabled in the base stage)
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
libarchive13 \
|
|
||||||
p7zip-full \
|
|
||||||
nginx \
|
|
||||||
openssl \
|
|
||||||
ca-certificates \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
RUN pnpm install prisma@7.7.0 --global
|
|
||||||
# init prisma to download all required files
|
|
||||||
RUN pnpm prisma init
|
|
||||||
|
|
||||||
COPY --from=build-system /app/server/prisma.config.ts ./
|
|
||||||
COPY --from=build-system /app/server/.output ./app
|
|
||||||
COPY --from=build-system /app/server/prisma ./prisma
|
|
||||||
COPY --from=build-system /app/server/build ./startup
|
|
||||||
COPY --from=build-system /app/server/build/nginx.conf /nginx.conf
|
|
||||||
COPY --from=torrential-build /build/torrential/target/release/torrential /usr/bin/
|
|
||||||
|
|
||||||
ENV LIBRARY="/library"
|
|
||||||
ENV DATA="/data"
|
|
||||||
ENV NGINX_CONFIG="/nginx.conf"
|
|
||||||
# Nuxt's port
|
|
||||||
ENV PORT=4000
|
|
||||||
|
|
||||||
CMD ["sh", "/app/startup/launch.sh"]
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
# Drop
|
# Drop
|
||||||
|
|
||||||
[](https://droposs.org)
|
[](https://droposs.org)
|
||||||
[](https://droposs.org/docs)
|
[](https://docs.droposs.org/)
|
||||||
[](https://forum.droposs.org)
|
[](https://forum.droposs.org)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
[](https://discord.gg/ACq4qZp4a9)
|
[](https://discord.gg/ACq4qZp4a9)
|
||||||
@@ -28,7 +28,7 @@ Drop is an open-source game distribution platform, similar to GameVault or Steam
|
|||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
See our documentation on how to [deploy Drop](https://droposs.org/docs/admin/quickstart) for more information.
|
See our documentation on how to [deploy Drop](https://docs.droposs.org/docs/guides/quickstart) for more information.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
/bin
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package core
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
|
||||||
)
|
|
||||||
|
|
||||||
func connect() {
|
|
||||||
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer conn.Close(context.Background())
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
module drop/core
|
|
||||||
|
|
||||||
go 1.26.1
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
|
||||||
github.com/jackc/pgx/v5 v5.9.1 // indirect
|
|
||||||
golang.org/x/text v0.29.0 // indirect
|
|
||||||
)
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
|
||||||
github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc=
|
|
||||||
github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
|
||||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
module drop
|
|
||||||
|
|
||||||
go 1.26.1
|
|
||||||
|
|
||||||
require github.com/gorilla/mux v1.8.1
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
|
||||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
go 1.26.1
|
|
||||||
|
|
||||||
use ./core
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
|
||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
|
||||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
|
||||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
|
||||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
)
|
|
||||||
|
|
||||||
func handler(res http.ResponseWriter, req *http.Request) {
|
|
||||||
fmt.Fprintf(res, "G'day there mate")
|
|
||||||
}
|
|
||||||
func routingMiddleware(h http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
url := *r.URL
|
|
||||||
url.Path = strings.TrimSuffix(r.URL.Path, "/")
|
|
||||||
r.URL = &url
|
|
||||||
|
|
||||||
h.ServeHTTP(w, r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := mux.NewRouter().StrictSlash(true)
|
|
||||||
r.Use(routingMiddleware)
|
|
||||||
|
|
||||||
r.HandleFunc("/api/v1", handler)
|
|
||||||
|
|
||||||
srv := &http.Server{
|
|
||||||
Addr: ":3433",
|
|
||||||
Handler: r,
|
|
||||||
}
|
|
||||||
log.Printf("starting drop server on :3433")
|
|
||||||
srv.ListenAndServe()
|
|
||||||
}
|
|
||||||
@@ -2,21 +2,6 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "addr2line"
|
|
||||||
version = "0.25.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
|
|
||||||
dependencies = [
|
|
||||||
"gimli",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "adler2"
|
|
||||||
version = "2.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@@ -120,10 +105,10 @@ version = "0.5.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490"
|
checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
"synstructure 0.13.2",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -132,10 +117,10 @@ version = "0.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c"
|
checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
"synstructure 0.13.2",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -144,9 +129,9 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
|
checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -155,9 +140,9 @@ version = "0.1.89"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -205,21 +190,6 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace"
|
|
||||||
version = "0.3.76"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
|
|
||||||
dependencies = [
|
|
||||||
"addr2line",
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"miniz_oxide",
|
|
||||||
"object",
|
|
||||||
"rustc-demangle",
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.22.1"
|
version = "0.22.1"
|
||||||
@@ -325,9 +295,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
|
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -564,9 +534,9 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -607,37 +577,26 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "droplet-rs"
|
name = "droplet-rs"
|
||||||
version = "0.16.3"
|
version = "0.14.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"droplet_types",
|
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"futures",
|
"futures",
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"hex",
|
"hex",
|
||||||
"humansize",
|
"humansize",
|
||||||
"libarchive-drop",
|
|
||||||
"rcgen",
|
"rcgen",
|
||||||
"ring",
|
"ring",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"speedometer",
|
|
||||||
"test-generator",
|
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"uuid",
|
"uuid",
|
||||||
"x509-parser 0.17.0",
|
"x509-parser 0.17.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "droplet_types"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dunce"
|
name = "dunce"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
@@ -681,28 +640,6 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "failure"
|
|
||||||
version = "0.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
|
|
||||||
dependencies = [
|
|
||||||
"backtrace",
|
|
||||||
"failure_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "failure_derive"
|
|
||||||
version = "0.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 1.0.103",
|
|
||||||
"quote 1.0.43",
|
|
||||||
"syn 1.0.109",
|
|
||||||
"synstructure 0.12.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "2.3.0"
|
version = "2.3.0"
|
||||||
@@ -800,9 +737,9 @@ version = "0.3.31"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -872,18 +809,6 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gimli"
|
|
||||||
version = "0.32.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glob"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gloo-timers"
|
name = "gloo-timers"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -1268,9 +1193,9 @@ version = "0.2.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78"
|
checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1336,24 +1261,6 @@ version = "1.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libarchive-drop"
|
|
||||||
version = "0.1.1"
|
|
||||||
dependencies = [
|
|
||||||
"libarchive3-sys",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libarchive3-sys"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3cd3beae8f59a4c7a806523269b5392037577c150446e88d684dfa6de6031ca7"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.178"
|
version = "0.2.178"
|
||||||
@@ -1428,15 +1335,6 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "miniz_oxide"
|
|
||||||
version = "0.8.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
|
||||||
dependencies = [
|
|
||||||
"adler2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
@@ -1523,15 +1421,6 @@ dependencies = [
|
|||||||
"objc2",
|
"objc2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "object"
|
|
||||||
version = "0.37.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oid-registry"
|
name = "oid-registry"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -1641,12 +1530,6 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic"
|
name = "portable-atomic"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
@@ -1686,15 +1569,6 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "0.4.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-xid 0.1.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.103"
|
version = "1.0.103"
|
||||||
@@ -1780,22 +1654,13 @@ dependencies = [
|
|||||||
"windows-sys 0.60.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "0.6.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.4.30",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.43"
|
version = "1.0.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
|
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2022,12 +1887,6 @@ dependencies = [
|
|||||||
"ordered-multimap",
|
"ordered-multimap",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc-demangle"
|
|
||||||
version = "0.1.27"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-hash"
|
name = "rustc-hash"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
@@ -2225,9 +2084,9 @@ version = "1.0.228"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2321,15 +2180,6 @@ dependencies = [
|
|||||||
"windows-sys 0.60.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "speedometer"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2789736092fa21b44baf8590acb4b360cb91f0f597bd6c1f1741ca9644c95c1e"
|
|
||||||
dependencies = [
|
|
||||||
"failure",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@@ -2348,36 +2198,14 @@ version = "2.6.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "0.15.44"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.4.30",
|
|
||||||
"quote 0.6.13",
|
|
||||||
"unicode-xid 0.1.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.109"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 1.0.103",
|
|
||||||
"quote 1.0.43",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.114"
|
version = "2.0.114"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2390,27 +2218,15 @@ dependencies = [
|
|||||||
"futures-core",
|
"futures-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "synstructure"
|
|
||||||
version = "0.12.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 1.0.103",
|
|
||||||
"quote 1.0.43",
|
|
||||||
"syn 1.0.109",
|
|
||||||
"unicode-xid 0.2.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "synstructure"
|
name = "synstructure"
|
||||||
version = "0.13.2"
|
version = "0.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2447,18 +2263,6 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "test-generator"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5b23be2add79223226e1cb6446cb3e37506a5927089870687a0f1149bb7a073a"
|
|
||||||
dependencies = [
|
|
||||||
"glob",
|
|
||||||
"proc-macro2 0.4.30",
|
|
||||||
"quote 0.6.13",
|
|
||||||
"syn 0.15.44",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.69"
|
version = "1.0.69"
|
||||||
@@ -2483,9 +2287,9 @@ version = "1.0.69"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2494,9 +2298,9 @@ version = "2.0.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2586,9 +2390,9 @@ version = "2.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
|
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2703,18 +2507,6 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.2.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unit-prefix"
|
name = "unit-prefix"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@@ -2835,7 +2627,7 @@ version = "0.2.106"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
|
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2846,9 +2638,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
|
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2956,9 +2748,9 @@ version = "0.60.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2967,9 +2759,9 @@ version = "0.59.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3303,10 +3095,10 @@ version = "0.8.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
|
checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
"synstructure 0.13.2",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3324,9 +3116,9 @@ version = "0.8.31"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
|
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3344,10 +3136,10 @@ version = "0.1.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
"synstructure 0.13.2",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3384,9 +3176,9 @@ version = "0.11.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
|
checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.103",
|
"proc-macro2",
|
||||||
"quote 1.0.43",
|
"quote",
|
||||||
"syn 2.0.114",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ clap = { version = "4.5.54", features = ["derive"] }
|
|||||||
console = "0.16.2"
|
console = "0.16.2"
|
||||||
dialoguer = "0.12.0"
|
dialoguer = "0.12.0"
|
||||||
dirs = "6.0.0"
|
dirs = "6.0.0"
|
||||||
droplet-rs = { path = "../libraries/droplet" }
|
droplet-rs = { path = "../droplet-rs", version = "0.14" }
|
||||||
fern = { version = "0.7.1", features = ["colored"] }
|
fern = { version = "0.7.1", features = ["colored"] }
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
indicatif = "0.18.3"
|
indicatif = "0.18.3"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::path::Path;
|
|||||||
use crate::{
|
use crate::{
|
||||||
cli::UploadInfo,
|
cli::UploadInfo,
|
||||||
commands::connect::{config::Config, config_option::ConfigOption},
|
commands::connect::{config::Config, config_option::ConfigOption},
|
||||||
manifest::{ClosureFactory, CompressionOption, DepotManifest, generate_v2_manifest},
|
manifest::{CompressionOption, DepotManifest, generate_v2_manifest},
|
||||||
operator_builder::OperatorBuilder,
|
operator_builder::OperatorBuilder,
|
||||||
};
|
};
|
||||||
use futures::AsyncWriteExt;
|
use futures::AsyncWriteExt;
|
||||||
@@ -12,13 +12,13 @@ use opendal::{FuturesAsyncWriter, Operator};
|
|||||||
use tokio_util::compat::{Compat, FuturesAsyncWriteCompatExt};
|
use tokio_util::compat::{Compat, FuturesAsyncWriteCompatExt};
|
||||||
|
|
||||||
pub async fn upload(
|
pub async fn upload(
|
||||||
upload_info: &UploadInfo,
|
info: &UploadInfo,
|
||||||
config: Config,
|
config: Config,
|
||||||
name: &Option<String>,
|
name: &Option<String>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let game_id = upload_info.game_id.clone();
|
let game_id = &info.game_id;
|
||||||
let path = upload_info.path.clone();
|
let path = &info.path;
|
||||||
let version_id = upload_info.version_id.clone();
|
let version_id = &info.version_id;
|
||||||
|
|
||||||
let operator = get_operator(config, name)?;
|
let operator = get_operator(config, name)?;
|
||||||
|
|
||||||
@@ -27,30 +27,28 @@ pub async fn upload(
|
|||||||
info!("Uploading chunks");
|
info!("Uploading chunks");
|
||||||
|
|
||||||
let v2_manifest = generate_v2_manifest(
|
let v2_manifest = generate_v2_manifest(
|
||||||
Path::new(&path),
|
Path::new(path),
|
||||||
ClosureFactory::new(
|
async |id: String| {
|
||||||
async move |id: String| {
|
info!("Uploading chunk id {id}");
|
||||||
info!("Uploading chunk id {id}");
|
let writer = operator
|
||||||
let writer = operator
|
.writer(&format!("{game_id}/{version_id}/{id}"))
|
||||||
.writer(&format!("{game_id}/{version_id}/{id}"))
|
.await
|
||||||
.await
|
.unwrap()
|
||||||
.unwrap()
|
.into_futures_async_write()
|
||||||
.into_futures_async_write()
|
.compat_write();
|
||||||
.compat_write();
|
writer
|
||||||
writer
|
},
|
||||||
},
|
|writer: Compat<FuturesAsyncWriter>| async {
|
||||||
|writer: Compat<FuturesAsyncWriter>| async {
|
writer.into_inner().close().await.unwrap();
|
||||||
writer.into_inner().close().await.unwrap();
|
},
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
info!("Finished uploading chunks");
|
info!("Finished uploading chunks");
|
||||||
|
|
||||||
existing_depot_manifest.append(
|
existing_depot_manifest.append(
|
||||||
upload_info.game_id.to_string(),
|
game_id.to_string(),
|
||||||
upload_info.version_id.to_string(),
|
version_id.to_string(),
|
||||||
CompressionOption::None,
|
CompressionOption::None,
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(async_fn_traits)]
|
|
||||||
|
|
||||||
use crate::commands::connect::config::manage_configuration;
|
use crate::commands::connect::config::manage_configuration;
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::{Cli, Commands},
|
cli::{Cli, Commands},
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use std::{collections::HashMap, path::Path};
|
use std::{collections::HashMap, path::Path};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use droplet_rs::manifest::{
|
||||||
use droplet_rs::manifest::{Manifest, ManifestWriterFactory, generate_manifest_rusty};
|
Manifest, generate_manifest_rusty, generate_manifest_rusty_v2,
|
||||||
|
};
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use log::info;
|
use log::info;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -39,60 +40,11 @@ impl DepotManifest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClosureFactory<Writer, Factory, Closer>
|
pub async fn generate_v2_manifest<W, F, CloseF>(dir: &Path, factory: F, closer: CloseF) -> anyhow::Result<Manifest>
|
||||||
where
|
where
|
||||||
Writer: AsyncWrite + Unpin,
|
W: AsyncWrite + Unpin,
|
||||||
Factory: AsyncFn(String) -> Writer,
|
F: AsyncFn(String) -> W,
|
||||||
Closer: AsyncFn(Writer),
|
CloseF: AsyncFn(W)
|
||||||
{
|
|
||||||
writer: Factory,
|
|
||||||
closer: Closer,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<
|
|
||||||
W: AsyncWrite + Unpin + Send + Sync,
|
|
||||||
F: AsyncFn(String) -> W + Send + Sync + 'static,
|
|
||||||
C: AsyncFn(W) + Send + Sync,
|
|
||||||
> ManifestWriterFactory for ClosureFactory<W, F, C>
|
|
||||||
where
|
|
||||||
for<'a> F::CallRefFuture<'a>: Send,
|
|
||||||
for<'b> C::CallRefFuture<'b>: Send,
|
|
||||||
{
|
|
||||||
type Writer = W;
|
|
||||||
|
|
||||||
async fn create(&self, id: String) -> anyhow::Result<Self::Writer> {
|
|
||||||
let func = &self.writer;
|
|
||||||
let output = func(id).await;
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
async fn close(&self, writer: Self::Writer) -> anyhow::Result<()> {
|
|
||||||
let func = &self.closer;
|
|
||||||
func(writer).await;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
W: AsyncWrite + Unpin + Send + Sync,
|
|
||||||
F: AsyncFn(String) -> W + Send + Sync + 'static,
|
|
||||||
C: AsyncFn(W) + Sync,
|
|
||||||
> ClosureFactory<W, F, C>
|
|
||||||
where
|
|
||||||
for<'a> F::CallRefFuture<'a>: Send,
|
|
||||||
for<'b> C::CallRefFuture<'b>: Send,
|
|
||||||
{
|
|
||||||
pub fn new(f: F, c: C) -> Self {
|
|
||||||
Self {
|
|
||||||
writer: f,
|
|
||||||
closer: c,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn generate_v2_manifest<Factory>(dir: &Path, factory: Factory) -> anyhow::Result<Manifest>
|
|
||||||
where
|
|
||||||
Factory: ManifestWriterFactory,
|
|
||||||
{
|
{
|
||||||
let progress_bar = ProgressBar::new(10_000).with_style(
|
let progress_bar = ProgressBar::new(10_000).with_style(
|
||||||
ProgressStyle::default_bar()
|
ProgressStyle::default_bar()
|
||||||
@@ -100,15 +52,15 @@ where
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
generate_manifest_rusty(
|
generate_manifest_rusty_v2(
|
||||||
dir,
|
dir,
|
||||||
|progress| {
|
|progress| {
|
||||||
let progress_int = (progress * 100f32).round() as u64;
|
let progress_int = (progress * 100f32).round() as u64;
|
||||||
progress_bar.set_position(progress_int);
|
progress_bar.set_position(progress_int);
|
||||||
},
|
},
|
||||||
|log| progress_bar.suspend(|| info!("{}", log)),
|
|log| progress_bar.suspend(|| info!("{}", log)),
|
||||||
Some(&factory),
|
factory,
|
||||||
None,
|
closer
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: "[BUG]"
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. Arch Linux, Windows]
|
||||||
|
- App Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
on: push
|
||||||
|
name: Clippy check
|
||||||
|
jobs:
|
||||||
|
clippy_check:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
permissions:
|
||||||
|
checks: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: install dependencies (ubuntu only)
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev
|
||||||
|
|
||||||
|
- uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: nightly
|
||||||
|
components: clippy
|
||||||
|
override: true
|
||||||
|
- uses: actions-rs/clippy-check@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
args: --manifest-path ./src-tauri/Cargo.toml
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
name: "Build and release desktop"
|
name: "publish"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch: {}
|
||||||
inputs:
|
|
||||||
tagName:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
description: "tagName to be associated with this release."
|
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
# This can be used to automatically publish nightlies at UTC nighttime
|
# This can be used to automatically publish nightlies at UTC nighttime
|
||||||
@@ -38,11 +33,13 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
submodules: true
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: setup pnpm
|
- name: setup pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
|
version: 10
|
||||||
run_install: false
|
run_install: false
|
||||||
|
|
||||||
- name: setup node
|
- name: setup node
|
||||||
@@ -61,7 +58,7 @@ jobs:
|
|||||||
- name: Rust cache
|
- name: Rust cache
|
||||||
uses: swatinem/rust-cache@v2
|
uses: swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
workspaces: './desktop/src-tauri -> target'
|
workspaces: './src-tauri -> target'
|
||||||
|
|
||||||
- name: install dependencies (ubuntu only)
|
- name: install dependencies (ubuntu only)
|
||||||
if: matrix.platform == 'ubuntu-22.04' || matrix.platform == 'ubuntu-22.04-arm' # This must match the platform value defined above.
|
if: matrix.platform == 'ubuntu-22.04' || matrix.platform == 'ubuntu-22.04-arm' # This must match the platform value defined above.
|
||||||
@@ -83,10 +80,6 @@ jobs:
|
|||||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
|
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
|
||||||
security set-keychain-settings -t 3600 -u build.keychain
|
security set-keychain-settings -t 3600 -u build.keychain
|
||||||
|
|
||||||
# Add build.keychain to the user keychain search list so that codesign
|
|
||||||
# (invoked later by tauri-action WITHOUT an explicit --keychain) can
|
|
||||||
# resolve the signing identity from it.
|
|
||||||
security list-keychains -d user -s build.keychain $(security list-keychains -d user | tr -d '"')
|
|
||||||
|
|
||||||
echo "Created keychain"
|
echo "Created keychain"
|
||||||
|
|
||||||
@@ -122,19 +115,14 @@ jobs:
|
|||||||
- uses: tauri-apps/tauri-action@v0
|
- uses: tauri-apps/tauri-action@v0
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# Do NOT set APPLE_CERTIFICATE / APPLE_CERTIFICATE_PASSWORD here. Doing so
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
# makes tauri-action import the cert into its own throwaway keychain and
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||||
# look up the identity by Apple-only name prefixes (e.g.
|
|
||||||
# "Developer ID Application:"), which never matches our "Drop OSS" cert
|
|
||||||
# and fails with "failed to resolve signing identity". Instead we rely on
|
|
||||||
# the build.keychain prepared above and only pass the resolved identity.
|
|
||||||
APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }}
|
APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }}
|
||||||
NO_STRIP: true
|
NO_STRIP: true
|
||||||
with:
|
with:
|
||||||
tagName: ${{ inputs.print_tags || 'v__VERSION__' }} # the action automatically replaces \_\_VERSION\_\_ with the app version.
|
tagName: v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version.
|
||||||
releaseName: "Auto-release v__VERSION__"
|
releaseName: "Auto-release v__VERSION__"
|
||||||
releaseBody: "See the assets to download this version and install. This release was created automatically."
|
releaseBody: "See the assets to download this version and install. This release was created automatically."
|
||||||
releaseDraft: false
|
releaseDraft: false
|
||||||
prerelease: true
|
prerelease: true
|
||||||
args: ${{ matrix.args }}
|
args: ${{ matrix.args }}
|
||||||
projectPath: './desktop'
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[submodule "src-tauri/tailscale/libtailscale"]
|
||||||
|
path = src-tauri/tailscale/libtailscale
|
||||||
|
url = https://github.com/tailscale/libtailscale.git
|
||||||
|
[submodule "libs/drop-base"]
|
||||||
|
path = libs/drop-base
|
||||||
|
url = https://github.com/drop-oss/drop-base.git
|
||||||
@@ -21,6 +21,13 @@ async function spawn(exec, opts) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const expectedLibs = ["drop-base/package.json"];
|
||||||
|
|
||||||
|
for (const lib of expectedLibs) {
|
||||||
|
const path = `./libs/${lib}`;
|
||||||
|
if (!fs.existsSync(path)) throw `Missing "${expectedLibs}". Run "git submodule update --init --recursive"`;
|
||||||
|
}
|
||||||
|
|
||||||
const views = fs.readdirSync(".").filter((view) => {
|
const views = fs.readdirSync(".").filter((view) => {
|
||||||
const expectedPath = `./${view}/package.json`;
|
const expectedPath = `./${view}/package.json`;
|
||||||
return fs.existsSync(expectedPath);
|
return fs.existsSync(expectedPath);
|
||||||
|
|||||||
@@ -1,141 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Listbox
|
|
||||||
as="div"
|
|
||||||
v-model="model.overrideHandler"
|
|
||||||
class="mt-6"
|
|
||||||
v-if="handlers.length > 1"
|
|
||||||
>
|
|
||||||
<ListboxLabel class="block text-sm/6 font-medium text-white"
|
|
||||||
>Launch method</ListboxLabel
|
|
||||||
>
|
|
||||||
<div class="relative mt-2">
|
|
||||||
<ListboxButton
|
|
||||||
class="grid w-full cursor-default grid-cols-1 rounded-md bg-white/5 py-1.5 pr-2 pl-3 text-left text-white outline-1 -outline-offset-1 outline-white/10 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-blue-500 sm:text-sm/6"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
v-if="currentHandler"
|
|
||||||
class="col-start-1 row-start-1 truncate pr-6"
|
|
||||||
>{{ currentHandler.name }}</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
v-else
|
|
||||||
class="col-start-1 row-start-1 truncate pr-6 italic text-zinc-400"
|
|
||||||
>Automatic</span
|
|
||||||
>
|
|
||||||
<ChevronUpDownIcon
|
|
||||||
class="col-start-1 row-start-1 size-5 self-center justify-self-end text-zinc-400 sm:size-4"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</ListboxButton>
|
|
||||||
|
|
||||||
<transition
|
|
||||||
leave-active-class="transition ease-in duration-100"
|
|
||||||
leave-from-class=""
|
|
||||||
leave-to-class="opacity-0"
|
|
||||||
>
|
|
||||||
<ListboxOptions
|
|
||||||
class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-zinc-800 py-1 text-base outline-1 -outline-offset-1 outline-white/10 sm:text-sm"
|
|
||||||
>
|
|
||||||
<ListboxOption
|
|
||||||
as="template"
|
|
||||||
:value="undefined"
|
|
||||||
v-slot="{ active, selected }"
|
|
||||||
>
|
|
||||||
<li
|
|
||||||
:class="[
|
|
||||||
active ? 'bg-blue-500 text-white outline-hidden' : 'text-white',
|
|
||||||
'relative cursor-default py-2 pr-9 pl-3 select-none',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
:class="[
|
|
||||||
selected ? 'font-semibold' : 'font-normal',
|
|
||||||
'block truncate italic',
|
|
||||||
]"
|
|
||||||
>Automatic</span
|
|
||||||
>
|
|
||||||
<span class="block truncate text-xs text-zinc-400"
|
|
||||||
>Pick the best method for this game.</span
|
|
||||||
>
|
|
||||||
|
|
||||||
<span
|
|
||||||
v-if="selected"
|
|
||||||
:class="[
|
|
||||||
active ? 'text-white' : 'text-blue-400',
|
|
||||||
'absolute inset-y-0 right-0 flex items-center pr-4',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<CheckIcon class="size-5" aria-hidden="true" />
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ListboxOption>
|
|
||||||
<ListboxOption
|
|
||||||
as="template"
|
|
||||||
v-for="handler in handlers"
|
|
||||||
:key="handler.id"
|
|
||||||
:value="handler.id"
|
|
||||||
v-slot="{ active, selected }"
|
|
||||||
>
|
|
||||||
<li
|
|
||||||
:class="[
|
|
||||||
active ? 'bg-blue-500 text-white outline-hidden' : 'text-white',
|
|
||||||
'relative cursor-default py-2 pr-9 pl-3 select-none',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
:class="[
|
|
||||||
selected ? 'font-semibold' : 'font-normal',
|
|
||||||
'block truncate',
|
|
||||||
]"
|
|
||||||
>{{ handler.name }}</span
|
|
||||||
>
|
|
||||||
<span class="block truncate text-xs text-zinc-400">{{
|
|
||||||
handler.description
|
|
||||||
}}</span>
|
|
||||||
|
|
||||||
<span
|
|
||||||
v-if="selected"
|
|
||||||
:class="[
|
|
||||||
active ? 'text-white' : 'text-blue-400',
|
|
||||||
'absolute inset-y-0 right-0 flex items-center pr-4',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<CheckIcon class="size-5" aria-hidden="true" />
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ListboxOption>
|
|
||||||
</ListboxOptions>
|
|
||||||
</transition>
|
|
||||||
</div>
|
|
||||||
<p class="mt-2 text-sm text-zinc-400">
|
|
||||||
Override how this game is launched.
|
|
||||||
</p>
|
|
||||||
</Listbox>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
|
||||||
import {
|
|
||||||
Listbox,
|
|
||||||
ListboxButton,
|
|
||||||
ListboxLabel,
|
|
||||||
ListboxOption,
|
|
||||||
ListboxOptions,
|
|
||||||
} from "@headlessui/vue";
|
|
||||||
import { ChevronUpDownIcon } from "@heroicons/vue/16/solid";
|
|
||||||
import { CheckIcon } from "@heroicons/vue/20/solid";
|
|
||||||
import type { GameVersion } from "~/types";
|
|
||||||
|
|
||||||
type ProcessHandlerOption = { id: string; name: string; description: string };
|
|
||||||
|
|
||||||
const model = defineModel<GameVersion["userConfiguration"]>({ required: true });
|
|
||||||
const props = defineProps<{ gameId: string }>();
|
|
||||||
|
|
||||||
const handlers = await invoke<ProcessHandlerOption[]>("get_process_handlers", {
|
|
||||||
id: props.gameId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const currentHandler = computed(() =>
|
|
||||||
handlers.find((v) => v.id == model.value.overrideHandler),
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
@@ -23,19 +23,16 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ProtonSelector v-model="model" v-if="$props.protonEnabled" />
|
<ProtonSelector v-model="model" v-if="$props.protonEnabled" />
|
||||||
<HandlerSelector v-model="model" :game-id="$props.gameId" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { GameVersion } from "~/types";
|
import type { GameVersion } from "~/types";
|
||||||
import ProtonSelector from "./ProtonSelector.vue";
|
import ProtonSelector from "./ProtonSelector.vue";
|
||||||
import HandlerSelector from "./HandlerSelector.vue";
|
|
||||||
|
|
||||||
const model = defineModel<GameVersion["userConfiguration"]>({ required: true });
|
const model = defineModel<GameVersion["userConfiguration"]>({ required: true });
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
protonEnabled: boolean;
|
protonEnabled: boolean;
|
||||||
gameId: string;
|
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<ModalTemplate size-class="max-w-4xl" v-model="open">
|
<ModalTemplate size-class="max-w-4xl" v-model="open">
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="flex flex-row gap-x-4 min-h-96">
|
<div class="flex flex-row gap-x-4 h-96">
|
||||||
<nav class="flex flex-1 flex-col" aria-label="Sidebar">
|
<nav class="flex flex-1 flex-col" aria-label="Sidebar">
|
||||||
<ul role="list" class="-mx-2 space-y-1">
|
<ul role="list" class="-mx-2 space-y-1">
|
||||||
<li v-for="(tab, tabIdx) in tabs" :key="tab.name">
|
<li v-for="(tab, tabIdx) in tabs" :key="tab.name">
|
||||||
@@ -29,12 +29,11 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="border-l-2 border-zinc-800 w-full grow pl-4">
|
<div class="border-l-2 border-zinc-800 w-full grow pl-4 overflow-y-scroll">
|
||||||
<component
|
<component
|
||||||
v-model="configuration"
|
v-model="configuration"
|
||||||
:is="tabs[currentTabIndex]?.page"
|
:is="tabs[currentTabIndex]?.page"
|
||||||
:proton-enabled="protonEnabled"
|
:proton-enabled="protonEnabled"
|
||||||
:game-id="props.gameId"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
as="div"
|
as="div"
|
||||||
v-for="(nav, navIndex) in filteredNavigation"
|
v-for="(nav, navIndex) in filteredNavigation"
|
||||||
:key="nav.id"
|
:key="nav.id"
|
||||||
:class="['first:pt-0 last:pb-0', nav.tools && !filteredNavigation[navIndex - 1].tools ? 'mt-auto' : '']"
|
:class="['first:pt-0 last:pb-0', nav.tools ? 'mt-auto' : '']"
|
||||||
v-slot="{ open }"
|
v-slot="{ open }"
|
||||||
:default-open="nav.deft"
|
:default-open="nav.deft"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"koa": "^2.16.1",
|
"koa": "^2.16.1",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"micromark": "^4.0.1",
|
"micromark": "^4.0.1",
|
||||||
"nuxt": "^4.4.8",
|
"nuxt": "^3.16.0",
|
||||||
"scss": "^0.2.4",
|
"scss": "^0.2.4",
|
||||||
"vue-router": "latest",
|
"vue-router": "latest",
|
||||||
"vuedraggable": "^4.1.0"
|
"vuedraggable": "^4.1.0"
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
const path = require('path');
|
|
||||||
|
|
||||||
const dropbase = path.join(__dirname, "../../libraries/base")
|
|
||||||
|
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
export default {
|
export default {
|
||||||
content: [
|
content: [
|
||||||
@@ -11,7 +7,7 @@ export default {
|
|||||||
"./plugins/**/*.{js,ts}",
|
"./plugins/**/*.{js,ts}",
|
||||||
"./app.vue",
|
"./app.vue",
|
||||||
"./error.vue",
|
"./error.vue",
|
||||||
`${dropbase}/components/**/*.{js,vue,ts}`,
|
"../libs/drop-base/**/*.{js,vue,ts}",
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ export type GameVersion = {
|
|||||||
userConfiguration: {
|
userConfiguration: {
|
||||||
launchTemplate: string;
|
launchTemplate: string;
|
||||||
overrideProtonPath: string;
|
overrideProtonPath: string;
|
||||||
overrideHandler: string | undefined;
|
|
||||||
enableUpdates: boolean
|
enableUpdates: boolean
|
||||||
};
|
};
|
||||||
setups: Array<{ platform: string }>;
|
setups: Array<{ platform: string }>;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"tauri": "tauri"
|
"tauri": "tauri"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pino": "^9.14.0",
|
"pino": "^9.7.0",
|
||||||
"pino-pretty": "^13.1.1",
|
"pino-pretty": "^13.1.1",
|
||||||
"tauri": "^0.15.0"
|
"tauri": "^0.15.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
onlyBuiltDependencies:
|
||||||
|
- sharp
|
||||||
|
|
||||||
|
overrides:
|
||||||
|
cross-spawn@<6.0.6: '>=6.0.6'
|
||||||
|
cross-spawn@>=7.0.0 <7.0.5: '>=7.0.5'
|
||||||
|
form-data@<2.5.4: '>=2.5.4'
|
||||||
|
got@<11.8.5: '>=11.8.5'
|
||||||
|
http-cache-semantics@<4.1.1: '>=4.1.1'
|
||||||
|
lodash@<4.17.21: '>=4.17.21'
|
||||||
|
lodash@>=4.0.0 <4.17.21: '>=4.17.21'
|
||||||
|
minimist@>=1.0.0 <1.2.6: '>=1.2.6'
|
||||||
|
nth-check@<2.0.1: '>=2.0.1'
|
||||||
|
semver-regex@<3.1.3: '>=3.1.3'
|
||||||
|
semver-regex@<3.1.4: '>=3.1.4'
|
||||||
|
semver@>=7.0.0 <7.5.2: '>=7.5.2'
|
||||||
|
sharp@<0.30.5: '>=0.30.5'
|
||||||
|
sharp@<0.32.6: '>=0.32.6'
|
||||||
|
tmp@<=0.2.3: '>=0.2.4'
|
||||||
|
tough-cookie@<4.1.3: '>=4.1.3'
|
||||||
|
trim-newlines@<3.0.1: '>=3.0.1'
|
||||||
@@ -41,6 +41,7 @@ database = { path = "./database" } # database
|
|||||||
deranged = "=0.4.0"
|
deranged = "=0.4.0"
|
||||||
dirs = "6.0.0"
|
dirs = "6.0.0"
|
||||||
download_manager = { path = "./download_manager", version = "0.1.0" } # download manager
|
download_manager = { path = "./download_manager", version = "0.1.0" } # download manager
|
||||||
|
droplet-rs = "0.7.3"
|
||||||
filetime = "0.2.25"
|
filetime = "0.2.25"
|
||||||
futures-core = "0.3.31"
|
futures-core = "0.3.31"
|
||||||
futures-lite = "2.6.0"
|
futures-lite = "2.6.0"
|
||||||
@@ -82,7 +83,7 @@ sha1 = "0.10.6"
|
|||||||
shared_child = "1.0.1"
|
shared_child = "1.0.1"
|
||||||
slice-deque = "0.3.0"
|
slice-deque = "0.3.0"
|
||||||
sysinfo = "0.36.1"
|
sysinfo = "0.36.1"
|
||||||
tar = "0.4.46"
|
tar = "0.4.44"
|
||||||
tauri-plugin-autostart = "*"
|
tauri-plugin-autostart = "*"
|
||||||
tauri-plugin-deep-link = "*"
|
tauri-plugin-deep-link = "*"
|
||||||
tauri-plugin-dialog = "*"
|
tauri-plugin-dialog = "*"
|
||||||
@@ -136,9 +137,6 @@ tauri-build = { version = "*", features = [] }
|
|||||||
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\"))".dependencies]
|
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\"))".dependencies]
|
||||||
tauri-plugin-single-instance = { version = "2.0.0", features = ["deep-link"] }
|
tauri-plugin-single-instance = { version = "2.0.0", features = ["deep-link"] }
|
||||||
|
|
||||||
[target."cfg(target_os = \"linux\")".dependencies]
|
|
||||||
libloading = "0.7"
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ rustix = "1.1.2"
|
|||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
serde_json = "1.0.145"
|
serde_json = "1.0.145"
|
||||||
serde_with = "3.15.0"
|
serde_with = "3.15.0"
|
||||||
tar = "0.4.46"
|
tar = "0.4.44"
|
||||||
tempfile = "3.23.0"
|
tempfile = "3.23.0"
|
||||||
uuid = "1.18.1"
|
uuid = "1.18.1"
|
||||||
whoami = "1.6.1"
|
whoami = "1.6.1"
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ pub mod data {
|
|||||||
UserConfiguration {
|
UserConfiguration {
|
||||||
launch_template: "{}".to_owned(),
|
launch_template: "{}".to_owned(),
|
||||||
override_proton_path: None,
|
override_proton_path: None,
|
||||||
override_handler: None,
|
|
||||||
enable_updates: false,
|
enable_updates: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,8 +88,6 @@ pub mod data {
|
|||||||
pub struct UserConfiguration {
|
pub struct UserConfiguration {
|
||||||
pub launch_template: String,
|
pub launch_template: String,
|
||||||
pub override_proton_path: Option<String>,
|
pub override_proton_path: Option<String>,
|
||||||
#[serde(default)]
|
|
||||||
pub override_handler: Option<String>,
|
|
||||||
pub enable_updates: bool,
|
pub enable_updates: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
env,
|
|
||||||
sync::RwLock,
|
sync::RwLock,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant}, usize,
|
||||||
usize,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
@@ -36,7 +34,7 @@ struct Depot {
|
|||||||
manifest: Option<DepotManifest>,
|
manifest: Option<DepotManifest>,
|
||||||
latest_speed: Option<usize>, // bytes per second
|
latest_speed: Option<usize>, // bytes per second
|
||||||
current_downloads: SyncSemaphore,
|
current_downloads: SyncSemaphore,
|
||||||
enabled: bool,
|
enabled: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DepotManager {
|
pub struct DepotManager {
|
||||||
@@ -115,13 +113,7 @@ impl DepotManager {
|
|||||||
for depot in &mut new_depots {
|
for depot in &mut new_depots {
|
||||||
if let Err(sync_error) = self.sync_depot(depot).await {
|
if let Err(sync_error) = self.sync_depot(depot).await {
|
||||||
warn!("failed to sync depot {}: {:?}", depot.endpoint, sync_error);
|
warn!("failed to sync depot {}: {:?}", depot.endpoint, sync_error);
|
||||||
if env::var("FORCE_ENABLE_DEPOTS")
|
depot.enabled = false;
|
||||||
.map(|v| !v.is_empty())
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
} else {
|
|
||||||
depot.enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ crossbeam-channel = "0.5.15"
|
|||||||
ctr = "0.9.2"
|
ctr = "0.9.2"
|
||||||
database = { path = "../database", version = "0.1.0" }
|
database = { path = "../database", version = "0.1.0" }
|
||||||
download_manager = { path = "../download_manager", version = "0.1.0" }
|
download_manager = { path = "../download_manager", version = "0.1.0" }
|
||||||
droplet_types = { path = "../../../libraries/droplet_types" }
|
droplet-rs = { path = "../../../libraries/droplet" }
|
||||||
futures-util = "*"
|
futures-util = "*"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
log = "0.4.28"
|
log = "0.4.28"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use download_manager::util::download_thread_control_flag::{
|
|||||||
DownloadThreadControl, DownloadThreadControlFlag,
|
DownloadThreadControl, DownloadThreadControlFlag,
|
||||||
};
|
};
|
||||||
use download_manager::util::progress_object::{ProgressHandle, ProgressObject, ProgressType};
|
use download_manager::util::progress_object::{ProgressHandle, ProgressObject, ProgressType};
|
||||||
use droplet_types::{ChunkData, Manifest};
|
use droplet_rs::manifest::{ChunkData, Manifest};
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use futures_util::stream::FuturesUnordered;
|
use futures_util::stream::FuturesUnordered;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use download_manager::util::download_thread_control_flag::{
|
|||||||
DownloadThreadControl, DownloadThreadControlFlag,
|
DownloadThreadControl, DownloadThreadControlFlag,
|
||||||
};
|
};
|
||||||
use download_manager::util::progress_object::ProgressHandle;
|
use download_manager::util::progress_object::ProgressHandle;
|
||||||
use droplet_types::ChunkData;
|
use droplet_rs::manifest::ChunkData;
|
||||||
use futures_util::StreamExt as _;
|
use futures_util::StreamExt as _;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use remote::auth::generate_authorization_header;
|
use remote::auth::generate_authorization_header;
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
use std::{
|
use std::{fs::create_dir_all, path::PathBuf, process::Command};
|
||||||
fs::create_dir_all,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
process::Command,
|
|
||||||
};
|
|
||||||
|
|
||||||
use client::compat::{COMPAT_INFO, UMU_LAUNCHER_EXECUTABLE};
|
use client::compat::{COMPAT_INFO, UMU_LAUNCHER_EXECUTABLE};
|
||||||
use database::{
|
use database::{
|
||||||
Database, DownloadableMetadata, GameVersion, db::DATA_ROOT_DIR, platform::Platform,
|
Database, DownloadableMetadata, GameVersion, db::DATA_ROOT_DIR, platform::Platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{error::ProcessError, parser::ParsedCommand, process_manager::ProcessHandler};
|
use crate::{error::ProcessError, process_manager::ProcessHandler};
|
||||||
|
|
||||||
pub struct MacLauncher;
|
pub struct MacLauncher;
|
||||||
impl ProcessHandler for MacLauncher {
|
impl ProcessHandler for MacLauncher {
|
||||||
@@ -29,231 +25,13 @@ impl ProcessHandler for MacLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn modify_command(&self, _command: &mut Command) {}
|
fn modify_command(&self, _command: &mut Command) {}
|
||||||
|
|
||||||
fn id(&self) -> &'static str {
|
|
||||||
"macos"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"Direct"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Launches the game directly on macOS."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||||
|
|
||||||
#[cfg_attr(not(target_os = "windows"), allow(unused_variables))]
|
|
||||||
fn apply_no_window(command: &mut Command) {
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
{
|
|
||||||
use std::os::windows::process::CommandExt;
|
|
||||||
command.creation_flags(CREATE_NO_WINDOW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum WindowsLaunchStrategy {
|
|
||||||
Direct,
|
|
||||||
Cmd,
|
|
||||||
Powershell,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap a launch command for Windows; with no strategy, detect it from the file extension.
|
|
||||||
fn windows_launch_command(
|
|
||||||
launch_command: String,
|
|
||||||
current_dir: &str,
|
|
||||||
strategy: Option<WindowsLaunchStrategy>,
|
|
||||||
) -> Result<String, ProcessError> {
|
|
||||||
let mut parsed = ParsedCommand::parse(launch_command)?;
|
|
||||||
|
|
||||||
let strategy = strategy.unwrap_or_else(|| {
|
|
||||||
let extension = Path::new(&parsed.command)
|
|
||||||
.extension()
|
|
||||||
.and_then(|ext| ext.to_str())
|
|
||||||
.map(str::to_ascii_lowercase);
|
|
||||||
match extension.as_deref() {
|
|
||||||
Some("ps1") => WindowsLaunchStrategy::Powershell,
|
|
||||||
Some("exe") | Some("com") => WindowsLaunchStrategy::Direct,
|
|
||||||
_ => WindowsLaunchStrategy::Cmd,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
match strategy {
|
|
||||||
// PowerShell scripts
|
|
||||||
WindowsLaunchStrategy::Powershell => {
|
|
||||||
parsed.make_absolute(PathBuf::from(current_dir));
|
|
||||||
let script = std::mem::replace(&mut parsed.command, "powershell".to_owned());
|
|
||||||
let mut args = vec![
|
|
||||||
"-NoProfile".to_owned(),
|
|
||||||
"-ExecutionPolicy".to_owned(),
|
|
||||||
"Bypass".to_owned(),
|
|
||||||
"-File".to_owned(),
|
|
||||||
script,
|
|
||||||
];
|
|
||||||
args.append(&mut parsed.args);
|
|
||||||
parsed.args = args;
|
|
||||||
}
|
|
||||||
// Direct executables
|
|
||||||
WindowsLaunchStrategy::Direct => {
|
|
||||||
parsed.make_absolute(PathBuf::from(current_dir));
|
|
||||||
}
|
|
||||||
// cmd.exe, for batch files, builtins, PATHEXT resolution, %VAR% expansion, etc.
|
|
||||||
WindowsLaunchStrategy::Cmd => {
|
|
||||||
let command = std::mem::replace(&mut parsed.command, "cmd".to_owned());
|
|
||||||
let mut args = vec!["/C".to_owned(), command];
|
|
||||||
args.append(&mut parsed.args);
|
|
||||||
parsed.args = args;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(parsed.reconstruct())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WindowsLauncher;
|
pub struct WindowsLauncher;
|
||||||
impl ProcessHandler for WindowsLauncher {
|
impl ProcessHandler for WindowsLauncher {
|
||||||
fn create_launch_process(
|
|
||||||
&self,
|
|
||||||
_meta: &DownloadableMetadata,
|
|
||||||
launch_command: String,
|
|
||||||
_game_version: &GameVersion,
|
|
||||||
current_dir: &str,
|
|
||||||
_database: &Database,
|
|
||||||
) -> Result<String, ProcessError> {
|
|
||||||
windows_launch_command(launch_command, current_dir, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn valid_for_platform(&self, _db: &Database, _target: &Platform) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn modify_command(&self, command: &mut Command) {
|
|
||||||
apply_no_window(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn id(&self) -> &'static str {
|
|
||||||
"windows-auto"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"Automatic"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Detects the file type and launches it directly, or through cmd or PowerShell."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WindowsDirectLauncher;
|
|
||||||
impl ProcessHandler for WindowsDirectLauncher {
|
|
||||||
fn create_launch_process(
|
|
||||||
&self,
|
|
||||||
_meta: &DownloadableMetadata,
|
|
||||||
launch_command: String,
|
|
||||||
_game_version: &GameVersion,
|
|
||||||
current_dir: &str,
|
|
||||||
_database: &Database,
|
|
||||||
) -> Result<String, ProcessError> {
|
|
||||||
windows_launch_command(launch_command, current_dir, Some(WindowsLaunchStrategy::Direct))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn valid_for_platform(&self, _db: &Database, _target: &Platform) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn modify_command(&self, command: &mut Command) {
|
|
||||||
apply_no_window(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn id(&self) -> &'static str {
|
|
||||||
"windows-direct"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"Direct executable"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Runs the executable directly, without a shell."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WindowsCmdLauncher;
|
|
||||||
impl ProcessHandler for WindowsCmdLauncher {
|
|
||||||
fn create_launch_process(
|
|
||||||
&self,
|
|
||||||
_meta: &DownloadableMetadata,
|
|
||||||
launch_command: String,
|
|
||||||
_game_version: &GameVersion,
|
|
||||||
current_dir: &str,
|
|
||||||
_database: &Database,
|
|
||||||
) -> Result<String, ProcessError> {
|
|
||||||
windows_launch_command(launch_command, current_dir, Some(WindowsLaunchStrategy::Cmd))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn valid_for_platform(&self, _db: &Database, _target: &Platform) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn modify_command(&self, command: &mut Command) {
|
|
||||||
apply_no_window(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn id(&self) -> &'static str {
|
|
||||||
"windows-cmd"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"Command Prompt (cmd)"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Launches through cmd.exe. Supports batch files, builtins and %VAR% expansion."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct WindowsPowershellLauncher;
|
|
||||||
impl ProcessHandler for WindowsPowershellLauncher {
|
|
||||||
fn create_launch_process(
|
|
||||||
&self,
|
|
||||||
_meta: &DownloadableMetadata,
|
|
||||||
launch_command: String,
|
|
||||||
_game_version: &GameVersion,
|
|
||||||
current_dir: &str,
|
|
||||||
_database: &Database,
|
|
||||||
) -> Result<String, ProcessError> {
|
|
||||||
windows_launch_command(
|
|
||||||
launch_command,
|
|
||||||
current_dir,
|
|
||||||
Some(WindowsLaunchStrategy::Powershell),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn valid_for_platform(&self, _db: &Database, _target: &Platform) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn modify_command(&self, command: &mut Command) {
|
|
||||||
apply_no_window(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn id(&self) -> &'static str {
|
|
||||||
"windows-powershell"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"PowerShell"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Runs the command as a PowerShell script (-File)."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct LinuxNativeLauncher;
|
|
||||||
impl ProcessHandler for LinuxNativeLauncher {
|
|
||||||
fn create_launch_process(
|
fn create_launch_process(
|
||||||
&self,
|
&self,
|
||||||
_meta: &DownloadableMetadata,
|
_meta: &DownloadableMetadata,
|
||||||
@@ -262,26 +40,19 @@ impl ProcessHandler for LinuxNativeLauncher {
|
|||||||
_current_dir: &str,
|
_current_dir: &str,
|
||||||
_database: &Database,
|
_database: &Database,
|
||||||
) -> Result<String, ProcessError> {
|
) -> Result<String, ProcessError> {
|
||||||
// Run native Linux games directly, no umu-run wrapper
|
Ok(format!("cmd /C \"{}\"", launch_command))
|
||||||
Ok(launch_command)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn valid_for_platform(&self, _db: &Database, _target: &Platform) -> bool {
|
fn valid_for_platform(&self, _db: &Database, _target: &Platform) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modify_command(&self, _command: &mut Command) {}
|
#[allow(unused_variables)]
|
||||||
|
fn modify_command(&self, command: &mut Command) {
|
||||||
fn id(&self) -> &'static str {
|
#[cfg(target_os = "windows")]
|
||||||
"linux-native"
|
use std::os::windows::process::CommandExt;
|
||||||
}
|
#[cfg(target_os = "windows")]
|
||||||
|
command.creation_flags(CREATE_NO_WINDOW);
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"Native (direct)"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Runs the native Linux game directly on the host."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,18 +101,6 @@ impl ProcessHandler for UMUNativeLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn modify_command(&self, _command: &mut Command) {}
|
fn modify_command(&self, _command: &mut Command) {}
|
||||||
|
|
||||||
fn id(&self) -> &'static str {
|
|
||||||
"linux-umu"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"Steam Linux Runtime (umu-run)"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Runs the native Linux game inside umu-run's Steam Linux Runtime."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UMUCompatLauncher;
|
pub struct UMUCompatLauncher;
|
||||||
@@ -409,18 +168,6 @@ impl ProcessHandler for UMUCompatLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn modify_command(&self, _command: &mut Command) {}
|
fn modify_command(&self, _command: &mut Command) {}
|
||||||
|
|
||||||
fn id(&self) -> &'static str {
|
|
||||||
"proton-umu"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"Proton (umu-run)"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Runs the Windows game through Proton using umu-run."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AsahiMuvmLauncher;
|
pub struct AsahiMuvmLauncher;
|
||||||
@@ -481,16 +228,4 @@ impl ProcessHandler for AsahiMuvmLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn modify_command(&self, _command: &mut Command) {}
|
fn modify_command(&self, _command: &mut Command) {}
|
||||||
|
|
||||||
fn id(&self) -> &'static str {
|
|
||||||
"proton-muvm"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"Proton + muvm (Asahi)"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn description(&self) -> &'static str {
|
|
||||||
"Runs through Proton inside a muvm microVM, for Apple Silicon / Asahi Linux."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ use crate::{
|
|||||||
format::DropFormatArgs,
|
format::DropFormatArgs,
|
||||||
parser::{LaunchParameters, ParsedCommand},
|
parser::{LaunchParameters, ParsedCommand},
|
||||||
process_handlers::{
|
process_handlers::{
|
||||||
AsahiMuvmLauncher, LinuxNativeLauncher, MacLauncher, UMUCompatLauncher, UMUNativeLauncher,
|
AsahiMuvmLauncher, MacLauncher, UMUCompatLauncher, UMUNativeLauncher, WindowsLauncher,
|
||||||
WindowsCmdLauncher, WindowsDirectLauncher, WindowsLauncher, WindowsPowershellLauncher,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -55,13 +54,6 @@ pub struct LaunchOption {
|
|||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct ProcessHandlerOption {
|
|
||||||
id: String,
|
|
||||||
name: String,
|
|
||||||
description: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProcessManager<'_> {
|
impl ProcessManager<'_> {
|
||||||
pub fn new(app_handle: AppHandle) -> Self {
|
pub fn new(app_handle: AppHandle) -> Self {
|
||||||
let log_output_dir = DATA_ROOT_DIR.join("logs");
|
let log_output_dir = DATA_ROOT_DIR.join("logs");
|
||||||
@@ -84,22 +76,6 @@ impl ProcessManager<'_> {
|
|||||||
(Platform::Windows, Platform::Windows),
|
(Platform::Windows, Platform::Windows),
|
||||||
&WindowsLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
&WindowsLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
||||||
),
|
),
|
||||||
(
|
|
||||||
(Platform::Windows, Platform::Windows),
|
|
||||||
&WindowsDirectLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
(Platform::Windows, Platform::Windows),
|
|
||||||
&WindowsCmdLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
(Platform::Windows, Platform::Windows),
|
|
||||||
&WindowsPowershellLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
(Platform::Linux, Platform::Linux),
|
|
||||||
&LinuxNativeLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
(Platform::Linux, Platform::Linux),
|
(Platform::Linux, Platform::Linux),
|
||||||
&UMUNativeLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
&UMUNativeLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
||||||
@@ -125,7 +101,7 @@ impl ProcessManager<'_> {
|
|||||||
match self.processes.get_mut(&game_id) {
|
match self.processes.get_mut(&game_id) {
|
||||||
Some(process) => {
|
Some(process) => {
|
||||||
process.manually_killed = true;
|
process.manually_killed = true;
|
||||||
kill_process_tree(&process.handle)?;
|
process.handle.kill()?;
|
||||||
let exit_status = process.handle.wait()?;
|
let exit_status = process.handle.wait()?;
|
||||||
info!("exit status: {:?}", exit_status);
|
info!("exit status: {:?}", exit_status);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -212,21 +188,7 @@ impl ProcessManager<'_> {
|
|||||||
&self,
|
&self,
|
||||||
db_lock: &Database,
|
db_lock: &Database,
|
||||||
target_platform: &Platform,
|
target_platform: &Platform,
|
||||||
override_id: Option<&str>,
|
|
||||||
) -> Result<&(dyn ProcessHandler + Send + Sync), ProcessError> {
|
) -> Result<&(dyn ProcessHandler + Send + Sync), ProcessError> {
|
||||||
// An explicit override wins, as long as it's valid for the current platform.
|
|
||||||
if let Some(override_id) = override_id
|
|
||||||
&& let Some(handler) = self.game_launchers.iter().find(|e| {
|
|
||||||
let (e_current, e_target) = e.0;
|
|
||||||
e_current == self.current_platform
|
|
||||||
&& e_target == *target_platform
|
|
||||||
&& e.1.id() == override_id
|
|
||||||
&& e.1.valid_for_platform(db_lock, target_platform)
|
|
||||||
})
|
|
||||||
{
|
|
||||||
return Ok(handler.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self
|
Ok(self
|
||||||
.game_launchers
|
.game_launchers
|
||||||
.iter()
|
.iter()
|
||||||
@@ -242,44 +204,10 @@ impl ProcessManager<'_> {
|
|||||||
|
|
||||||
pub fn valid_platform(&self, platform: &Platform) -> bool {
|
pub fn valid_platform(&self, platform: &Platform) -> bool {
|
||||||
let db_lock = borrow_db_checked();
|
let db_lock = borrow_db_checked();
|
||||||
let process_handler = self.fetch_process_handler(&db_lock, platform, None);
|
let process_handler = self.fetch_process_handler(&db_lock, platform);
|
||||||
process_handler.is_ok()
|
process_handler.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_process_handlers(
|
|
||||||
&self,
|
|
||||||
game_id: String,
|
|
||||||
) -> Result<Vec<ProcessHandlerOption>, ProcessError> {
|
|
||||||
let db_lock = borrow_db_checked();
|
|
||||||
|
|
||||||
let meta = db_lock
|
|
||||||
.applications
|
|
||||||
.installed_game_version
|
|
||||||
.get(&game_id)
|
|
||||||
.cloned()
|
|
||||||
.ok_or(ProcessError::NotInstalled)?;
|
|
||||||
|
|
||||||
let target_platform = meta.target_platform;
|
|
||||||
|
|
||||||
let handlers = self
|
|
||||||
.game_launchers
|
|
||||||
.iter()
|
|
||||||
.filter(|e| {
|
|
||||||
let (e_current, e_target) = e.0;
|
|
||||||
e_current == self.current_platform
|
|
||||||
&& e_target == target_platform
|
|
||||||
&& e.1.valid_for_platform(&db_lock, &target_platform)
|
|
||||||
})
|
|
||||||
.map(|e| ProcessHandlerOption {
|
|
||||||
id: e.1.id().to_string(),
|
|
||||||
name: e.1.name().to_string(),
|
|
||||||
description: e.1.description().to_string(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(handlers)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_launch_options(game_id: String) -> Result<Vec<LaunchOption>, ProcessError> {
|
pub fn get_launch_options(game_id: String) -> Result<Vec<LaunchOption>, ProcessError> {
|
||||||
let db_lock = borrow_db_checked();
|
let db_lock = borrow_db_checked();
|
||||||
|
|
||||||
@@ -382,12 +310,7 @@ impl ProcessManager<'_> {
|
|||||||
|
|
||||||
let target_platform = meta.target_platform;
|
let target_platform = meta.target_platform;
|
||||||
|
|
||||||
let process_handler = self.fetch_process_handler(
|
let process_handler = self.fetch_process_handler(&db_lock, &target_platform)?;
|
||||||
&db_lock,
|
|
||||||
&target_platform,
|
|
||||||
game_version.user_configuration.override_handler.as_deref(),
|
|
||||||
)?;
|
|
||||||
debug!("using process handler {:?}", process_handler.id());
|
|
||||||
|
|
||||||
let (target_command, emulator) = match game_status {
|
let (target_command, emulator) = match game_status {
|
||||||
GameDownloadStatus::Installed {
|
GameDownloadStatus::Installed {
|
||||||
@@ -593,30 +516,6 @@ impl ProcessManager<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kill_process_tree(handle: &SharedChild) -> io::Result<()> {
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
{
|
|
||||||
// handle.kill() only terminates the launched process (often a cmd or
|
|
||||||
// powershell wrapper), orphaning the actual game. taskkill /T kills the
|
|
||||||
// whole process tree.
|
|
||||||
use std::os::windows::process::CommandExt;
|
|
||||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
|
||||||
let pid = handle.id().to_string();
|
|
||||||
let killed = Command::new("taskkill")
|
|
||||||
.args(["/F", "/T", "/PID", pid.as_str()])
|
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
|
||||||
.stdout(std::process::Stdio::null())
|
|
||||||
.stderr(std::process::Stdio::null())
|
|
||||||
.status()
|
|
||||||
.map(|status| status.success())
|
|
||||||
.unwrap_or(false);
|
|
||||||
if killed {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handle.kill()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ProcessHandler: Send + 'static {
|
pub trait ProcessHandler: Send + 'static {
|
||||||
fn create_launch_process(
|
fn create_launch_process(
|
||||||
&self,
|
&self,
|
||||||
@@ -630,8 +529,4 @@ pub trait ProcessHandler: Send + 'static {
|
|||||||
fn valid_for_platform(&self, db: &Database, target: &Platform) -> bool;
|
fn valid_for_platform(&self, db: &Database, target: &Platform) -> bool;
|
||||||
|
|
||||||
fn modify_command(&self, command: &mut Command);
|
fn modify_command(&self, command: &mut Command);
|
||||||
|
|
||||||
fn id(&self) -> &'static str;
|
|
||||||
fn name(&self) -> &'static str;
|
|
||||||
fn description(&self) -> &'static str;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ bytes = "1.11.0"
|
|||||||
chrono = "0.4.42"
|
chrono = "0.4.42"
|
||||||
client = { path = "../client", version = "0.1.0" }
|
client = { path = "../client", version = "0.1.0" }
|
||||||
database = { path = "../database", version = "0.1.0" }
|
database = { path = "../database", version = "0.1.0" }
|
||||||
|
droplet-rs = "0.7.3"
|
||||||
gethostname = "1.0.2"
|
gethostname = "1.0.2"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
http = "1.3.1"
|
http = "1.3.1"
|
||||||
|
|||||||
@@ -8,17 +8,8 @@
|
|||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env, fs::File, io::Write, panic::PanicHookInfo, path::Path, str::FromStr,
|
||||||
fs::File,
|
sync::nonpoison::Mutex, time::SystemTime,
|
||||||
io::Write,
|
|
||||||
panic::PanicHookInfo,
|
|
||||||
path::Path,
|
|
||||||
str::FromStr,
|
|
||||||
sync::{
|
|
||||||
atomic::{AtomicBool, Ordering},
|
|
||||||
nonpoison::Mutex,
|
|
||||||
},
|
|
||||||
time::SystemTime,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ::client::{
|
use ::client::{
|
||||||
@@ -269,7 +260,6 @@ pub fn run() {
|
|||||||
get_autostart_enabled,
|
get_autostart_enabled,
|
||||||
open_process_logs,
|
open_process_logs,
|
||||||
get_launch_options,
|
get_launch_options,
|
||||||
get_process_handlers,
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
::process::compat::fetch_proton_paths,
|
::process::compat::fetch_proton_paths,
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@@ -369,17 +359,8 @@ pub fn run() {
|
|||||||
)
|
)
|
||||||
.expect("Failed to generate menu");
|
.expect("Failed to generate menu");
|
||||||
|
|
||||||
if env::var("NO_TRAY_ICON").is_ok_and(|value| value.to_lowercase() == "true") {
|
|
||||||
TRAY_DISABLED.store(true, Ordering::Relaxed);
|
|
||||||
} else if !tray_icon_supported() {
|
|
||||||
warn!(
|
|
||||||
"appindicator library not available at runtime, disabling system tray icon"
|
|
||||||
);
|
|
||||||
TRAY_DISABLED.store(true, Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
run_on_tray(|| {
|
run_on_tray(|| {
|
||||||
let tray = TrayIconBuilder::new()
|
TrayIconBuilder::new()
|
||||||
.icon(
|
.icon(
|
||||||
app.default_window_icon()
|
app.default_window_icon()
|
||||||
.expect("Failed to get default window icon")
|
.expect("Failed to get default window icon")
|
||||||
@@ -402,12 +383,8 @@ pub fn run() {
|
|||||||
warn!("menu event not handled: {:?}", event.id);
|
warn!("menu event not handled: {:?}", event.id);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.build(app);
|
.build(app)
|
||||||
|
.expect("error while setting up tray menu");
|
||||||
if let Err(e) = tray {
|
|
||||||
warn!("failed to set up system tray icon, disabling tray: {e}");
|
|
||||||
TRAY_DISABLED.store(true, Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -468,30 +445,13 @@ pub fn run() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static TRAY_DISABLED: AtomicBool = AtomicBool::new(false);
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
fn tray_icon_supported() -> bool {
|
|
||||||
[
|
|
||||||
"libayatana-appindicator3.so.1",
|
|
||||||
"libappindicator3.so.1",
|
|
||||||
"libayatana-appindicator3.so",
|
|
||||||
"libappindicator3.so",
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
.any(|name| unsafe { libloading::Library::new(name) }.is_ok())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
|
||||||
fn tray_icon_supported() -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_on_tray<T: FnOnce()>(f: T) {
|
fn run_on_tray<T: FnOnce()>(f: T) {
|
||||||
if TRAY_DISABLED.load(Ordering::Relaxed) {
|
if match std::env::var("NO_TRAY_ICON") {
|
||||||
return;
|
Ok(s) => s.to_lowercase() != "true",
|
||||||
|
Err(_) => true,
|
||||||
|
} {
|
||||||
|
(f)();
|
||||||
}
|
}
|
||||||
(f)();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor
|
// TODO: Refactor
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||||||
use process::{
|
use process::{
|
||||||
PROCESS_MANAGER,
|
PROCESS_MANAGER,
|
||||||
error::ProcessError,
|
error::ProcessError,
|
||||||
process_manager::{LaunchOption, ProcessHandlerOption, ProcessManager},
|
process_manager::{LaunchOption, ProcessManager},
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tauri::AppHandle;
|
use tauri::AppHandle;
|
||||||
@@ -16,11 +16,6 @@ pub fn get_launch_options(id: String) -> Result<Vec<LaunchOption>, ProcessError>
|
|||||||
Ok(launch_options)
|
Ok(launch_options)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_process_handlers(id: String) -> Result<Vec<ProcessHandlerOption>, ProcessError> {
|
|
||||||
PROCESS_MANAGER.lock().get_process_handlers(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(tag = "result", content = "data")]
|
#[serde(tag = "result", content = "data")]
|
||||||
pub enum LaunchResult {
|
pub enum LaunchResult {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"active": true,
|
"active": true,
|
||||||
"targets": ["nsis", "deb", "rpm", "dmg"],
|
"targets": ["nsis", "deb", "rpm", "dmg", "appimage"],
|
||||||
"windows": {
|
"windows": {
|
||||||
"nsis": {
|
"nsis": {
|
||||||
"installMode": "both"
|
"installMode": "both"
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default defineConfig({
|
|||||||
{ slug: "user" },
|
{ slug: "user" },
|
||||||
{
|
{
|
||||||
label: "Install",
|
label: "Install",
|
||||||
items: [{ autogenerate: { directory: "user/install" } }],
|
autogenerate: { directory: "user/install" },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Usage",
|
label: "Usage",
|
||||||
@@ -65,26 +65,25 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Going further",
|
label: "Going further",
|
||||||
items: [{ autogenerate: { directory: "admin/going-further" } }],
|
autogenerate: { directory: "admin/going-further" },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Metadata",
|
label: "Metadata",
|
||||||
items: [{ autogenerate: { directory: "admin/metadata" } }],
|
autogenerate: { directory: "admin/metadata" },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Authentication",
|
label: "Authentication",
|
||||||
items: [{ autogenerate: { directory: "admin/authentication" } }],
|
autogenerate: { directory: "admin/authentication" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Reference",
|
label: "Reference",
|
||||||
items: [{ autogenerate: { directory: "reference" } }],
|
autogenerate: { directory: "reference" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
customCss: ["./src/styles/drop.css"],
|
customCss: ["./src/styles/drop.css"],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
site: "https://droposs.org",
|
site: "https://docs-next.droposs.org/",
|
||||||
base: "/docs",
|
|
||||||
});
|
});
|
||||||
@@ -10,11 +10,11 @@
|
|||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/starlight": "^0.40.0",
|
"@astrojs/starlight": "^0.37.4",
|
||||||
"astro": "^6.4.8",
|
"astro": "^5.6.1",
|
||||||
"sharp": "^0.35.2",
|
"sharp": "^0.34.2",
|
||||||
"starlight-image-zoom": "^0.14.2",
|
"starlight-image-zoom": "^0.13.2",
|
||||||
"starlight-links-validator": "^0.24.1",
|
"starlight-links-validator": "^0.19.2",
|
||||||
"starlight-theme-rapide": "^0.5.2"
|
"starlight-theme-rapide": "^0.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
onlyBuiltDependencies:
|
||||||
|
- esbuild
|
||||||
|
- sharp
|
||||||
|
Before Width: | Height: | Size: 696 B After Width: | Height: | Size: 696 B |
|
Before Width: | Height: | Size: 436 B After Width: | Height: | Size: 436 B |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
@@ -28,7 +28,7 @@ For convenience's sake, we can also specify file extensions for Drop's auto-dete
|
|||||||
|
|
||||||
Add a launch executable for every platform you want to support. The options are fairly self-explanatory, but make sure to use the `{rom}` placeholder, and optionally add the file extensions.
|
Add a launch executable for every platform you want to support. The options are fairly self-explanatory, but make sure to use the `{rom}` placeholder, and optionally add the file extensions.
|
||||||
|
|
||||||
Read the [Command Parsing](/docs/reference/command-parsing/) article to understand how it's parsed and substituted.
|
Read the [Command Parsing](/reference/command-parsing/) article to understand how it's parsed and substituted.
|
||||||
|
|
||||||
3. ## Import your game
|
3. ## Import your game
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ If you're using a library source that supports versioning, you can add and impor
|
|||||||
|
|
||||||
2. ### Follow the import guide again
|
2. ### Follow the import guide again
|
||||||
|
|
||||||
Follow the [import guide again](/docs/admin/guides/import-version/), but this time for your new version folder.
|
Follow the [import guide again](/admin/guides/import-version/), but this time for your new version folder.
|
||||||
|
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ You can stack many "update mode" versions on top of each other, and they will pi
|
|||||||
|
|
||||||
2. ### Follow the import guide again
|
2. ### Follow the import guide again
|
||||||
|
|
||||||
Follow the [import guide again](/docs/admin/guides/import-version/), but this time for your new version folder.
|
Follow the [import guide again](/admin/guides/import-version/), but this time for your new version folder.
|
||||||
|
|
||||||
3. ### Before import, enable update mode
|
3. ### Before import, enable update mode
|
||||||
|
|
||||||
@@ -3,7 +3,7 @@ title: Setting up OIDC
|
|||||||
---
|
---
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
You can find reference information in the [OIDC authentication docs](/docs/admin/authentication/oidc/).
|
You can find reference information in the [OIDC authentication docs](/admin/authentication/oidc/).
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Authentik
|
## Authentik
|
||||||
@@ -10,7 +10,7 @@ To import games and start using Drop, you must first create a library to import
|
|||||||
|
|
||||||
1. **Decide on a library layout.**
|
1. **Decide on a library layout.**
|
||||||
|
|
||||||
Drop supports different layouts for your files on disk, you can read more about them in the [Library Sources](/docs/reference/library-sources) reference section.
|
Drop supports different layouts for your files on disk, you can read more about them in the [Library Sources](/reference/library-sources) reference section.
|
||||||
|
|
||||||
2. **Mount your library in the Docker container.**
|
2. **Mount your library in the Docker container.**
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ To import games and start using Drop, you must first create a library to import
|
|||||||
- `/mnt/media/my-drop-library` is the path to your library.
|
- `/mnt/media/my-drop-library` is the path to your library.
|
||||||
- `/library` is a **unique** path inside the container. **Use something else if another volume mounts to `/library`**.
|
- `/library` is a **unique** path inside the container. **Use something else if another volume mounts to `/library`**.
|
||||||
|
|
||||||
If you followed the [Quickstart](/docs/admin/quickstart/) guide, you'll have already set up a library at `./library` pointing to `/library` within the container. You may want to instead edit that line in the `volumes` section to point to where your library is located.
|
If you followed the [Quickstart](/admin/quickstart/) guide, you'll have already set up a library at `./library` pointing to `/library` within the container. You may want to instead edit that line in the `volumes` section to point to where your library is located.
|
||||||
|
|
||||||
3. **Open library source interface in Admin Dashboard.**
|
3. **Open library source interface in Admin Dashboard.**
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ Drop automatically parses and formats the URL, so there are no requirements on t
|
|||||||
|
|
||||||
## LAN
|
## LAN
|
||||||
|
|
||||||
The `compose.yaml` provided in the [Quickstart guide](/docs/admin/quickstart/) already exposes the Drop instance on port 3000. If you're on the same LAN as your Drop instance, you can find it's IP and then use:
|
The `compose.yaml` provided in the [Quickstart guide](/admin/quickstart/) already exposes the Drop instance on port 3000. If you're on the same LAN as your Drop instance, you can find it's IP and then use:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://[instance IP]:3000
|
http://[instance IP]:3000
|
||||||
@@ -60,7 +60,7 @@ Once you've got a library set up, and have imported a game, you can import a ver
|
|||||||
A installer version uses "setup mode". Enable the option, and then add the installer executable in setup commands.
|
A installer version uses "setup mode". Enable the option, and then add the installer executable in setup commands.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
Setup and launch commands are parsed in a cross-platform, POSIX style. It's not relevant for simple setups, but useful to know. Read more about it in [Command Parsing](/docs/reference/command-parsing/).
|
Setup and launch commands are parsed in a cross-platform, POSIX style. It's not relevant for simple setups, but useful to know. Read more about it in [Command Parsing](/reference/command-parsing/).
|
||||||
:::
|
:::
|
||||||
|
|
||||||
6. ### **Wait for import.**
|
6. ### **Wait for import.**
|
||||||
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
@@ -40,7 +40,7 @@ services:
|
|||||||
|
|
||||||
**The main things in this `compose.yaml` is the volumes attached to the `drop` service:**
|
**The main things in this `compose.yaml` is the volumes attached to the `drop` service:**
|
||||||
|
|
||||||
1. `./library` is where you will put your games to be imported into Drop. See '[Creating a library](/docs/admin/guides/creating-library/)' once you're set up.
|
1. `./library` is where you will put your games to be imported into Drop. See '[Creating a library](/admin/guides/creating-library/)' once you're set up.
|
||||||
2. `./data` is where Drop will store anything that's using the default file-system backed storage system. Typically, these are objects.
|
2. `./data` is where Drop will store anything that's using the default file-system backed storage system. Typically, these are objects.
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
@@ -7,7 +7,7 @@ hero:
|
|||||||
file: ../../assets/drop.svg
|
file: ../../assets/drop.svg
|
||||||
actions:
|
actions:
|
||||||
- text: Quickstart
|
- text: Quickstart
|
||||||
link: /docs/admin/quickstart
|
link: /admin/quickstart
|
||||||
icon: right-arrow
|
icon: right-arrow
|
||||||
- text: Download client
|
- text: Download client
|
||||||
link: https://droposs.org/download
|
link: https://droposs.org/download
|
||||||
@@ -89,7 +89,7 @@ Drop's [dockerfile](https://github.com/Drop-OSS/drop/blob/develop/Dockerfile) pr
|
|||||||
:::
|
:::
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install prisma@7.7.0 dotenv # dotenv is required
|
npm install prisma@7.3.0 dotenv # dotenv is required
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, with your database running:
|
Then, with your database running:
|
||||||
@@ -21,40 +21,12 @@ Then, what happens with this, depends on the type of game we're launching:
|
|||||||
|
|
||||||
## Normal (no emulator)
|
## Normal (no emulator)
|
||||||
|
|
||||||
Drop reconstructs the original shell string, and passes it into a platform-specific command wrapper, called a **launch method**. Drop picks a sensible launch method automatically, but you can override it per-game for troubleshooting — see [Launch methods](#launch-methods) below.
|
Drop reconstructs the original shell string, and passes it into platform-specific command wrappers. For Windows, this means nothing. For Linux, it gets wrapped in `umu-run`.
|
||||||
|
|
||||||
By default, on Windows the command is launched based on its file type: `.exe` files run directly, `.bat` and `.cmd` files run through `cmd`, `.ps1` files run through PowerShell, and anything else is handed to `cmd` so builtins, `PATHEXT` resolution and `%VAR%` expansion all work. On Linux, native games run directly on the host, while games targeting Windows are wrapped in `umu-run` (with Proton).
|
|
||||||
|
|
||||||
It is then parsed again, and then passed into process creation, mapping the environment variable, command, and arguments into their respective platform-dependent places.
|
It is then parsed again, and then passed into process creation, mapping the environment variable, command, and arguments into their respective platform-dependent places.
|
||||||
|
|
||||||
Drop logs out it's final parsed command, if you want to look at it in the client logs.
|
Drop logs out it's final parsed command, if you want to look at it in the client logs.
|
||||||
|
|
||||||
## Launch methods
|
|
||||||
|
|
||||||
The wrapper Drop uses to start a game is called a **launch method** (a *process handler* internally). Drop automatically selects the best available method for each game, but if a game won't launch you can override it under **Game Options → Launch → Launch method**.
|
|
||||||
|
|
||||||
Only methods supported by your current platform (and the game's target platform) are listed, each with a short description in the client.
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
|
|
||||||
| Method | Description |
|
|
||||||
| ------ | ----------- |
|
|
||||||
| **Automatic** *(default)* | Detects the file type and launches it directly, or through `cmd` or PowerShell. |
|
|
||||||
| **Direct executable** | Runs the executable directly, without a shell. |
|
|
||||||
| **Command Prompt (cmd)** | Launches through `cmd.exe`. Supports batch files, builtins and `%VAR%` expansion. |
|
|
||||||
| **PowerShell** | Runs the command as a PowerShell script (`-File`). |
|
|
||||||
|
|
||||||
### Linux
|
|
||||||
|
|
||||||
| Method | Description |
|
|
||||||
| ------ | ----------- |
|
|
||||||
| **Native (direct)** *(default for Linux games)* | Runs the native Linux game directly on the host. |
|
|
||||||
| **Steam Linux Runtime (umu-run)** | Runs the native Linux game inside `umu-run`'s Steam Linux Runtime. Requires [UMU launcher](/docs/user/usage/proton/). |
|
|
||||||
| **Proton (umu-run)** *(default for Windows games)* | Runs a Windows game through Proton, using `umu-run`. Requires [Proton](/docs/user/usage/proton/). |
|
|
||||||
| **Proton + muvm (Asahi)** | Runs a Windows game through Proton inside a muvm microVM, for Apple Silicon / Asahi Linux. |
|
|
||||||
|
|
||||||
On macOS, games are always launched directly.
|
|
||||||
|
|
||||||
## Emulators
|
## Emulators
|
||||||
For emulators, we have the "emulator version" (version containing the emulator), and the "emulated version" (version containing the ROM).
|
For emulators, we have the "emulator version" (version containing the emulator), and the "emulated version" (version containing the ROM).
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ In the UI, you'll be prompted to "import" each folder separately:
|
|||||||
|
|
||||||
So your game has gotten an update and you've got new files. All you need to do is create a new version folder inside the game folder, and move all the files you have into that folder. Then, import it within the Drop admin UI.
|
So your game has gotten an update and you've got new files. All you need to do is create a new version folder inside the game folder, and move all the files you have into that folder. Then, import it within the Drop admin UI.
|
||||||
|
|
||||||
If you have files that you're supposed to **paste over the previous version**, Drop supports that! Read [Update mode](/docs/reference/update-mode/) to find out more.
|
If you have files that you're supposed to **paste over the previous version**, Drop supports that! Read [Update mode](/reference/update-mode/) to find out more.
|
||||||
|
|
||||||
# Compatibility (flat-style)
|
# Compatibility (flat-style)
|
||||||
|
|
||||||
@@ -4,4 +4,4 @@ title: Getting Started
|
|||||||
|
|
||||||
Drop clients are available for download from [our website](https://droposs.org/download), or follow one of our installation guides on the sidebar. Download the correct version for your platform, and open it up.
|
Drop clients are available for download from [our website](https://droposs.org/download), or follow one of our installation guides on the sidebar. Download the correct version for your platform, and open it up.
|
||||||
|
|
||||||
The client will walk you through the setup and sign-in process to get started. You'll need a Drop instance you can connect to, and an account on the server. If you don't have one, you can follow the [Quickstart](/docs/admin/quickstart/) guide to set up your own.
|
The client will walk you through the setup and sign-in process to get started. You'll need a Drop instance you can connect to, and an account on the server. If you don't have one, you can follow the [Quickstart](/admin/quickstart/) guide to set up your own.
|
||||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |