Server-side savegames: Rust service with a shared savegame list in the menu, fallback to files
- server/: small axum service storing savegames as files (1 MB each, 500 MB total, rate limit) - docker compose: second container with a volume; nginx forwards /api/ - JS plugin: asynchronous HTTP requests polled by the game - Save/Load open a list page (name field, new, overwrite, load, delete with confirmation) - Without a reachable service the game keeps using savegame files and the browser autosave Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c5b7896609
commit
7f4324abca
17 files changed
+1390
-30
No files matched your search
+36
-1
@@ -1,6 +1,13 @@
|
||||
// Browser integration via our own miniquad JS plugin (www/dc_plugin.js):
|
||||
// persistent key/value storage (localStorage), a cache that is written to storage when the
|
||||
// page is hidden or closed, file download and file upload. Native builds use simple fallbacks.
|
||||
// page is hidden or closed, file download, file upload and HTTP requests.
|
||||
// Native builds use simple fallbacks.
|
||||
|
||||
// Result of an HTTP request: status 0 means the service could not be reached
|
||||
pub struct HttpResult {
|
||||
pub status: i32,
|
||||
pub body: Vec<u8>,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod imp {
|
||||
@@ -13,6 +20,27 @@ mod imp {
|
||||
fn dc_open_file();
|
||||
fn dc_file_poll() -> i32;
|
||||
fn dc_file_take(dst: *mut u8);
|
||||
fn dc_http(m: *const u8, ml: u32, u: *const u8, ul: u32, b: *const u8, bl: u32) -> u32;
|
||||
fn dc_http_poll(id: u32) -> i32;
|
||||
fn dc_http_len(id: u32) -> u32;
|
||||
fn dc_http_take(id: u32, dst: *mut u8);
|
||||
}
|
||||
|
||||
// starts a request; poll the returned id with http_poll()
|
||||
pub fn http(method: &str, url: &str, body: &[u8]) -> u32 {
|
||||
unsafe { dc_http(method.as_ptr(), method.len() as u32, url.as_ptr(), url.len() as u32, body.as_ptr(), body.len() as u32) }
|
||||
}
|
||||
|
||||
pub fn http_poll(id: u32) -> Option<super::HttpResult> {
|
||||
unsafe {
|
||||
let status = dc_http_poll(id);
|
||||
if status == -2 {
|
||||
return None;
|
||||
}
|
||||
let mut body = vec![0u8; dc_http_len(id) as usize];
|
||||
dc_http_take(id, body.as_mut_ptr());
|
||||
Some(super::HttpResult { status, body })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn storage_get(key: &str) -> Option<String> {
|
||||
@@ -81,6 +109,13 @@ mod imp {
|
||||
pub fn take_file() -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
// no savegame service in native builds: every request fails like an unreachable server
|
||||
pub fn http(_method: &str, _url: &str, _body: &[u8]) -> u32 {
|
||||
0
|
||||
}
|
||||
pub fn http_poll(_id: u32) -> Option<super::HttpResult> {
|
||||
Some(super::HttpResult { status: 0, body: Vec::new() })
|
||||
}
|
||||
}
|
||||
|
||||
pub use imp::*;
|
||||
|
||||
Reference in new issue
Block a user