Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
e57f232
Refactor inGamePresenceData GraphQL query
BellezaEmporium May 4, 2026
0d67350
Add connection directive to SearchPlayer query
BellezaEmporium May 4, 2026
88e02eb
Add GraphQL query for AddOnGameCard
BellezaEmporium May 4, 2026
10725a7
Add lifecycleStatusFragment to GraphQL schema
BellezaEmporium May 4, 2026
8c16ecb
use stable functions + game download safeguard
Jun 1, 2026
078e28e
upd deps
BellezaEmporium Jun 10, 2026
fb42bea
Add chat.proto with conversation and typing messages
BellezaEmporium Jun 18, 2026
3ab2b3d
Add new fields to rtm.proto for player context and events
BellezaEmporium Jun 18, 2026
2b80a86
Update rtm.proto
BellezaEmporium Jun 18, 2026
871cf57
rewrite w/ tokio async
BellezaEmporium Jun 25, 2026
feed237
add fr-FR, small changes
BellezaEmporium Jun 26, 2026
8e472d8
Update connection.rs
BellezaEmporium Jun 26, 2026
cdbfe79
feat: generate lsx challenge key
BellezaEmporium Jun 29, 2026
e64f1d5
add safeguards, bump resolver to 3 to match rust ver, make use of wor…
BellezaEmporium Jun 30, 2026
67a8ac9
add fallback on deps in resolver settings, remove lazy_static for std…
BellezaEmporium Jul 2, 2026
296ec4e
WIP DO NOT USE
BellezaEmporium Jul 3, 2026
ce48ac2
WIP
BellezaEmporium Jul 5, 2026
4066929
fixes, preliminary cleanups, will need further cleanup
BellezaEmporium Jul 24, 2026
20a2c2c
.
BellezaEmporium Jul 27, 2026
5e30585
Update rtm.proto
BellezaEmporium Jul 31, 2026
c8425cf
Update requests.proto
BellezaEmporium Jul 31, 2026
65c0ebe
Update common.proto
BellezaEmporium Jul 31, 2026
855dc03
Update chat.proto
BellezaEmporium Jul 31, 2026
e99270a
Update chat.proto
BellezaEmporium Jul 31, 2026
e8d2bf8
Update README.md
BellezaEmporium Jul 31, 2026
2a80188
Update requests.proto
BellezaEmporium Jul 31, 2026
12cd2be
Update responses.proto
BellezaEmporium Jul 31, 2026
e827e08
Add CommunicationType and ChannelMessageType enums
BellezaEmporium Aug 1, 2026
3ff815a
switch to Antelope protocol based on last RTM proto findings, keep de…
BellezaEmporium Aug 1, 2026
dfece6c
switched to Antelope protocol properly, working base RTM
BellezaEmporium Aug 1, 2026
f63525b
properly rewrite social links
BellezaEmporium Aug 1, 2026
a4ce811
Update README.md
BellezaEmporium Aug 1, 2026
5901d47
Update README.md
BellezaEmporium Aug 1, 2026
3ab3d38
Update README.md
BellezaEmporium Aug 1, 2026
af33516
Implement touchup service into maxima-service, elevates request directly
BellezaEmporium Aug 13, 2026
920fbda
File Exclusion
sjp761 Jan 24, 2026
600a5f0
Per game wine prefixes
sjp761 Jan 25, 2026
7753037
Refresh UI after game is done downloading or located
sjp761 Mar 18, 2026
a73c725
Wine improvements
sjp761 May 21, 2026
796ab18
Trim null byte in incoming LSX messages, fixes game issues
sjp761 Jul 27, 2026
60a7b6b
Rename MAXIMA_WINE_SCRIPT to MAXIMA_UMU_LOCATION
sjp761 Aug 1, 2026
5bdcec5
Update touchup handling stuff for service (Linux still runs through n…
sjp761 Aug 14, 2026
53c00f4
Load zlib state only if file is not 0 bytes, set write or append depe…
sjp761 Aug 14, 2026
98027e7
Fix game path read on registry install check fallback
sjp761 Aug 21, 2026
7de606a
Proper downloading content (only increments when file in finished wri…
sjp761 Aug 21, 2026
8521e64
Fix current download not showing (displays progress properly as well)
sjp761 Aug 22, 2026
d492e2b
Merge pull request #1 from sjp761/belleza-rebase
BellezaEmporium Aug 23, 2026
d0114bc
fix french translation, usual dep update, fix cli potential hiccup & …
BellezaEmporium Sep 1, 2026
d38e92e
cargo fmt
BellezaEmporium Sep 1, 2026
53e8dbb
Disable state serialization on Linux, cleanup handling of manifest an…
sjp761 Aug 26, 2026
210a158
Create gameinfo JSON when touchup is not needed, improve PathBuf hand…
sjp761 Aug 26, 2026
7e4df3a
Refactor and cleanup LSX Server
sjp761 Sep 2, 2026
0aaa4da
Fix maxima-cli blocking, track bytes as they are being written, check…
sjp761 Sep 3, 2026
3beb51a
Remove unused dependencies
sjp761 Sep 4, 2026
7769bd3
Quick gameinfo cleanups
sjp761 Sep 9, 2026
2628c5d
Cargo clippy fix
sjp761 Sep 9, 2026
8e38031
cargo fmt and cargo fix
sjp761 Sep 9, 2026
0964d9b
Ignore Cargo.lock (maintainer request)
sjp761 Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[resolver]
incompatible-rust-versions = "fallback"
27 changes: 14 additions & 13 deletions .github/workflows/build-ci.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Maxima Build

on: [push]
on: [push, pull_request]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
group: ${{ github.workflow }}-${{ github.event.pull_request && github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
Expand All @@ -15,9 +15,9 @@ jobs:
strategy:
fail-fast: false
matrix:
rust-version: [nightly]
rust-version: ["1.96", "stable", "nightly"]
experimental: [false, false, true]
os: [ubuntu-latest, windows-latest]
experimental: [false]

env:
CARGO_TERM_COLOR: always
Expand All @@ -26,18 +26,10 @@ jobs:
- name: Checkout the repo
uses: actions/checkout@v4

- name: Cache Rust ${{ matrix.rust-version }}
uses: actions/cache@v3
with:
path: ${{ github.workspace }}\rust\.rustup
key: rust-${{ matrix.rust-version }}-${{ hashFiles('**/rust-toolchain') }}

- name: Setup Rust ${{ matrix.rust-version }}
uses: actions-rs/toolchain@v1
uses: dtolnay/rust-toolchain@master
with:
profile: minimal
toolchain: ${{ matrix.rust-version }}
override: true
components: rustfmt, clippy

- name: Install Protoc
Expand All @@ -56,6 +48,15 @@ jobs:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/master' }}

- name: Clippy
run: cargo clippy --workspace -- -D warnings

- name: Format check
run: cargo fmt --all -- --check

- name: Tests
run: cargo test --workspace

- name: Build Maxima
if: runner.os == 'Windows'
run: |
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/target
/.vscode
/.idea

Cargo.lock
Cargo.lock
57 changes: 53 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
resolver = "2"
resolver = "3"
members = [
"maxima-bootstrap",
"maxima-cli",
Expand All @@ -10,9 +10,58 @@ members = [
"maxima-resources",
]

[workspace.dependencies]
# Common Workspace Dependencies for all Maxima libs
tokio = { version = "1.53.1", features = ["rt-multi-thread", "time", "net", "sync", "macros", "fs", "process"] }
serde = { version = "1.0.229", features = ["derive"] }
serde_json = "1.0.151"
rustls = { version = "0.23.43", features = ["aws-lc-rs"] }
reqwest = { version = "0.13.4", features = ["stream", "rustls"], default-features = false }
base64 = "0.23.1"
thiserror = "2.0.20"
anyhow = "1.0.104"
log = "0.4.34"
regex = "1.13.1"
futures = "0.3.34"
clap = { version = "4.6.6", features = ["derive"] }
inquire = "0.9.4"
strum = { version = "0.28.0", features = ["derive"] }
strum_macros = "0.28.0"
url = "2.5.8"
directories = "6.0.0"
hex = "0.4.3"

# Common Target Specific Dependencies
windows-sys = { version = "0.61.2", features = ["Win32_System", "Win32_System_Threading", "Win32_System_Console", "Win32_System_Console"] }
winreg = "0.56.0"
windows-service = "0.8.1"
is_elevated = "0.1.2"

[patch.crates-io]
async-compression = { git = "https://github.com/sjp761/async-compression.git", rev = "a226c72f754f942ad187cc65cb1f03df5ae26b7b", version = "0.4.42" }
flate2 = { git = "https://github.com/sjp761/flate2-rs.git", rev = "45fc9f6a56a97513b285029fee14213a2d0fe2e5", version = "1.1.10" }

[workspace.package]
version = "0.1.0"
edition = "2024"
authors = ["Nick Whelan <cooldood909@gmail.com>", "Sean Kahler <sean@battleda.sh>", "Maxima Contributors"]
rust-version = "1.96.1"

[profile.release]
strip = true
lto = "thin"
codegen-units = 1
panic = "abort"

[patch.crates-io]
flate2 = { git = 'https://github.com/ArmchairDevelopers/flate2-rs.git' }
async-compression = { git = 'https://github.com/ArmchairDevelopers/async-compression.git' }
[profile.release-debug]
inherits = "release"
strip = false
debug = 1

[profile.dev]
opt-level = 0
debug = true
split-debuginfo = "unpacked"

[profile.dev.package."*"]
opt-level = 1
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Maxima itself is a library (`maxima-lib`), with provided CLI (`maxima-cli`), TUI

![UI](images/UI.png)

**Current developing stack:**

Rust 1.90.1 | UI : egui / glow | Requests : reqwest | Async support & work : tokio | Windows layer : windows-sys | Linux layer : homemade | macOS layer : homemade and many under the hood plugins that make this program possible.

**Features:**
- EA Authentication
- Downloading/Updating games
Expand All @@ -24,20 +28,21 @@ Maxima itself is a library (`maxima-lib`), with provided CLI (`maxima-cli`), TUI
- Locating games (aka. game importing)
- Running games under [proton](https://github.com/GloriousEggroll/proton-ge-custom) on Linux/SteamDeck
- `proton-ge` is automatically installed together with [umu](https://github.com/Open-Wine-Components/umu-launcher).

**In-Dev:**
- macOS support
- Support for launching Maxima through Epic/Steam

**Developer Roadmap:**
- macOS support (sjp761)
- Chat system
- Friend Adding/Removing/Inviting
- Support for launching Maxima through Epic/Steam (Link2EA protocol)
- Cleaner/Stabler downloader implementation

**Planned:**
- Library documentation/examples
- Support for installing DLCs
- Full EA Desktop interoperability. Games installed with EA Desktop already appear on Maxima, but to take it a step further we'd like the ability to, for example, start a download on EA Desktop and continue it on Maxima.
- Cleaner/Stabler downloader implementation
- Progressive/Selective installs
- Some games are able to start without being fully installed, and some games contain language-specific files.
- Support for the store (buying games)
- Friend Adding/Removing/Inviting
- Status setting; locked to "online" at the moment
- Refactoring Maxima to new architecture allowing multiple frontends to co-exist

Expand Down
37 changes: 9 additions & 28 deletions maxima-bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,38 +1,19 @@
[package]
name = "maxima-bootstrap"
description = "Maxima handler for custom EA protocols"
version = "0.1.0"
authors = ["Sean Kahler <sean@battleda.sh>"]
edition = "2021"
version = { workspace = true }
authors = { workspace = true }
edition = { workspace = true }

[dependencies]
maxima-lib = { path = "../maxima-lib" }
tokio = { version = "1.28.2", features = [
"full",
"rt",
"rt-multi-thread",
"time",
"net",
] }
serde = { version = "1.0.164", features = ["derive"] }
serde_json = "1.0.97"
reqwest = { version = "0.11.18", features = ["stream", "rustls-tls"], default-features = false }
base64 = "0.21.2"
url = "2.4.0"
querystring = "1.1.0"
tokio = { workspace = true }
serde_json = { workspace = true }
reqwest = { workspace = true, features = ["query"] }
base64 = { workspace = true }
url = { workspace = true }
urlencoding = "2.1.3"
thiserror = "2.0.12"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = [
"memoryapi",
"handleapi",
"synchapi",
"wincon",
"consoleapi",
] }
winreg = "0.50.0"
windows-service = "0.6.0"
thiserror = { workspace = true }

[target.'cfg(target_os = "macos")'.dependencies]
cacao = "0.3.2"
Expand Down
53 changes: 36 additions & 17 deletions maxima-bootstrap/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use std::string::FromUtf8Error;
use thiserror::Error;
use tokio::process::Command;

use base64::{engine::general_purpose, Engine};
use base64::{Engine, engine::general_purpose};
use maxima::core::launch::BootstrapLaunchArgs;
use maxima::util::BackgroundServiceControlError;
use maxima::util::native::NativeError;
#[cfg(windows)]
use maxima::util::service::{is_service_valid, register_service};
use maxima::util::BackgroundServiceControlError;
use url::Url;
use url::{Url, form_urlencoded};

#[cfg(target_os = "macos")]
mod macos;
Expand Down Expand Up @@ -70,19 +70,18 @@ async fn handle_launch_args() -> Result<bool, RunError> {

let result = run(&args).await;
if cfg!(debug_assertions) || std::env::var("MAXIMA_DEBUG").is_ok() {
println!("Args: {:?}", &args);
println!("Args: {:?}", args);

let str_result = result
.as_ref()
.map_err(|e| {
let source = e.source();
let error_str = if source.is_some() {

if source.is_some() {
source.unwrap().to_string()
} else {
e.to_string()
};

error_str
}
})
.err()
.unwrap_or("Success".to_string());
Expand Down Expand Up @@ -116,22 +115,24 @@ async fn platform_launch(args: BootstrapLaunchArgs) -> Result<(), NativeError> {
let mut binding = Command::new(args.path);
let child = binding.args(args.args);

let status = child.spawn()?.wait().await?;
let _status = child.spawn()?.wait().await?;
// bail!("{}", status.code().unwrap());
Ok(())
}

#[cfg(unix)]
async fn platform_launch(args: BootstrapLaunchArgs) -> Result<(), NativeError> {
use maxima::unix::wine::run_wine_command;
use maxima::unix::wine::CommandType;
use maxima::unix::wine::run_wine_command;
use maxima::unix::wine::wine_prefix_dir;

run_wine_command(
args.path,
args.path.into(),
Some(args.args),
None,
false,
CommandType::WaitForExitAndRun,
&wine_prefix_dir(&args.slug).unwrap(),
)
.await?;

Expand All @@ -153,20 +154,30 @@ async fn run(args: &[String]) -> Result<bool, RunError> {

if arg.starts_with("origin2") {
let url = Url::parse(arg)?;
let query = querystring::querify(url.query().unwrap());
let _offer_id = query.iter().find(|(x, _)| *x == "offerIds").unwrap().1;
let cmd_params = query.iter().find(|(x, _)| *x == "cmdParams").unwrap().1;
let mut offer_id = None;
let mut cmd_params = None;

for (key, value) in form_urlencoded::parse(url.query().unwrap_or_default().as_bytes()) {
match key.as_ref() {
"offerIds" => offer_id = Some(value),
"cmdParams" => cmd_params = Some(value),
_ => {}
}
}

let _offer_id = offer_id.unwrap();
let cmd_params = cmd_params.unwrap();

let mut child = Command::new(current_exe()?.with_file_name("maxima-cli.exe"));
child.env(
"MAXIMA_LAUNCH_ARGS",
urlencoding::decode(cmd_params)?
urlencoding::decode(cmd_params.as_ref())?
.into_owned()
.replace("\\\"", "\""),
);
println!(
"{}",
urlencoding::decode(cmd_params)?
urlencoding::decode(cmd_params.as_ref())?
.into_owned()
.replace("\\\"", "\"")
);
Expand All @@ -178,7 +189,15 @@ async fn run(args: &[String]) -> Result<bool, RunError> {
}

if arg.starts_with("qrc") {
let query = arg.split("login_successful.html?").collect::<Vec<&str>>()[1];
let raw_query = arg
.split("login_successful.html?")
.nth(1)
.unwrap_or_default();
let mut serializer = form_urlencoded::Serializer::new(String::new());
for (key, value) in form_urlencoded::parse(raw_query.as_bytes()) {
serializer.append_pair(key.as_ref(), value.as_ref());
}
let query = serializer.finish();
reqwest::get(format!("http://127.0.0.1:31033/auth?{}", query)).await?;

return Ok(true);
Expand Down
28 changes: 11 additions & 17 deletions maxima-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
[package]
name = "maxima-cli"
version = "0.1.0"
authors = ["Sean Kahler <sean@battleda.sh>"]
edition = "2021"
version = { workspace = true }
authors = { workspace = true }
edition = { workspace = true }

[dependencies]
maxima-lib = { path = "../maxima-lib" }
clap = { version = "4.3.5", features = [ "derive" ] }
tokio = { version = "1.28.2", features = [ "full", "rt", "rt-multi-thread", "time", "net" ] }
serde = { version = "1.0.164", features = [ "derive" ] }
serde_json = "1.0.97"
anyhow = "1.0.71"
lazy_static = "1.4.0"
base64 = "0.21.2"
log = "0.4.19"
regex = "1.8.4"
inquire = "0.6.2"
futures = "0.3.30"
clap = { workspace = true }
tokio = { workspace = true }
anyhow = { workspace = true }
log = { workspace = true }
regex = { workspace = true }
inquire = { workspace = true }
rustls = { workspace = true }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = [ "memoryapi", "handleapi", "synchapi", "wincon", "consoleapi" ] }
winreg = "0.50.0"
is_elevated = "0.1.2"
is_elevated = { workspace = true }

[build-dependencies]
maxima-resources = { path = "../maxima-resources" }
Expand Down
Loading
Loading