From 66f641b7ca132cf9ffab8402160d578378a5c217 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 31 Oct 2024 21:46:50 -0400 Subject: [PATCH] Switch around the server/client for Dalamud communication This is to facilitate support for this feature on the Web, where the plugin needs to start a server instead of Auracite itself. Otherwise, the functionality is identical to before. --- Cargo.lock | 329 +++++++++++++++------------- Cargo.toml | 7 +- dalamud/Auracite/AppearanceStep.cs | 4 + dalamud/Auracite/Auracite.csproj | 4 + dalamud/Auracite/CurrencyStep.cs | 4 + dalamud/Auracite/EndStep.cs | 79 +++++++ dalamud/Auracite/IStep.cs | 2 +- dalamud/Auracite/MiscStep.cs | 4 + dalamud/Auracite/PlaytimeStep.cs | 2 +- dalamud/Auracite/Plugin.cs | 17 +- dalamud/Auracite/packages.lock.json | 22 ++ src/bin/auracite/Main.qml | 6 +- src/bin/auracite/bridge.rs | 3 +- src/downloader.rs | 1 + src/lib.rs | 54 ++--- 15 files changed, 331 insertions(+), 207 deletions(-) create mode 100644 dalamud/Auracite/EndStep.cs diff --git a/Cargo.lock b/Cargo.lock index 7f58215..304d907 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,12 +39,18 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "auracite" version = "0.1.0" dependencies = [ "ahash", - "base64 0.22.1", + "base64", "cxx", "cxx-kde-frameworks", "cxx-qt", @@ -59,7 +65,6 @@ dependencies = [ "serde", "serde_json", "tokio", - "touche", "wasm-bindgen", "wasm-bindgen-futures", "zip", @@ -86,12 +91,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -104,15 +103,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -192,15 +182,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - [[package]] name = "crc32fast" version = "1.4.2" @@ -216,16 +197,6 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - [[package]] name = "cssparser" version = "0.34.0" @@ -398,16 +369,6 @@ dependencies = [ "syn", ] -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - [[package]] name = "displaydoc" version = "0.2.5" @@ -446,6 +407,15 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -523,6 +493,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + [[package]] name = "futures-task" version = "0.3.31" @@ -550,16 +526,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -579,36 +545,31 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" -[[package]] -name = "headers" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" -dependencies = [ - "base64 0.21.7", - "bytes", - "headers-core", - "http 0.2.12", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http 0.2.12", -] - [[package]] name = "hermit-abi" version = "0.3.9" @@ -629,17 +590,6 @@ dependencies = [ "syn", ] -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.1.0" @@ -658,7 +608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http", ] [[package]] @@ -669,7 +619,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", + "http", "http-body", "pin-project-lite", ] @@ -680,12 +630,6 @@ version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "hyper" version = "1.5.0" @@ -695,7 +639,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "h2", + "http", "http-body", "httparse", "itoa", @@ -705,6 +650,23 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -730,7 +692,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "http", "http-body", "hyper", "pin-project-lite", @@ -943,16 +905,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" version = "0.36.5" @@ -1243,14 +1195,17 @@ version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ - "base64 0.22.1", + "base64", "bytes", + "encoding_rs", "futures-core", "futures-util", - "http 1.1.0", + "h2", + "http", "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-tls", "hyper-util", "ipnet", @@ -1266,6 +1221,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -1276,6 +1232,21 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1295,6 +1266,19 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.23.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -1310,6 +1294,17 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.18" @@ -1441,17 +1436,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "shlex" version = "1.3.0" @@ -1464,6 +1448,15 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -1480,6 +1473,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1518,6 +1517,12 @@ dependencies = [ "quote", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.85" @@ -1538,6 +1543,27 @@ dependencies = [ "futures-core", ] +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" version = "3.13.0" @@ -1591,15 +1617,6 @@ dependencies = [ "syn", ] -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - [[package]] name = "tinyvec" version = "1.8.0" @@ -1653,15 +1670,27 @@ dependencies = [ ] [[package]] -name = "touche" -version = "0.0.10" -source = "git+https://github.com/redstrate/touche#8979a3367dcf79d605d818157ea187a52608fed9" +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "headers", - "http 0.2.12", - "httparse", - "thiserror", - "threadpool", + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", ] [[package]] @@ -1695,12 +1724,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - [[package]] name = "unicode-bidi" version = "0.3.17" @@ -1734,6 +1757,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.2" @@ -2007,6 +2036,12 @@ dependencies = [ "syn", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zip" version = "2.2.0" diff --git a/Cargo.toml b/Cargo.toml index c09a465..6d491fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,13 +23,8 @@ regex = { version = "1.11", default-features = false, features = ["unicode-perl" # Used to generate the HTML page to easily preview your exported data minijinja = { version = "2.0", default-features = false } -# Used to communicate with the Dalamud plugin -# Needs my fork for allowing server shutdown -# TODO: upstream this or poke upstream to add this -touche = { git = "https://github.com/redstrate/touche", default-features = false, features = ["server"] } - # Download files -reqwest = { version = "0.12", default-features = false, features = ["native-tls"] } +reqwest = { version = "0.12" } # Zip the character archive zip = { version = "2.2", default-features = false } diff --git a/dalamud/Auracite/AppearanceStep.cs b/dalamud/Auracite/AppearanceStep.cs index 5680998..ab11963 100644 --- a/dalamud/Auracite/AppearanceStep.cs +++ b/dalamud/Auracite/AppearanceStep.cs @@ -25,4 +25,8 @@ public class AppearanceStep : IStep { return "No user action required."; } + + public void Dispose() + { + } } \ No newline at end of file diff --git a/dalamud/Auracite/Auracite.csproj b/dalamud/Auracite/Auracite.csproj index 43f8a48..70f809b 100644 --- a/dalamud/Auracite/Auracite.csproj +++ b/dalamud/Auracite/Auracite.csproj @@ -6,4 +6,8 @@ 1.0.0.0 NeoVARC + + + + diff --git a/dalamud/Auracite/CurrencyStep.cs b/dalamud/Auracite/CurrencyStep.cs index 91128da..e09e4df 100644 --- a/dalamud/Auracite/CurrencyStep.cs +++ b/dalamud/Auracite/CurrencyStep.cs @@ -27,4 +27,8 @@ public class CurrencyStep : IStep { return "No user action required."; } + + public void Dispose() + { + } } \ No newline at end of file diff --git a/dalamud/Auracite/EndStep.cs b/dalamud/Auracite/EndStep.cs new file mode 100644 index 0000000..a90675e --- /dev/null +++ b/dalamud/Auracite/EndStep.cs @@ -0,0 +1,79 @@ +using System; +using System.Text; +using System.Threading.Tasks; +using EmbedIO; +using EmbedIO.Routing; +using EmbedIO.WebApi; +using Newtonsoft.Json; + +namespace Auracite; + +public class EndStep : IStep +{ + public event IStep.CompletedDelegate? Completed; + + public void Run() + { + StartWebServer(); + } + + public void End() + { + Completed?.Invoke(); + } + + public string StepName() + { + return "Waiting for Upload"; + } + + public string StepDescription() + { + return "Run Auracite to archive your character."; + } + + private class Controller : WebApiController + { + private EndStep _endStep; + + public Controller(EndStep endStep) + { + _endStep = endStep; + } + + [Route(HttpVerbs.Get, "/package")] + public void GetPackage() + { + Response.ContentType = MimeType.Json; + using var writer = HttpContext.OpenResponseText(Encoding.UTF8, true); + writer.Write(JsonConvert.SerializeObject(Plugin.package)); + + _endStep.End(); + } + } + + private WebServer? _server; + + private void StartWebServer() + { + ShutdownWebServer(); + + _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(); + } + + private void ShutdownWebServer() + { + _server?.Dispose(); + _server = null; + } + + public void Dispose() + { + ShutdownWebServer(); + } +} \ No newline at end of file diff --git a/dalamud/Auracite/IStep.cs b/dalamud/Auracite/IStep.cs index 2516bb1..2e6dc7d 100644 --- a/dalamud/Auracite/IStep.cs +++ b/dalamud/Auracite/IStep.cs @@ -2,7 +2,7 @@ using System; namespace Auracite; -public interface IStep +public interface IStep : IDisposable { public event CompletedDelegate Completed; diff --git a/dalamud/Auracite/MiscStep.cs b/dalamud/Auracite/MiscStep.cs index 070ac49..d66fe12 100644 --- a/dalamud/Auracite/MiscStep.cs +++ b/dalamud/Auracite/MiscStep.cs @@ -30,4 +30,8 @@ public class MiscStep : IStep { return "No user action required."; } + + public void Dispose() + { + } } \ No newline at end of file diff --git a/dalamud/Auracite/PlaytimeStep.cs b/dalamud/Auracite/PlaytimeStep.cs index 539210a..254c88f 100644 --- a/dalamud/Auracite/PlaytimeStep.cs +++ b/dalamud/Auracite/PlaytimeStep.cs @@ -4,7 +4,7 @@ using Dalamud.Game.Text.SeStringHandling; namespace Auracite; -public class PlaytimeStep : IStep, IDisposable +public class PlaytimeStep : IStep { public PlaytimeStep() { diff --git a/dalamud/Auracite/Plugin.cs b/dalamud/Auracite/Plugin.cs index 095c5f2..b0318dc 100644 --- a/dalamud/Auracite/Plugin.cs +++ b/dalamud/Auracite/Plugin.cs @@ -1,11 +1,16 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net.Http; +using System.Threading.Tasks; using Dalamud.Game.Command; using Dalamud.Interface.Windowing; using Dalamud.IoC; using Dalamud.Plugin; using Dalamud.Plugin.Services; +using EmbedIO; +using EmbedIO.Routing; +using EmbedIO.WebApi; using Newtonsoft.Json; namespace Auracite; @@ -16,7 +21,7 @@ public sealed class Plugin : IDalamudPlugin private readonly WindowSystem WindowSystem = new("Auracite"); private readonly List _steps = - [typeof(AppearanceStep), typeof(CurrencyStep), typeof(MiscStep), typeof(PlaytimeStep)]; + [typeof(AppearanceStep), typeof(CurrencyStep), typeof(MiscStep), typeof(PlaytimeStep), typeof(EndStep)]; private int _stepIndex; @@ -60,6 +65,7 @@ public sealed class Plugin : IDalamudPlugin public void Dispose() { + CurrentStep?.Dispose(); WindowSystem.RemoveAllWindows(); } @@ -79,20 +85,13 @@ public sealed class Plugin : IDalamudPlugin _stepIndex++; if (_stepIndex >= _steps.Count) { + CurrentStep?.Dispose(); CurrentStep = null; StepWindow.IsOpen = false; - SendPackage(); return; } CurrentStep = (IStep)Activator.CreateInstance(_steps[_stepIndex])!; CurrentStep.Completed += NextStep; CurrentStep.Run(); } - - private void SendPackage() - { - var client = new HttpClient(); - client.PostAsync("http://127.0.0.1:8000/package", new StringContent(JsonConvert.SerializeObject(package))); - package = null; - } } \ No newline at end of file diff --git a/dalamud/Auracite/packages.lock.json b/dalamud/Auracite/packages.lock.json index 19fcea9..e4d9972 100644 --- a/dalamud/Auracite/packages.lock.json +++ b/dalamud/Auracite/packages.lock.json @@ -7,6 +7,28 @@ "requested": "[2.1.13, )", "resolved": "2.1.13", "contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ==" + }, + "EmbedIO": { + "type": "Direct", + "requested": "[3.5.2, )", + "resolved": "3.5.2", + "contentHash": "YU4j+3XvuO8/VPkNf7KWOF1TpMhnyVhXnPsG1mvnDhTJ9D5BZOFXVDvCpE/SkQ1AJ0Aa+dXOVSW3ntgmLL7aJg==", + "dependencies": { + "Unosquare.Swan.Lite": "3.1.0" + } + }, + "System.ValueTuple": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "Unosquare.Swan.Lite": { + "type": "Transitive", + "resolved": "3.1.0", + "contentHash": "X3s5QE/KMj3WAPFqFve7St+Ds10BB50u8kW8PmKIn7FVkn7yEXe9Yxr2htt1WV85DRqfFR0MN/BUNHkGHtL4OQ==", + "dependencies": { + "System.ValueTuple": "4.5.0" + } } } } diff --git a/src/bin/auracite/Main.qml b/src/bin/auracite/Main.qml index 8679852..85d4994 100644 --- a/src/bin/auracite/Main.qml +++ b/src/bin/auracite/Main.qml @@ -18,9 +18,13 @@ Kirigami.ApplicationWindow { placeholderText: "Full name of the character" } + QQC2.CheckBox { + id: dalamudCheckbox + } + QQC2.Button { text: "Archive" - onClicked: root.backend.archiveCharacter(characterNameField.text, false) + onClicked: root.backend.archiveCharacter(characterNameField.text, dalamudCheckbox.checked) } } diff --git a/src/bin/auracite/bridge.rs b/src/bin/auracite/bridge.rs index 981a26a..0969870 100644 --- a/src/bin/auracite/bridge.rs +++ b/src/bin/auracite/bridge.rs @@ -40,13 +40,14 @@ impl bridge::Backend { pub fn archive_character(mut self: Pin<&mut Self>, character_name: &QString, use_dalamud: bool) { match archive_character_blocking(&character_name.to_string(), use_dalamud) { Ok(_) => { self.archive_successful() } - Err(err) => { + Err(err) => { match err { // TODO: Pass the URL up ArchiveError::DownloadFailed(_) => { self.archive_failed(&i18n("Download failed")) } ArchiveError::CharacterNotFound => { self.archive_failed(&i18n("Character not found")) } ArchiveError::ParsingError => { self.archive_failed(&i18n("Parsing error")) } ArchiveError::UnknownError => { self.archive_failed(&i18n("Unknown error")) } + ArchiveError::CouldNotConnectToDalamud => { self.archive_failed(&i18n("Could not connect to Dalamud plugin")) } } } } diff --git a/src/downloader.rs b/src/downloader.rs index ee499d0..7b71ddb 100644 --- a/src/downloader.rs +++ b/src/downloader.rs @@ -2,6 +2,7 @@ use reqwest::Url; pub async fn download(url: &Url) -> Result, 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 body = client.get(url.to_string()) diff --git a/src/lib.rs b/src/lib.rs index 182e022..11c6f1b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,6 @@ use std::convert::Infallible; use std::io::Write; use std::sync::{Arc, Mutex}; use reqwest::Url; -use touche::server::Service; -use touche::{Body, HttpBody, Request, Response, Server, StatusCode}; use zip::result::ZipError; use zip::write::SimpleFileOptions; use zip::ZipWriter; @@ -38,38 +36,12 @@ struct Package { player_commendations: i32, } -#[derive(Clone)] -struct PackageService<'a> { - wants_stop: Arc>, // TODO: THIS IS TERRIBLE STOP STOP STOP - package: &'a Arc>, -} - -impl Service for PackageService<'_> { - type Body = &'static str; - type Error = Infallible; - - fn call(&self, req: Request) -> Result, Self::Error> { - *self.package.lock().unwrap() = serde_json::from_str(&String::from_utf8(req.into_body().into_bytes().unwrap()).unwrap()).unwrap(); - - *self.wants_stop.lock().unwrap() = true; - - Ok(Response::builder() - .status(StatusCode::OK) - .body("") - .unwrap()) - } - - // TODO: NO NO NO NO - fn wants_stop(&self) -> bool { - *self.wants_stop.lock().unwrap() - } -} - #[derive(Debug)] pub enum ArchiveError { DownloadFailed(String), CharacterNotFound, ParsingError, + CouldNotConnectToDalamud, UnknownError } @@ -124,8 +96,6 @@ pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Resul let mut zip = ZipWriter::new(std::io::Cursor::new(&mut buf[..])); let options = SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored); - zip.start_file("character.json", options)?; - zip.write_all(serde_json::to_string(&char_data).unwrap().as_ref())?; if !char_data.portrait_url.is_empty() { let portrait_url = char_data.portrait_url.replace("img2.finalfantasyxiv.com", "img-tunnel.ryne.moe"); @@ -151,13 +121,12 @@ pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Resul } if use_dalamud { - println!("Now waiting for the Dalamud plugin. Type /auracite begin in chat."); - - let package = Arc::new(Mutex::new(Package::default())); - - Server::bind("0.0.0.0:8000").serve_single_thread(PackageService { wants_stop: Arc::new(Mutex::new(false)), package: &package }).unwrap(); - - let package = &*package.lock().unwrap(); + let dalamud_url = Url::parse(&"http://localhost:42072/package").map_err(|_| ArchiveError::UnknownError)?; + let package = download(&dalamud_url).await.map_err(|_| ArchiveError::CouldNotConnectToDalamud)?; + let package = String::from_utf8(package).map_err(|_| ArchiveError::ParsingError)?; + // Remove BOM at the start + let package = package.trim_start_matches("\u{feff}"); + let package: Package = serde_json::from_str(&package.trim_start()).unwrap(); char_data.playtime = package.playtime.parse().unwrap(); char_data.appearance.height = package.height; @@ -170,14 +139,17 @@ pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Resul char_data.player_commendations = package.player_commendations; // TODO: fetch from the lodestone? } + zip.start_file("character.json", options)?; + zip.write_all(serde_json::to_string(&char_data).unwrap().as_ref())?; + let html = create_html( &char_data ); - zip.start_file("character.html", options); - zip.write_all(html.as_ref()); + zip.start_file("character.html", options)?; + zip.write_all(html.as_ref())?; - zip.finish(); + zip.finish()?; Ok(buf) }