Skip to content

Commit

Permalink
Add functionality to sync mods from savefile
Browse files Browse the repository at this point in the history
  • Loading branch information
circlesabound committed Apr 23, 2024
1 parent 081c991 commit cd82a0d
Show file tree
Hide file tree
Showing 14 changed files with 378 additions and 59 deletions.
134 changes: 124 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ publish = false

[dependencies]
async-stream = "0.3"
async_zip = { version = "0.0.17", features = [ "full" ] }
base64 = "0.22"
bincode = "1.3"
bytes = "1.0"
Expand All @@ -27,6 +28,7 @@ regex = "1.4"
reqwest = { version = "0.12.1", features = [ "json" ] }
rocksdb = "0.22"
rocket = { version = "0.5", features = [ "json" ] }
sanitize-filename = "0.5"
serde = { version = "1.0", features = [ "derive" ] }
serde_json = "1.0"
serenity = { version = "0.12", default-features = false, features = [ "client", "gateway", "rustls_backend", "model", "cache" ] }
Expand Down
21 changes: 19 additions & 2 deletions openapi/mgmt-server-rest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ openapi: 3.0.0
info:
title: fctrl mgmt-server REST API
description: REST API exposed by fctrl mgmt-server
version: 0.1.1
version: 0.1.2

servers:
- url: /api/v1
Expand Down Expand Up @@ -147,7 +147,7 @@ paths:
parameters:
- name: savefile_id
in: path
description: Name of the savefile to be delete
description: Name of the savefile to delete
required: true
schema:
type: string
Expand Down Expand Up @@ -178,6 +178,23 @@ paths:
responses:
'200':
description: Ok
/server/savefiles/{savefile_id}/mods:
get:
summary: Extract the list of mods from the savefile
parameters:
- name: savefile_id
in: path
description: Name of the savefile to extract mod list from
required: true
schema:
type: string
responses:
'200':
description: A JSON array of objects representing mods from the savefile
content:
application/json:
schema:
$ref: '#/components/schemas/ServerModList'
/server/config/adminlist:
get:
summary: Gets the adminlist the Factorio server is configured to use.
Expand Down
10 changes: 10 additions & 0 deletions src/agent/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pub enum Error {
RconEmptyCommand,
RconNotConnected,

// SaveHeader
HeaderNotFound,

// Generic
Aggregate(Vec<Error>),

Expand All @@ -30,6 +33,7 @@ pub enum Error {
Reqwest(reqwest::Error),
TomlDe(toml::de::Error),
TomlSer(toml::ser::Error),
Zip(async_zip::error::ZipError),
}

impl std::error::Error for Error {}
Expand Down Expand Up @@ -81,3 +85,9 @@ impl From<toml::ser::Error> for Error {
Error::TomlSer(e)
}
}

impl From<async_zip::error::ZipError> for Error {
fn from(e: async_zip::error::ZipError) -> Self {
Error::Zip(e)
}
}
34 changes: 34 additions & 0 deletions src/agent/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ impl AgentController {
self.mod_list_get(operation_id).await;
}

AgentRequest::ModListExtractFromSave(save_name) => {
self.mod_list_extract_from_save(save_name, operation_id).await;
}

AgentRequest::ModListSet(mod_list) => {
self.mod_list_set(mod_list, operation_id).await;
}
Expand Down Expand Up @@ -1102,6 +1106,36 @@ impl AgentController {
}
}

async fn mod_list_extract_from_save(&self, save_name: String, operation_id: OperationId) {
match util::saves::exists_savefile(&save_name).await {
Ok(true) => {
match util::saves::read_header(&save_name).await {
Ok(header) => {
let base_mod_name = header.base_mod;
let ret = header.mods.into_iter().filter(|shm| {
shm.name == base_mod_name
}).map(|shm| {
ModObject {
name: shm.name,
version: shm.version.to_string(),
}
}).collect();
self.reply_success(AgentOutMessage::ModsList(ret), operation_id).await;
},
Err(e) => self.reply_failed(
AgentOutMessage::Error(format!("Failed to read savefile header: {:?}", e)),
operation_id
).await,
}
},
Ok(false) => self.reply_failed(AgentOutMessage::SaveNotFound, operation_id).await,
Err(e) => self.reply_failed(
AgentOutMessage::Error(format!("Failed to read savefile: {:?}", e)),
operation_id
).await,
}
}

async fn mod_list_set(&self, mod_list: Vec<ModObject>, operation_id: OperationId) {
match ModManager::read_or_apply_default().await {
Ok(mut m) => match Secrets::read().await {
Expand Down
Loading

0 comments on commit cd82a0d

Please sign in to comment.