mirror of
https://github.com/redstrate/Auracite.git
synced 2025-04-22 20:57:46 +00:00
Make the Dalamud plugin work with the WebAssembly version
This commit is contained in:
parent
66f641b7ca
commit
acb42a7cb6
6 changed files with 109 additions and 39 deletions
81
Cargo.lock
generated
81
Cargo.lock
generated
|
@ -199,14 +199,14 @@ checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
|||
|
||||
[[package]]
|
||||
name = "cssparser"
|
||||
version = "0.34.0"
|
||||
version = "0.31.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7c66d1cd8ed61bf80b38432613a7a2f09401ab8d0501110655f8b341484a3e3"
|
||||
checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be"
|
||||
dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa",
|
||||
"phf",
|
||||
"phf 0.11.2",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
|
@ -397,9 +397,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ego-tree"
|
||||
version = "0.9.0"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c6ba7d4eec39eaa9ab24d44a0e73a7949a1095a8b3f3abb11eddf27dbb56a53"
|
||||
checksum = "12a0bb14ac04a9fcf170d0bbbef949b44cc492f4452bd20c095636956f653642"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
|
@ -526,6 +526,15 @@ dependencies = [
|
|||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
|
@ -578,9 +587,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
|||
|
||||
[[package]]
|
||||
name = "html5ever"
|
||||
version = "0.29.0"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e15626aaf9c351bc696217cbe29cb9b5e86c43f8a46b5e2f5c6c5cf7cb904ce"
|
||||
checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mac",
|
||||
|
@ -812,13 +821,13 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
|||
|
||||
[[package]]
|
||||
name = "markup5ever"
|
||||
version = "0.14.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82c88c6129bd24319e62a0359cb6b958fa7e8be6e19bb1663bc396b90883aca5"
|
||||
checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45"
|
||||
dependencies = [
|
||||
"log",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
"phf 0.11.2",
|
||||
"phf_codegen 0.11.2",
|
||||
"string_cache",
|
||||
"string_cache_codegen",
|
||||
"tendril",
|
||||
|
@ -993,6 +1002,15 @@ version = "2.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
|
||||
dependencies = [
|
||||
"phf_shared 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
|
@ -1003,6 +1021,16 @@ dependencies = [
|
|||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
|
||||
dependencies = [
|
||||
"phf_generator 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.11.2"
|
||||
|
@ -1328,15 +1356,16 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||
|
||||
[[package]]
|
||||
name = "scraper"
|
||||
version = "0.21.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0e749d29b2064585327af5038a5a8eb73aeebad4a3472e83531a436563f7208"
|
||||
checksum = "b90460b31bfe1fc07be8262e42c665ad97118d4585869de9345a84d501a9eaf0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"cssparser",
|
||||
"ego-tree",
|
||||
"getopts",
|
||||
"html5ever",
|
||||
"precomputed-hash",
|
||||
"once_cell",
|
||||
"selectors",
|
||||
"tendril",
|
||||
]
|
||||
|
@ -1366,9 +1395,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "selectors"
|
||||
version = "0.26.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8"
|
||||
checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cssparser",
|
||||
|
@ -1376,8 +1405,8 @@ dependencies = [
|
|||
"fxhash",
|
||||
"log",
|
||||
"new_debug_unreachable",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
"phf 0.10.1",
|
||||
"phf_codegen 0.10.0",
|
||||
"precomputed-hash",
|
||||
"servo_arc",
|
||||
"smallvec",
|
||||
|
@ -1429,9 +1458,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "servo_arc"
|
||||
version = "0.4.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae65c4249478a2647db249fb43e23cec56a2c8974a427e7bd8cb5a1d0964921a"
|
||||
checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44"
|
||||
dependencies = [
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
@ -1525,9 +1554,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.85"
|
||||
version = "2.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||
checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1599,18 +1628,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.65"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
|
||||
checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.65"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
|
||||
checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -12,7 +12,8 @@ cxx-qt-build = { git = "https://github.com/KDAB/cxx-qt", branch = "main", featur
|
|||
|
||||
[dependencies]
|
||||
# Used to scrape the Lodestone HTML pages
|
||||
scraper = { version ="0.21", default-features = false }
|
||||
# NOTE: Do not upgrade to 0.21, as it crashes in WebAssembly for some reason. Report this upstream.
|
||||
scraper = { version ="0.20" }
|
||||
|
||||
# Used to serialize the JSON data we export
|
||||
serde = { version = "1.0", features = ["derive"], default-features = false }
|
||||
|
|
|
@ -44,10 +44,17 @@ public class EndStep : IStep
|
|||
[Route(HttpVerbs.Get, "/package")]
|
||||
public void GetPackage()
|
||||
{
|
||||
Response.Headers.Set(HttpHeaderNames.AccessControlAllowOrigin, "*");
|
||||
Response.ContentType = MimeType.Json;
|
||||
using var writer = HttpContext.OpenResponseText(Encoding.UTF8, true);
|
||||
writer.Write(JsonConvert.SerializeObject(Plugin.package));
|
||||
|
||||
}
|
||||
|
||||
// TODO: Make this a POST request?
|
||||
// This is needed since we don't know when the CORS handshake really stops. This really shouldn't be needed though.
|
||||
[Route(HttpVerbs.Get, "/stop")]
|
||||
public void Stop()
|
||||
{
|
||||
_endStep.End();
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +68,6 @@ public class EndStep : IStep
|
|||
_server = new WebServer(o => o
|
||||
.WithUrlPrefix("http://localhost:42072/")
|
||||
.WithMode(HttpListenerMode.EmbedIO))
|
||||
.WithCors("http://localhost:42072/")
|
||||
.WithWebApi("/", m => m.WithController(() => new Controller(this)));
|
||||
_server.RunAsync();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
function archive() {
|
||||
init().then(() => {
|
||||
archive_character_base64(document.getElementById("name").value, false).then((uri) => {
|
||||
archive_character_base64(document.getElementById("name").value, document.getElementById("scales").checked).then((uri) => {
|
||||
// Download character archive
|
||||
window.location.replace(uri);
|
||||
document.getElementById("statusMessage").innerText = "Archive complete!";
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
use reqwest::Url;
|
||||
|
||||
pub async fn download(url: &Url) -> Result<Vec<u8>, reqwest::Error> {
|
||||
let client = reqwest::Client::builder()
|
||||
.no_proxy() // This fixes localhost connections... for some reason (https://github.com/seanmonstar/reqwest/issues/913)
|
||||
.build()?;
|
||||
let mut client = reqwest::Client::builder();
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
{
|
||||
client = client.no_proxy(); // This fixes localhost connections... for some reason (https://github.com/seanmonstar/reqwest/issues/913)
|
||||
}
|
||||
|
||||
let client = client.build()?;
|
||||
|
||||
let body = client.get(url.to_string())
|
||||
.send()
|
||||
|
|
41
src/lib.rs
41
src/lib.rs
|
@ -21,8 +21,18 @@ use wasm_bindgen::prelude::wasm_bindgen;
|
|||
#[cfg(target_family = "wasm")]
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
/// The main Lodestone domain
|
||||
const LODESTONE_HOST: &str = "https://na.finalfantasyxiv.com";
|
||||
|
||||
/// The Lodestone proxy used in WebAssembly builds. Needed for CORS and cookie injection.
|
||||
const LODESTONE_TUNNEL_HOST: &str = "https://lodestone-tunnel.ryne.moe";
|
||||
|
||||
/// The image domain.
|
||||
const IMAGE_HOST: &str = "img2.finalfantasyxiv.com";
|
||||
|
||||
/// The image proxy used in WebAssembly builds. Needed for CORS.
|
||||
const IMAGE_TUNNEL_HOST: &str = "img-tunnel.ryne.moe";
|
||||
|
||||
#[derive(Default, Deserialize, Clone)]
|
||||
struct Package {
|
||||
playtime: String,
|
||||
|
@ -66,13 +76,20 @@ impl From<ArchiveError> for JsValue {
|
|||
ArchiveError::CharacterNotFound => { JsValue::from_str(&"character_not_found".to_string()) }
|
||||
ArchiveError::ParsingError => { JsValue::from_str(&"parsing_error".to_string())}
|
||||
ArchiveError::UnknownError => { JsValue::from_str(&"unknown_error".to_string()) }
|
||||
ArchiveError::CouldNotConnectToDalamud => { JsValue::from_str(&"could_not_connect_to_dalamud".to_string()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Archives the character named `character_name` and gives a ZIP file as bytes that can be written to disk.
|
||||
pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Result<Vec<u8>, ArchiveError> {
|
||||
let search_url = Url::parse_with_params(&format!("{LODESTONE_HOST}/lodestone/character?"), &[("q", character_name)]).map_err(|_| ArchiveError::UnknownError)?;
|
||||
let lodestone_host = if cfg!(target_family = "wasm") {
|
||||
LODESTONE_TUNNEL_HOST
|
||||
} else {
|
||||
LODESTONE_HOST
|
||||
};
|
||||
|
||||
let search_url = Url::parse_with_params(&format!("{lodestone_host}/lodestone/character?"), &[("q", character_name)]).map_err(|_| ArchiveError::UnknownError)?;
|
||||
let search_page = download(&search_url)
|
||||
.await
|
||||
.map_err(|_| ArchiveError::DownloadFailed(search_url.to_string()))?;
|
||||
|
@ -83,7 +100,7 @@ pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Resul
|
|||
return Err(ArchiveError::CharacterNotFound);
|
||||
}
|
||||
|
||||
let char_page_url = Url::parse(&format!("{LODESTONE_HOST}{}", href)).map_err(|_| ArchiveError::UnknownError)?;
|
||||
let char_page_url = Url::parse(&format!("{lodestone_host}{}", href)).map_err(|_| ArchiveError::UnknownError)?;
|
||||
let char_page = download(&char_page_url)
|
||||
.await
|
||||
.map_err(|_| ArchiveError::DownloadFailed(char_page_url.to_string()))?;
|
||||
|
@ -92,13 +109,17 @@ pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Resul
|
|||
let mut char_data = parser::parse_lodestone(&char_page);
|
||||
|
||||
// 2 MiB, for one JSON and two images
|
||||
let mut buf = vec![0; 2097152];
|
||||
let mut zip = ZipWriter::new(std::io::Cursor::new(&mut buf[..]));
|
||||
let mut buf = Vec::new();
|
||||
let mut zip = ZipWriter::new(std::io::Cursor::new(&mut buf));
|
||||
|
||||
let options = SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored);
|
||||
|
||||
if !char_data.portrait_url.is_empty() {
|
||||
let portrait_url = char_data.portrait_url.replace("img2.finalfantasyxiv.com", "img-tunnel.ryne.moe");
|
||||
let portrait_url = if cfg!(target_family = "wasm") {
|
||||
&char_data.portrait_url.replace(IMAGE_HOST, IMAGE_TUNNEL_HOST)
|
||||
} else {
|
||||
&char_data.portrait_url
|
||||
};
|
||||
let portrait_url = Url::parse(&portrait_url).map_err(|_| ArchiveError::UnknownError)?;
|
||||
|
||||
let portrait = download(&portrait_url)
|
||||
|
@ -109,7 +130,11 @@ pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Resul
|
|||
zip.write_all(&*portrait)?;
|
||||
}
|
||||
if !char_data.face_url.is_empty() {
|
||||
let face_url = char_data.face_url.replace("img2.finalfantasyxiv.com", "img-tunnel.ryne.moe");
|
||||
let face_url = if cfg!(target_family = "wasm") {
|
||||
&char_data.face_url.replace(IMAGE_HOST, IMAGE_TUNNEL_HOST)
|
||||
} else {
|
||||
&char_data.face_url
|
||||
};
|
||||
let face_url = Url::parse(&face_url).map_err(|_| ArchiveError::UnknownError)?;
|
||||
|
||||
let face = download(&face_url)
|
||||
|
@ -137,6 +162,10 @@ pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Resul
|
|||
char_data.is_novice = package.is_novice;
|
||||
char_data.is_returner = package.is_returner;
|
||||
char_data.player_commendations = package.player_commendations; // TODO: fetch from the lodestone?
|
||||
|
||||
// Stop the HTTP server
|
||||
let stop_url = Url::parse(&"http://localhost:42072/stop").map_err(|_| ArchiveError::UnknownError)?;
|
||||
download(&stop_url).await;
|
||||
}
|
||||
|
||||
zip.start_file("character.json", options)?;
|
||||
|
|
Loading…
Add table
Reference in a new issue