diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index dfff310..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,2388 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ages-prs" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "089e6d1d25d8975ac1bf2da0d1556ebdb99fee1a9aec6467d138a6e090b92ff4" -dependencies = [ - "libflate_lz77", -] - -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom 0.2.6", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" -dependencies = [ - "backtrace", -] - -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "async-channel" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "once_cell", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c290043c9a95b05d45e952fb6383c67bcb61471f60cfa21e890dba6654234f43" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-mutex", - "blocking", - "futures-lite", - "num_cpus", - "once_cell", -] - -[[package]] -name = "async-io" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" -dependencies = [ - "concurrent-queue", - "futures-lite", - "libc", - "log", - "once_cell", - "parking", - "polling", - "slab", - "socket2", - "waker-fn", - "winapi", -] - -[[package]] -name = "async-lock" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-mutex" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-native-tls" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33" -dependencies = [ - "async-std", - "native-tls", - "thiserror", - "url", -] - -[[package]] -name = "async-process" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6" -dependencies = [ - "async-io", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "libc", - "once_cell", - "signal-hook", - "winapi", -] - -[[package]] -name = "async-recursion" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-std" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52580991739c5cdb36cde8b2a516371c0a3b70dda36d916cc08b82372916808c" -dependencies = [ - "async-attributes", - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "num_cpus", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" - -[[package]] -name = "async-trait" -version = "0.1.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atoi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" -dependencies = [ - "num-traits", -] - -[[package]] -name = "atomic-waker" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "barrel" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d67c978b1322c8031145b1f6c236fc371292f52c565bc96018b2971afcbffe1" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bcrypt" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f691e63585950d8c1c43644d11bab9073e40f5060dd2822734ae7c3dc69a3a80" -dependencies = [ - "base64", - "blowfish", - "getrandom 0.2.6", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "block-buffer" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" -dependencies = [ - "async-channel", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "once_cell", -] - -[[package]] -name = "blowfish" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3ff3fc1de48c1ac2e3341c4df38b0d1bfb8fdf04632a187c8b75aaa319a7ab" -dependencies = [ - "byteorder", - "cipher", - "opaque-debug", -] - -[[package]] -name = "build_const" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7" - -[[package]] -name = "bumpalo" -version = "3.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "colored" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" -dependencies = [ - "atty", - "lazy_static", - "winapi", -] - -[[package]] -name = "concurrent-queue" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" -dependencies = [ - "cache-padded", -] - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" -dependencies = [ - "build_const", -] - -[[package]] -name = "crc" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" - -[[package]] -name = "crossbeam-queue" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" -dependencies = [ - "cfg-if", - "lazy_static", -] - -[[package]] -name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ctor" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn", -] - -[[package]] -name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elseware" -version = "0.1.0" -dependencies = [ - "ages-prs", - "anyhow", - "async-recursion", - "async-std", - "async-trait", - "barrel", - "bcrypt", - "byteorder", - "chrono", - "crc 1.8.1", - "derive_more", - "enum-utils", - "fern", - "futures", - "lazy_static", - "libpso", - "log", - "rand 0.7.3", - "rand_chacha 0.2.2", - "refinery", - "ron", - "serde", - "serde_json", - "sqlx", - "strum", - "strum_macros", - "thiserror", - "toml", -] - -[[package]] -name = "enum-utils" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed327f716d0d351d86c9fd3398d20ee39ad8f681873cc081da2ca1c10fed398a" -dependencies = [ - "enum-utils-from-str", - "failure", - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "enum-utils-from-str" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d49be08bad6e4ca87b2b8e74146987d4e5cb3b7512efa50ef505b51a22227ee1" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "event-listener" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" - -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", -] - -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - -[[package]] -name = "fern" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e69ab0d5aca163e388c3a49d284fed6c3d0810700e77c5ae2756a50ec1a4daaa" -dependencies = [ - "chrono", - "colored", - "log", -] - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "futures" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-executor" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-intrusive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot", -] - -[[package]] -name = "futures-io" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" - -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-macro" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "futures-task" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" - -[[package]] -name = "futures-util" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" - -[[package]] -name = "gloo-timers" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashlink" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" -dependencies = [ - "hashbrown", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" -dependencies = [ - "autocfg 1.1.0", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "js-sys" -version = "0.3.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" - -[[package]] -name = "libflate_lz77" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739e9d7726dc32173fed2d69d17eef3c54682169e4e20ff1d0a45dcd37063cef" - -[[package]] -name = "libpso" -version = "0.1.0" -dependencies = [ - "chrono", - "psopacket", - "rand 0.6.5", -] - -[[package]] -name = "lock_api" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" -dependencies = [ - "autocfg 1.1.0", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" -dependencies = [ - "cfg-if", - "value-bag", -] - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "md-5" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582" -dependencies = [ - "digest", -] - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "native-tls" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nom" -version = "7.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg 1.1.0", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg 1.1.0", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40bec70ba014595f99f7aa110b84331ffe1ee9aece7fe6f387cc7e3ecda4d456" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" -dependencies = [ - "autocfg 1.1.0", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "paste" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "phf" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_shared", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" - -[[package]] -name = "polling" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" -dependencies = [ - "cfg-if", - "libc", - "log", - "wepoll-ffi", - "winapi", -] - -[[package]] -name = "postgres" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb76d6535496f633fa799bb872ffb4790e9cbdedda9d35564ca0252f930c0dd5" -dependencies = [ - "bytes", - "fallible-iterator", - "futures", - "log", - "tokio", - "tokio-postgres", -] - -[[package]] -name = "postgres-protocol" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ec03bce71f18b4a27c4c64c6ba2ddf74686d69b91d8714fb32ead3adaed713" -dependencies = [ - "base64", - "byteorder", - "bytes", - "fallible-iterator", - "hmac", - "md-5", - "memchr", - "rand 0.8.5", - "sha2", - "stringprep", -] - -[[package]] -name = "postgres-types" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04619f94ba0cc80999f4fc7073607cb825bc739a883cb6d20900fc5e009d6b0d" -dependencies = [ - "bytes", - "fallible-iterator", - "postgres-protocol", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "proc-macro2" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "psopacket" -version = "1.0.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom 0.2.6", - "redox_syscall", - "thiserror", -] - -[[package]] -name = "refinery" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e29bd9c881127d714f4b5b9fdd9ea7651f3dd254922e959a10f6ada620e841da" -dependencies = [ - "refinery-core", - "refinery-macros", -] - -[[package]] -name = "refinery-core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53260bc01535ea10c553ce0fc410609ba2dc0a9f4c9b4503e0af842dd4a6f89d" -dependencies = [ - "async-trait", - "cfg-if", - "chrono", - "lazy_static", - "log", - "postgres", - "regex", - "serde", - "siphasher", - "thiserror", - "toml", - "url", - "walkdir", -] - -[[package]] -name = "refinery-macros" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a79ff62c9b674b62c06a09cc8becf06cbafba9952afa1d8174e7e15f2c4ed43" -dependencies = [ - "proc-macro2", - "quote", - "refinery-core", - "regex", - "syn", -] - -[[package]] -name = "regex" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "ron" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b861ecaade43ac97886a512b360d01d66be9f41f3c61088b42cedf92e03d678" -dependencies = [ - "base64", - "bitflags", - "serde", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "ryu" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "security-framework" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" - -[[package]] -name = "serde" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_derive_internals" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha-1" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "signal-hook" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "siphasher" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" - -[[package]] -name = "slab" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" - -[[package]] -name = "smallvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "sqlformat" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" -dependencies = [ - "itertools", - "nom", - "unicode_categories", -] - -[[package]] -name = "sqlx" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" -dependencies = [ - "sqlx-core", - "sqlx-macros", -] - -[[package]] -name = "sqlx-core" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" -dependencies = [ - "ahash", - "atoi", - "base64", - "bitflags", - "byteorder", - "bytes", - "chrono", - "crc 2.1.0", - "crossbeam-queue", - "dirs", - "either", - "event-listener", - "futures-channel", - "futures-core", - "futures-intrusive", - "futures-util", - "hashlink", - "hex", - "hkdf", - "hmac", - "indexmap", - "itoa", - "libc", - "log", - "md-5", - "memchr", - "once_cell", - "paste", - "percent-encoding", - "rand 0.8.5", - "serde", - "serde_json", - "sha-1", - "sha2", - "smallvec", - "sqlformat", - "sqlx-rt", - "stringprep", - "thiserror", - "url", - "whoami", -] - -[[package]] -name = "sqlx-macros" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" -dependencies = [ - "dotenv", - "either", - "heck 0.4.0", - "once_cell", - "proc-macro2", - "quote", - "serde_json", - "sha2", - "sqlx-core", - "sqlx-rt", - "syn", - "url", -] - -[[package]] -name = "sqlx-rt" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" -dependencies = [ - "async-native-tls", - "async-std", - "native-tls", -] - -[[package]] -name = "stringprep" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "strum" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89a286a7e3b5720b9a477b23253bc50debac207c8d21505f8e70b36792f11b5" - -[[package]] -name = "strum_macros" -version = "0.19.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e61bb0be289045cb80bfce000512e32d09f8337e54c186725da381377ad1f8d5" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "thiserror" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f48b6d60512a392e34dbf7fd456249fd2de3c83669ab642e021903f4015185b" -dependencies = [ - "bytes", - "libc", - "memchr", - "mio", - "once_cell", - "pin-project-lite", - "socket2", - "winapi", -] - -[[package]] -name = "tokio-postgres" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6c8b33df661b548dcd8f9bf87debb8c56c05657ed291122e1188698c2ece95" -dependencies = [ - "async-trait", - "byteorder", - "bytes", - "fallible-iterator", - "futures", - "log", - "parking_lot", - "percent-encoding", - "phf", - "pin-project-lite", - "postgres-protocol", - "postgres-types", - "socket2", - "tokio", - "tokio-util", -] - -[[package]] -name = "tokio-util" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" -dependencies = [ - "serde", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "unicode-bidi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "value-bag" -version = "1.0.0-alpha.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" -dependencies = [ - "ctor", - "version_check", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" - -[[package]] -name = "web-sys" -version = "0.3.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wepoll-ffi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] - -[[package]] -name = "whoami" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524b58fa5a20a2fb3014dd6358b70e6579692a56ef6fce928834e488f42f65e8" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index d62e110..c2e511d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ async-recursion= "1.0.0" lazy_static = "1.4.0" barrel = { version = "0.6.5", features = ["pg"] } refinery = { version = "0.5.0", features = ["postgres"] } -sqlx = { version = "0.5.10", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } +sqlx = { version = "0.6.2", features = ["runtime-async-std-native-tls", "postgres", "json", "chrono"] } strum = "0.19.5" strum_macros = "0.19" anyhow = { version = "1.0.68", features = ["backtrace"] } diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index 99c65bb..df922ac 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -4,10 +4,10 @@ use futures::future::{Future, BoxFuture}; use crate::entity::account::*; use crate::entity::character::*; use crate::entity::item::*; +use crate::entity::room::*; // TODO: better granularity? -//#[derive(Error, Debug)] #[derive(Error, Debug)] pub enum GatewayError { #[error("unknown error")] @@ -147,6 +147,14 @@ pub trait EntityGateway: Send + Sync { async fn set_character_playtime(&mut self, _char_id: &CharacterEntityId, _playtime: u32) -> Result<(), GatewayError> { unimplemented!(); } + + async fn create_room(&mut self, _room: NewRoomEntity) -> Result { + unimplemented!(); + } + + async fn add_room_note(&mut self, _room_id: RoomEntityId, _note: RoomNote) -> Result<(), GatewayError> { + unimplemented!(); + } } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index 75df8a1..50a650e 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -6,6 +6,7 @@ use crate::entity::account::*; use crate::entity::character::*; use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError}; use crate::entity::item::*; +use crate::entity::room::*; use async_std::sync::{Arc, Mutex}; @@ -766,4 +767,21 @@ impl EntityGateway for InMemoryGateway { Err(GatewayError::Error) } } + + // I do not care to replicate this in testing + async fn create_room(&mut self, room: NewRoomEntity) -> Result { + Ok(RoomEntity { + id: RoomEntityId(0), + name: room.name, + section_id: room.section_id, + episode: room.episode, + difficulty: room.difficulty, + mode: room.mode, + }) + } + + // I do not care to replicate this in testing + async fn add_room_note(&mut self, _room_id: RoomEntityId, _note: RoomNote) -> Result<(), GatewayError> { + Ok(()) + } } diff --git a/src/entity/gateway/postgres/migrations/V0012__room.sql b/src/entity/gateway/postgres/migrations/V0012__room.sql new file mode 100644 index 0000000..1064ea1 --- /dev/null +++ b/src/entity/gateway/postgres/migrations/V0012__room.sql @@ -0,0 +1,14 @@ +create table room ( + id serial primary key not null, + name varchar(32) not null, + section_id char not null, + mode char not null, + episode char not null, + difficulty char not null +); + +create table room_note ( + room integer references room (id) not null, + note jsonb not null, + created_at timestamptz default current_timestamp not null +); diff --git a/src/entity/gateway/postgres/migrations/V0013__room2.sql b/src/entity/gateway/postgres/migrations/V0013__room2.sql new file mode 100644 index 0000000..f7a6a0a --- /dev/null +++ b/src/entity/gateway/postgres/migrations/V0013__room2.sql @@ -0,0 +1,17 @@ +drop table room_note; +drop table room; + +create table room ( + id serial primary key not null, + name varchar(32) not null, + section_id "char" not null, + mode "char" not null, + episode "char" not null, + difficulty "char" not null +); + +create table room_note ( + room integer references room (id) not null, + note jsonb not null, + created_at timestamptz default current_timestamp not null +); diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index e1a6c8c..f3a2f39 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -7,7 +7,10 @@ use libpso::util::vec_to_array; use crate::entity::account::*; use crate::entity::character::*; use crate::entity::item::*; +use crate::entity::room::*; use crate::ship::map::MapArea; +use crate::ship::room::{Episode, Difficulty}; +use crate::ship::monster::MonsterType; #[derive(Debug, sqlx::FromRow)] pub struct PgUserAccount { @@ -577,6 +580,16 @@ pub enum PgItemNoteDetail { }, EnemyDrop { character_id: u32, + room_id: u32, + monster_type: MonsterType, + map_area: MapArea, + x: f32, + y: f32, + z: f32, + }, + BoxDrop { + character_id: u32, + room_id: u32, map_area: MapArea, x: f32, y: f32, @@ -592,14 +605,19 @@ pub enum PgItemNoteDetail { y: f32, z: f32, }, - Consumed, + Consumed { + character_id: u32, + }, FedToMag { + character_id: u32, mag: u32, }, BoughtAtShop { character_id: u32, }, - SoldToShop, + SoldToShop { + character_id: u32, + }, Trade { trade_id: u32, character_to: u32, @@ -624,8 +642,16 @@ impl From for PgItemNoteDetail { ItemNote::CharacterCreation{character_id} => PgItemNoteDetail::CharacterCreation { character_id: character_id.0, }, - ItemNote::EnemyDrop{character_id, map_area, x, y, z} => PgItemNoteDetail::EnemyDrop { + ItemNote::EnemyDrop{character_id, room_id, monster_type, map_area, x, y, z} => PgItemNoteDetail::EnemyDrop { + character_id: character_id.0, + room_id: room_id.0, + monster_type, + map_area, + x,y,z, + }, + ItemNote::BoxDrop{character_id, room_id, map_area, x, y, z} => PgItemNoteDetail::BoxDrop { character_id: character_id.0, + room_id: room_id.0, map_area, x,y,z, }, @@ -637,14 +663,19 @@ impl From for PgItemNoteDetail { map_area, x,y,z, }, - ItemNote::Consumed => PgItemNoteDetail::Consumed, - ItemNote::FedToMag{mag} => PgItemNoteDetail::FedToMag{ + ItemNote::Consumed{character_id} => PgItemNoteDetail::Consumed { + character_id: character_id.0, + }, + ItemNote::FedToMag{character_id, mag} => PgItemNoteDetail::FedToMag{ + character_id: character_id.0, mag: mag.0 }, ItemNote::BoughtAtShop{character_id} => PgItemNoteDetail::BoughtAtShop { character_id: character_id.0, }, - ItemNote::SoldToShop => PgItemNoteDetail::SoldToShop, + ItemNote::SoldToShop{character_id} => PgItemNoteDetail::SoldToShop { + character_id: character_id.0, + }, ItemNote::Trade{trade_id, character_to, character_from} => PgItemNoteDetail::Trade { trade_id: trade_id.0, character_to: character_to.0, @@ -677,8 +708,16 @@ impl From for ItemNote { PgItemNoteDetail::CharacterCreation{character_id} => ItemNote::CharacterCreation { character_id: CharacterEntityId(character_id), }, - PgItemNoteDetail::EnemyDrop{character_id, map_area, x, y, z} => ItemNote::EnemyDrop { + PgItemNoteDetail::EnemyDrop{character_id, room_id, monster_type, map_area, x, y, z} => ItemNote::EnemyDrop { character_id: CharacterEntityId(character_id), + room_id: RoomEntityId(room_id), + monster_type, + map_area, + x,y,z, + }, + PgItemNoteDetail::BoxDrop{character_id, room_id, map_area, x, y, z} => ItemNote::BoxDrop { + character_id: CharacterEntityId(character_id), + room_id: RoomEntityId(room_id), map_area, x,y,z, }, @@ -690,14 +729,19 @@ impl From for ItemNote { map_area, x,y,z, }, - PgItemNoteDetail::Consumed => ItemNote::Consumed, - PgItemNoteDetail::FedToMag{mag} => ItemNote::FedToMag{ + PgItemNoteDetail::Consumed{character_id} => ItemNote::Consumed { + character_id: CharacterEntityId(character_id), + }, + PgItemNoteDetail::FedToMag{character_id, mag} => ItemNote::FedToMag{ + character_id: CharacterEntityId(character_id), mag: ItemEntityId(mag) }, PgItemNoteDetail::BoughtAtShop{character_id} => ItemNote::BoughtAtShop { character_id: CharacterEntityId(character_id), }, - PgItemNoteDetail::SoldToShop => ItemNote::SoldToShop, + PgItemNoteDetail::SoldToShop{character_id} => ItemNote::SoldToShop { + character_id: CharacterEntityId(character_id), + }, PgItemNoteDetail::Trade {trade_id, character_to, character_from} => ItemNote::Trade { trade_id: TradeId(trade_id), character_to: CharacterEntityId(character_to), @@ -880,3 +924,27 @@ impl From for TradeEntity { } } } + + +#[derive(Debug, sqlx::FromRow, Serialize)] +pub struct PgRoomEntity { + id: i32, + name: String, + section_id: i8, + mode: i8, + episode: i8, + difficulty: i8, +} + +impl From for RoomEntity { + fn from(other: PgRoomEntity) -> RoomEntity { + RoomEntity { + id: RoomEntityId(other.id as u32), + name: other.name, + section_id: SectionID::from(other.section_id as u8), + mode: RoomEntityMode::from(other.mode as u8), + episode: Episode::try_from(other.episode as u8).unwrap(), + difficulty: Difficulty::try_from(other.difficulty as u8).unwrap(), + } + } +} diff --git a/src/entity/gateway/postgres/postgres.rs b/src/entity/gateway/postgres/postgres.rs index 717f8ca..c31217f 100644 --- a/src/entity/gateway/postgres/postgres.rs +++ b/src/entity/gateway/postgres/postgres.rs @@ -10,6 +10,7 @@ use crate::entity::account::*; use crate::entity::character::*; use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError}; use crate::entity::item::*; +use crate::entity::room::*; use super::models::*; use sqlx::postgres::PgPoolOptions; @@ -178,7 +179,7 @@ async fn create_user(conn: &mut sqlx::PgConnection, user: NewUserAccountEntity) async fn get_user_by_id(conn: &mut sqlx::PgConnection, id: UserAccountId) -> Result { let user = sqlx::query_as::<_, PgUserAccount>("select * from user_accounts where id = $1") - .bind(id.0) + .bind(id.0 as i32) .fetch_one(conn).await?; Ok(user.into()) } @@ -199,8 +200,8 @@ async fn save_user(conn: &mut sqlx::PgConnection, user: &UserAccountEntity) -> R .bind(&user.password) .bind(user.banned_until) .bind(user.muted_until) - .bind(user.flags) - .bind(user.id.0) + .bind(user.flags as i32) + .bind(user.id.0 as i32) .execute(conn).await?; Ok(()) } @@ -209,7 +210,7 @@ async fn create_user_settings(conn: &mut sqlx::PgConnection, settings: NewUserSe { let new_settings = sqlx::query_as::<_, PgUserSettings>("insert into user_settings (user_account, blocked_users, key_config, joystick_config, option_flags, shortcuts, symbol_chats, team_name) values ($1, $2, $3, $4, $5, $6, $7, $8) returning *;") - .bind(settings.user_id.0) + .bind(settings.user_id.0 as i32) .bind(settings.settings.blocked_users.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::>()) .bind(settings.settings.keyboard_config.to_vec()) .bind(settings.settings.gamepad_config.to_vec()) @@ -224,7 +225,7 @@ async fn create_user_settings(conn: &mut sqlx::PgConnection, settings: NewUserSe async fn get_user_settings_by_user(conn: &mut sqlx::PgConnection, user: &UserAccountEntity) -> Result { let settings = sqlx::query_as::<_, PgUserSettings>("select * from user_settings where user_account = $1") - .bind(user.id.0) + .bind(user.id.0 as i32) .fetch_one(conn).await?; Ok(settings.into()) } @@ -235,11 +236,11 @@ async fn save_user_settings(conn: &mut sqlx::PgConnection, settings: &UserSettin .bind(settings.settings.blocked_users.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::>()) .bind(&settings.settings.keyboard_config.to_vec()) .bind(&settings.settings.gamepad_config.to_vec()) - .bind(settings.settings.option_flags) + .bind(settings.settings.option_flags as i32) .bind(&settings.settings.shortcuts.to_vec()) .bind(&settings.settings.symbol_chats.to_vec()) .bind(settings.settings.team_name.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::>()) - .bind(settings.id.0) + .bind(settings.id.0 as i32) .execute(conn).await?; Ok(()) } @@ -262,7 +263,7 @@ async fn create_character(conn: &mut sqlx::PgConnection, char: NewCharacterEntit $26, $27, $28, $29, $30) returning *;"#; let character = sqlx::query_as::<_, PgCharacter>(q) - .bind(char.user_id.0) + .bind(char.user_id.0 as i32) .bind(char.slot as i16) .bind(char.name) .bind(char.exp as i32) @@ -300,7 +301,7 @@ async fn create_character(conn: &mut sqlx::PgConnection, char: NewCharacterEntit async fn get_characters_by_user(conn: &mut sqlx::PgConnection, user: &UserAccountEntity) -> Result<[Option; 4], GatewayError> { let stream = sqlx::query_as::<_, PgCharacter>("select * from player_character where user_account = $1 and slot < 4 order by created_at;") - .bind(user.id.0) + .bind(user.id.0 as i32) .fetch(conn); Ok(stream.fold(core::array::from_fn(|_| None), |mut acc, char| async move { @@ -320,7 +321,7 @@ async fn save_character(conn: &mut sqlx::PgConnection, char: &CharacterEntity) - evade=$24, luck=$25, hp=$26, tp=$27, tech_menu=$28, option_flags=$29, playtime=$30 where id=$31;"#; sqlx::query(q) - .bind(char.user_id.0) // $1 + .bind(char.user_id.0 as i32) // $1 .bind(char.slot as i16) // $2 .bind(&char.name) // $3 .bind(char.exp as i32) // $4 @@ -370,7 +371,7 @@ async fn create_item(conn: &mut sqlx::PgConnection, item: NewItemEntity) -> Resu async fn add_item_note(conn: &mut sqlx::PgConnection, item_id: &ItemEntityId, item_note: ItemNote) -> Result<(), GatewayError> { sqlx::query("insert into item_note(item, note) values ($1, $2)") - .bind(item_id.0) + .bind(item_id.0 as i32) .bind(sqlx::types::Json(PgItemNoteDetail::from(item_note))) .execute(conn).await?; Ok(()) @@ -379,7 +380,7 @@ async fn add_item_note(conn: &mut sqlx::PgConnection, item_id: &ItemEntityId, it async fn feed_mag(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, tool_item_id: &ItemEntityId) -> Result<(), GatewayError> { sqlx::query("insert into mag_modifier (mag, modifier) values ($1, $2);") - .bind(mag_item_id.0) + .bind(mag_item_id.0 as i32) .bind(sqlx::types::Json(PgMagModifierDetail::from(mag::MagModifier::FeedMag{food: *tool_item_id}))) .execute(conn).await?; Ok(()) @@ -388,7 +389,7 @@ async fn feed_mag(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, too async fn change_mag_owner(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, character: &CharacterEntity) -> Result<(), GatewayError> { sqlx::query("insert into mag_modifier (mag, modifier) values ($1, $2);") - .bind(mag_item_id.0) + .bind(mag_item_id.0 as i32) .bind(sqlx::types::Json(PgMagModifierDetail::from(mag::MagModifier::OwnerChange(character.char_class, character.section_id)))) .execute(conn).await?; Ok(()) @@ -397,7 +398,7 @@ async fn change_mag_owner(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntit async fn use_mag_cell(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, mag_cell_id: &ItemEntityId) -> Result<(), GatewayError> { sqlx::query("insert into mag_modifier (mag, modifier) values ($1, $2);") - .bind(mag_item_id.0) + .bind(mag_item_id.0 as i32) .bind(sqlx::types::Json(PgMagModifierDetail::from(mag::MagModifier::MagCell(*mag_cell_id)))) .execute(conn).await?; Ok(()) @@ -406,7 +407,7 @@ async fn use_mag_cell(conn: &mut sqlx::PgConnection, mag_item_id: &ItemEntityId, async fn add_weapon_modifier(conn: &mut sqlx::PgConnection, item_id: &ItemEntityId, modifier: &weapon::WeaponModifier) -> Result<(), GatewayError> { sqlx::query("insert into weapon_modifier (weapon, modifier) values ($1, $2);") - .bind(item_id.0) + .bind(item_id.0 as i32) .bind(sqlx::types::Json(modifier)) .execute(conn).await?; Ok(()) @@ -416,7 +417,7 @@ async fn get_character_inventory(conn: &mut sqlx::PgConnection, char_id: &Charac { let conn = Arc::new(Mutex::new(conn.begin().await?)); // this is some degen shit let inventory = sqlx::query_as::<_, PgInventoryEntity>("select * from inventory where pchar = $1") - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(&mut **conn.lock().await).await?; Ok(InventoryEntity::new( @@ -441,14 +442,14 @@ async fn get_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn let bank = match bank_identifier { BankIdentifier::Character => { sqlx::query_as::<_, PgInventoryEntity>("select * from bank where pchar = $1") - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(&mut **conn.lock().await).await? }, BankIdentifier::Shared(bank_name) => { sqlx::query_as::<_, PgInventoryEntity>("select player_character.id as pchar, shared_bank.items as items from shared_bank join player_character on shared_bank.user_account = player_character.user_account where player_character.id = $1 and shared_bank.name = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(&bank_name.0) .fetch_optional(&mut **conn.lock().await) .await? @@ -491,7 +492,7 @@ async fn set_character_inventory(conn: &mut sqlx::PgConnection, char_id: &Charac .collect::>(); sqlx::query("insert into inventory (pchar, items) values ($1, $2) on conflict (pchar) do update set items = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(sqlx::types::Json(inventory)) .execute(conn) .await?; @@ -516,7 +517,7 @@ async fn set_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn match bank_identifier { BankIdentifier::Character => { sqlx::query("insert into bank (pchar, items, name) values ($1, $2, '') on conflict (pchar, name) do update set items = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(sqlx::types::Json(bank)) .execute(conn) .await?; @@ -526,7 +527,7 @@ async fn set_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn select player_character.user_account, $2, $3 from player_character where player_character.id = $1 on conflict (user_account, name) do update set items = $2;") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(sqlx::types::Json(bank)) .bind(&bank_name.0) .execute(conn) @@ -539,7 +540,7 @@ async fn set_character_bank(conn: &mut sqlx::PgConnection, char_id: &CharacterEn async fn get_character_equips(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId) -> Result { let equips = sqlx::query_as::<_, PgEquipped>("select * from equipped where pchar = $1") - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(conn) .await?; @@ -550,7 +551,7 @@ async fn set_character_equips(conn: &mut sqlx::PgConnection, char_id: &Character { sqlx::query(r#"insert into equipped (pchar, weapon, armor, shield, unit0, unit1, unit2, unit3, mag) values ($1, $2, $3, $4, $5, $6, $7, $8, $9) on conflict (pchar) do update set weapon=$2, armor=$3, shield=$4, unit0=$5, unit1=$6, unit2=$7, unit3=$8, mag=$9"#) - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(equips.weapon.map(|i| i.0 as i32)) .bind(equips.armor.map(|i| i.0 as i32)) .bind(equips.shield.map(|i| i.0 as i32)) @@ -568,7 +569,7 @@ async fn set_character_equips(conn: &mut sqlx::PgConnection, char_id: &Character async fn set_character_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> { sqlx::query("insert into character_meseta values ($1, $2) on conflict (pchar) do update set meseta = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(meseta.0 as i32) .execute(conn) .await?; @@ -580,7 +581,7 @@ async fn get_character_meseta(conn: &mut sqlx::PgConnection, char_id: &Character #[derive(sqlx::FromRow)] struct PgMeseta(i32); let meseta = sqlx::query_as::<_, PgMeseta>(r#"select meseta from character_meseta where pchar = $1"#) - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(conn) .await?; Ok(Meseta(meseta.0 as u32)) @@ -591,7 +592,7 @@ async fn set_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit match bank_identifier { BankIdentifier::Character => { sqlx::query("insert into bank_meseta values ($1, '', $2) on conflict (pchar, bank) do update set meseta = $2") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(meseta.0 as i32) .execute(conn) .await?; @@ -601,7 +602,7 @@ async fn set_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit select player_character.user_account, $2, $3 from player_character where player_character.id = $1 on conflict (user_account, name) do update set meseta = $3") - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(&bank_name.0) .bind(meseta.0 as i32) .execute(conn) @@ -620,7 +621,7 @@ async fn get_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit let meseta = match bank_identifier { BankIdentifier::Character => { sqlx::query_as::<_, PgMeseta>(r#"select meseta from bank_meseta where pchar = $1"#) - .bind(char_id.0) + .bind(char_id.0 as i32) .fetch_one(conn) .await? }, @@ -628,7 +629,7 @@ async fn get_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit sqlx::query_as::<_, PgMeseta>(r#"select shared_bank_meseta.meseta from shared_bank_meseta join player_character on shared_bank_meseta.user_account = player_character.user_account where player_character.id = $1 and shared_bank_meseta.name = $2"#) - .bind(char_id.0) + .bind(char_id.0 as i32) .bind(&bank_name.0) .fetch_optional(conn) .await? @@ -641,8 +642,8 @@ async fn get_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit async fn create_trade(conn: &mut sqlx::PgConnection, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result { let trade = sqlx::query_as::<_, PgTradeEntity>(r#"insert into trades (character1, character2) values ($1, $2) returning *;"#) - .bind(char_id1.0) - .bind(char_id2.0) + .bind(char_id1.0 as i32) + .bind(char_id2.0 as i32) .fetch_one(conn) .await?; Ok(trade.into()) @@ -651,8 +652,30 @@ async fn create_trade(conn: &mut sqlx::PgConnection, char_id1: &CharacterEntityI async fn set_character_playtime(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> { sqlx::query(r#"update player_character set playtime=$2 where id=$1;"#) - .bind(char_id.0) - .bind(playtime) + .bind(char_id.0 as i32) + .bind(playtime as i32) + .execute(conn) + .await?; + Ok(()) +} + +async fn create_room(conn: &mut sqlx::PgConnection, room: NewRoomEntity) -> Result { + sqlx::query_as::<_, PgRoomEntity>("insert into room (name, section_id, mode, episode, difficulty) values ($1, $2, $3, $4, $5) returning *") + .bind(room.name) + .bind(u8::from(room.section_id) as i8) + .bind(u8::from(room.mode) as i8) + .bind(u8::from(room.episode) as i8) + .bind(u8::from(room.difficulty) as i8) + .fetch_one(conn) + .await + .map(|room| room.into()) + .map_err(|err| err.into()) +} + +async fn add_room_note(conn: &mut sqlx::PgConnection, room_id: RoomEntityId, note: RoomNote) -> Result<(), GatewayError> { + sqlx::query("insert into room_note (room, note) values ($1, $2)") + .bind(room_id.0 as i32) + .bind(sqlx::types::Json(note)) .execute(conn) .await?; Ok(()) @@ -797,6 +820,14 @@ impl EntityGateway for PostgresGateway { async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> { set_character_playtime(&mut *self.pool.acquire().await?, char_id, playtime).await } + + async fn create_room(&mut self, room: NewRoomEntity) -> Result { + create_room(&mut *self.pool.acquire().await?, room).await + } + + async fn add_room_note(&mut self, room_id: RoomEntityId, note: RoomNote) -> Result<(), GatewayError> { + add_room_note(&mut *self.pool.acquire().await?, room_id, note).await + } } @@ -923,5 +954,13 @@ impl<'c> EntityGateway for PostgresTransaction<'c> { async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> { set_character_playtime(&mut *self.pgtransaction.lock().await, char_id, playtime).await } + + async fn create_room(&mut self, room: NewRoomEntity) -> Result { + create_room(&mut *self.pgtransaction.lock().await, room).await + } + + async fn add_room_note(&mut self, room_id: RoomEntityId, note: RoomNote) -> Result<(), GatewayError> { + add_room_note(&mut *self.pgtransaction.lock().await, room_id, note).await + } } diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 8b1d967..7023f7c 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -10,7 +10,9 @@ pub mod esweapon; use serde::{Serialize, Deserialize}; use crate::entity::character::CharacterEntityId; +use crate::entity::room::RoomEntityId; use crate::ship::map::MapArea; +use crate::ship::monster::MonsterType; use crate::ship::drops::ItemDropType; #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] @@ -35,8 +37,16 @@ pub enum ItemNote { }, EnemyDrop { character_id: CharacterEntityId, - //monster_type: MonsterType, - //droprate: f32, + room_id: RoomEntityId, + monster_type: MonsterType, + map_area: MapArea, + x: f32, + y: f32, + z: f32, + }, + BoxDrop { + character_id: CharacterEntityId, + room_id: RoomEntityId, map_area: MapArea, x: f32, y: f32, @@ -52,15 +62,19 @@ pub enum ItemNote { y: f32, z: f32, }, - Consumed, // TODO: character_id + Consumed { + character_id: CharacterEntityId, + }, FedToMag { - //character_id: CharacterEntityId, + character_id: CharacterEntityId, mag: ItemEntityId, }, BoughtAtShop { character_id: CharacterEntityId, }, - SoldToShop, + SoldToShop { + character_id: CharacterEntityId, + }, Trade { trade_id: TradeId, character_to: CharacterEntityId, diff --git a/src/entity/mod.rs b/src/entity/mod.rs index ba0b6e4..8970e37 100644 --- a/src/entity/mod.rs +++ b/src/entity/mod.rs @@ -2,3 +2,4 @@ pub mod gateway; pub mod account; pub mod character; pub mod item; +pub mod room; diff --git a/src/entity/room.rs b/src/entity/room.rs new file mode 100644 index 0000000..a5eeea4 --- /dev/null +++ b/src/entity/room.rs @@ -0,0 +1,83 @@ +use serde::{Serialize, Deserialize}; + + +use crate::entity::character::{CharacterEntityId, SectionID}; +use crate::ship::room::{Episode, Difficulty}; + + +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] +pub struct RoomEntityId(pub u32); + + +#[derive(Debug, Copy, Clone)] +pub enum RoomEntityMode { + Multi, + Single, + Challenge, + Battle, +} + +impl From for RoomEntityMode { + fn from(other: u8) -> RoomEntityMode { + match other { + 0 => RoomEntityMode::Multi, + 1 => RoomEntityMode::Single, + 2 => RoomEntityMode::Challenge, + 3 => RoomEntityMode::Battle, + _ => unreachable!() + } + } +} + +impl From for u8 { + fn from(other: RoomEntityMode) -> u8 { + match other { + RoomEntityMode::Multi => 0, + RoomEntityMode::Single => 1, + RoomEntityMode::Challenge => 2, + RoomEntityMode::Battle => 3, + } + } +} + + +#[derive(Debug, Clone)] +pub struct RoomEntity { + pub id: RoomEntityId, + pub name: String, + pub section_id: SectionID, + pub mode: RoomEntityMode, + pub episode: Episode, + pub difficulty: Difficulty, +} + + + +#[derive(Debug, Clone)] +pub struct NewRoomEntity { + pub name: String, + pub section_id: SectionID, + pub mode: RoomEntityMode, + pub episode: Episode, + pub difficulty: Difficulty, +} + +#[derive(Debug, Copy, Clone, Serialize)] +pub enum RoomNote { + Create { + character_id: CharacterEntityId, + }, + PlayerJoin { + character_id: CharacterEntityId, + }, + PlayerLeave { + character_id: CharacterEntityId, + }, + QuestStart { + // quest id + }, + QuestComplete { + // quest id + }, + +} diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index afdd044..0c06691 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -9,22 +9,23 @@ use std::iter::IntoIterator; use anyhow::Context; use libpso::packet::{ship::Message, messages::GameMessage}; -use crate::ship::map::MapArea; -use crate::ship::ship::SendShipPacket; use crate::entity::character::{CharacterEntity, CharacterEntityId}; use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction}; +use crate::entity::item::{ItemDetail, NewItemEntity, TradeId, ItemModifier}; +use crate::entity::item::tool::Tool; +use crate::entity::room::RoomEntityId; +use crate::ship::map::MapArea; +use crate::ship::ship::SendShipPacket; use crate::ship::items::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail}; use crate::ship::items::bank::{BankItem, BankItemDetail}; use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail}; use crate::ship::items::floor::{FloorItem, FloorItemDetail}; use crate::ship::items::apply_item::{apply_item, ApplyItemAction}; -use crate::entity::item::{ItemDetail, NewItemEntity, TradeId}; -use crate::entity::item::tool::Tool; -use crate::entity::item::ItemModifier; use crate::ship::shops::ShopItem; use crate::ship::drops::{ItemDrop, ItemDropType}; use crate::ship::packet::builder; use crate::ship::location::AreaClient; +use crate::ship::monster::MonsterType; pub enum TriggerCreateItem { Yes, @@ -513,7 +514,9 @@ where Box::pin(async move { let mut transaction = inventory_item.with_entity_id(transaction, |mut transaction, entity_id| { async move { - transaction.gateway().add_item_note(&entity_id, ItemNote::Consumed).await?; + transaction.gateway().add_item_note(&entity_id, ItemNote::Consumed { + character_id: character.id, + }).await?; Ok(transaction) }}).await?; @@ -548,7 +551,7 @@ where let mut transaction = tool.with_entity_id(transaction, |mut transaction, entity_id| { async move { transaction.gateway().add_item_note(&entity_id, ItemNote::FedToMag { - //character_id: character.id, + character_id: character.id, mag: mag_entity_id, }).await?; transaction.gateway().feed_mag(&mag_entity_id, &entity_id).await?; @@ -660,7 +663,9 @@ where let mut transaction = inventory_item.with_entity_id(transaction, |mut transaction, entity_id| { async move { - transaction.gateway().add_item_note(&entity_id, ItemNote::SoldToShop).await?; + transaction.gateway().add_item_note(&entity_id, ItemNote::SoldToShop { + character_id, + }).await?; Ok(transaction) }}).await?; transaction.gateway().set_character_meseta(&character_id, inventory.meseta).await?; @@ -904,7 +909,6 @@ where pub(super) fn convert_item_drop_to_floor_item<'a, EG, TR>( - character_id: CharacterEntityId, item_drop: ItemDrop, ) -> impl Fn((ItemStateProxy, TR), ()) -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone @@ -946,13 +950,6 @@ where let entity = transaction.gateway().create_item(NewItemEntity { item: item_detail.clone(), }).await?; - transaction.gateway().add_item_note(&entity.id, ItemNote::EnemyDrop { - character_id, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }).await?; FloorItem { item_id, item: FloorItemDetail::Individual(IndividualItemDetail { @@ -969,13 +966,6 @@ where let entity = transaction.gateway().create_item(NewItemEntity { item: ItemDetail::Tool(tool), }).await?; - transaction.gateway().add_item_note(&entity.id, ItemNote::EnemyDrop { - character_id, - map_area: item_drop.map_area, - x: item_drop.x, - y: item_drop.y, - z: item_drop.z, - }).await?; FloorItem { item_id, item: FloorItemDetail::Stacked(StackedItemDetail{ @@ -1005,6 +995,88 @@ where } } + +pub(super) fn item_note_enemy_drop<'a, EG, TR>( + character_id: CharacterEntityId, + room_id: RoomEntityId, + monster_type: MonsterType, +) -> impl Fn((ItemStateProxy, TR), FloorItem) + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone +where + EG: EntityGateway, + TR: EntityGatewayTransaction + 'a, +{ + move |(item_state, mut transaction), floor_item| { + Box::pin(async move { + match &floor_item.item { + FloorItemDetail::Individual(individual) => { + transaction.gateway().add_item_note(&individual.entity_id, ItemNote::EnemyDrop { + character_id, + room_id, + monster_type, + map_area: floor_item.map_area, + x: floor_item.x, + y: floor_item.y, + z: floor_item.z, + }).await?; + }, + FloorItemDetail::Stacked(stacked) => { + transaction.gateway().add_item_note(&stacked.entity_ids[0], ItemNote::EnemyDrop { + character_id, + room_id, + monster_type, + map_area: floor_item.map_area, + x: floor_item.x, + y: floor_item.y, + z: floor_item.z, + }).await?; + }, + _ => {}, + } + Ok(((item_state, transaction), floor_item)) + }) + } +} + +pub(super) fn item_note_box_drop<'a, EG, TR>( + character_id: CharacterEntityId, + room_id: RoomEntityId, +) -> impl Fn((ItemStateProxy, TR), FloorItem) + -> BoxFuture<'a, Result<((ItemStateProxy, TR), FloorItem), anyhow::Error>> + Clone +where + EG: EntityGateway, + TR: EntityGatewayTransaction + 'a, +{ + move |(item_state, mut transaction), floor_item| { + Box::pin(async move { + match &floor_item.item { + FloorItemDetail::Individual(individual) => { + transaction.gateway().add_item_note(&individual.entity_id, ItemNote::BoxDrop { + character_id, + room_id, + map_area: floor_item.map_area, + x: floor_item.x, + y: floor_item.y, + z: floor_item.z, + }).await?; + }, + FloorItemDetail::Stacked(stacked) => { + transaction.gateway().add_item_note(&stacked.entity_ids[0], ItemNote::BoxDrop { + character_id, + room_id, + map_area: floor_item.map_area, + x: floor_item.x, + y: floor_item.y, + z: floor_item.z, + }).await?; + }, + _ => {}, + } + Ok(((item_state, transaction), floor_item)) + }) + } +} + pub(super) fn add_item_to_local_floor<'a, EG, TR>( character_id: CharacterEntityId, ) -> impl Fn((ItemStateProxy, TR), FloorItem) @@ -1169,4 +1241,4 @@ where Ok(((item_state, transaction), ())) }) } -} \ No newline at end of file +} diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index 2bde925..0c3f948 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -6,15 +6,17 @@ use crate::ship::ship::SendShipPacket; use crate::ship::map::MapArea; use crate::entity::character::{CharacterEntity, CharacterEntityId}; use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction}; +use crate::entity::item::ItemModifier; +use crate::entity::room::RoomEntityId; use crate::ship::items::state::{ItemState, ItemStateProxy, IndividualItemDetail}; use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction}; use crate::ship::items::inventory::InventoryItem; use crate::ship::items::floor::FloorItem; -use crate::entity::item::ItemModifier; use crate::ship::shops::ShopItem; use crate::ship::trade::TradeItem; use crate::ship::location::AreaClient; use crate::ship::drops::ItemDrop; +use crate::ship::monster::MonsterType; use crate::ship::items::actions; @@ -465,6 +467,32 @@ pub fn enemy_drops_item<'a, EG> ( item_state: &'a mut ItemState, entity_gateway: &'a mut EG, character_id: CharacterEntityId, + room_id: RoomEntityId, + monster_type: MonsterType, + item_drop: ItemDrop) + -> BoxFuture<'a, Result> +where + EG: EntityGateway + 'static, +{ + entity_gateway.with_transaction(move |transaction| async move { + let item_state_proxy = ItemStateProxy::new(item_state.clone()); + let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default() + .act(actions::convert_item_drop_to_floor_item(item_drop)) + .act(actions::item_note_enemy_drop(character_id, room_id, monster_type)) + .act(actions::add_item_to_local_floor(character_id)) + .commit((item_state_proxy, transaction)) + .await?; + + item_state_proxy.commit().await; + Ok((transaction, floor_item)) + }) +} + +pub fn box_drops_item<'a, EG> ( + item_state: &'a mut ItemState, + entity_gateway: &'a mut EG, + character_id: CharacterEntityId, + room_id: RoomEntityId, item_drop: ItemDrop) -> BoxFuture<'a, Result> where @@ -473,7 +501,8 @@ where entity_gateway.with_transaction(move |transaction| async move { let item_state_proxy = ItemStateProxy::new(item_state.clone()); let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default() - .act(actions::convert_item_drop_to_floor_item(character_id, item_drop)) + .act(actions::convert_item_drop_to_floor_item(item_drop)) + .act(actions::item_note_box_drop(character_id, room_id)) .act(actions::add_item_to_local_floor(character_id)) .commit((item_state_proxy, transaction)) .await?; diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 81f0146..3c914e8 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -18,7 +18,7 @@ use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem}; use crate::ship::items::state::{ItemState, ItemStateError}; use crate::ship::items::floor::{FloorType, FloorItemDetail}; use crate::ship::items::actions::TriggerCreateItem; -use crate::ship::items::tasks::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, take_meseta, apply_modifier}; +use crate::ship::items::tasks::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, box_drops_item, take_meseta, apply_modifier}; const BANK_ACTION_DEPOSIT: u8 = 0; const BANK_ACTION_WITHDRAW: u8 = 1; @@ -89,8 +89,8 @@ where EG: EntityGateway + 'static, { let room_id = client_location.get_room(id).await?; - let monster = rooms.with(room_id, |room| Box::pin(async move { - room.maps.enemy_by_id(request_item.enemy_id as usize) + let (room_entity_id, monster) = rooms.with(room_id, |room| Box::pin(async move { + Ok::<_, anyhow::Error>((room.room_id, room.maps.enemy_by_id(request_item.enemy_id as usize)?)) })).await??; if monster.dropped_item { @@ -121,7 +121,7 @@ where client.character.id })).await?; - let floor_item = enemy_drops_item(item_state, entity_gateway, character_id, item_drop).await?; + let floor_item = enemy_drops_item(item_state, entity_gateway, character_id, room_entity_id, monster.monster, item_drop).await?; let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?; item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))); @@ -200,8 +200,8 @@ where EG: EntityGateway + Clone + 'static { let room_id = client_location.get_room(id).await?; - let box_object = rooms.with(room_id, |room| Box::pin(async move { - room.maps.object_by_id(box_drop_request.object_id as usize) + let (room_entity_id, box_object) = rooms.with(room_id, |room| Box::pin(async move { + Ok::<_, anyhow::Error>((room.room_id, room.maps.object_by_id(box_drop_request.object_id as usize)?)) })).await??; if box_object.dropped_item { @@ -232,7 +232,7 @@ where let character_id = clients.with(area_client.client, |client| Box::pin(async move { client.character.id })).await?; - let floor_item = enemy_drops_item(item_state, entity_gateway, character_id, item_drop).await?; + let floor_item = box_drops_item(item_state, entity_gateway, character_id, room_entity_id, item_drop).await?; //let floor_item = enemy_drops_item(item_state, &mut entity_gateway, client.character.id, item_drop).await?; let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?; item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))) diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index 9d7ca08..d5506c4 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -8,6 +8,7 @@ use crate::ship::location::{ClientLocation, LobbyId, RoomLobby, ClientLocationEr use crate::ship::packet; use crate::ship::items::state::ItemState; use crate::entity::gateway::EntityGateway; +use crate::entity::room::RoomNote; use crate::ship::map::MapArea; use futures::future::join_all; @@ -89,14 +90,25 @@ where } }, RoomLobby::Room(old_room) => { + let room_entity_id = rooms.with(old_room, |room| Box::pin(async { + room.room_id + })).await?; if client_location.get_client_neighbors(id).await?.is_empty() { rooms.remove(old_room).await; } + + let character_id = clients.with(id, |client| Box::pin(async { + client.character.id + })).await?; clients.with(id, |client| { let mut item_state = item_state.clone(); + let mut entity_gateway = entity_gateway.clone(); Box::pin(async move { item_state.remove_character_from_room(&client.character).await; - })}).await?; + entity_gateway.add_room_note(room_entity_id, RoomNote::PlayerLeave { + character_id + }).await + })}).await??; }, } let leave_lobby = packet::builder::lobby::remove_from_lobby(id, client_location).await?; diff --git a/src/ship/packet/handler/quest.rs b/src/ship/packet/handler/quest.rs index e451f9f..1c8c31e 100644 --- a/src/ship/packet/handler/quest.rs +++ b/src/ship/packet/handler/quest.rs @@ -46,8 +46,9 @@ pub async fn send_quest_category_list(id: ClientId, let room_id = client_location.get_room(id).await?; let rql = rql.clone(); rooms.with_mut(room_id, |room| Box::pin(async move { - let qcl = quest::quest_category_list(&room.quests[rql.flag.clamp(0, (room.quests.len() - 1) as u32) as usize]); - room.set_quest_group(rql.flag as usize); + //let qcl = quest::quest_category_list(&room.quests[rql.flag.clamp(0, (room.quests.len() - 1) as u32) as usize]); + room.quest_group = rql.flag.into(); + let qcl = quest::quest_category_list(room.quests()); Ok(vec![(id, SendShipPacket::QuestCategoryList(qcl))]) })).await? } @@ -59,10 +60,10 @@ pub async fn select_quest_category(id: ClientId, -> Result, anyhow::Error> { let room_id = client_location.get_room(id).await?; rooms.with(room_id, |room| Box::pin(async move { - let (_, category_quests) = room.quests[room.quest_group.value()].iter() + let (_, category_quests) = room.quests() + .iter() .nth(menuselect.item as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(menuselect.item as u16))?; - let ql = quest::quest_list(menuselect.item, category_quests); Ok(vec![(id, SendShipPacket::QuestOptionList(ql))]) })).await? @@ -76,7 +77,7 @@ pub async fn quest_detail(id: ClientId, -> Result, anyhow::Error> { let room_id = client_location.get_room(id).await?; rooms.with(room_id, |room| Box::pin(async move { - let (_, category_quests) = room.quests[room.quest_group.value()].iter() + let (_, category_quests) = room.quests().iter() .nth(questdetailrequest.category as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(questdetailrequest.category))?; @@ -105,7 +106,7 @@ pub async fn player_chose_quest(id: ClientId, rooms.with_mut(room_id, |room| { let clients = clients.clone(); Box::pin(async move { - let quest = room.quests[room.quest_group.value()].iter() + let quest = room.quests().iter() .nth(questmenuselect.category as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(questmenuselect.category))? .1 @@ -149,7 +150,7 @@ pub async fn quest_file_request(id: ClientId, let quest_file_request = quest_file_request.clone(); rooms.with(room_id, |room| Box::pin(async move { let (category_id, quest_id, datatype) = parse_filename(&quest_file_request.filename)?; - let (_, category_quests) = room.quests[room.quest_group.value()].iter() + let (_, category_quests) = room.quests().iter() .nth(category_id as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(category_id))?; @@ -182,7 +183,7 @@ pub async fn quest_chunk_ack(id: ClientId, let quest_chunk_ack = quest_chunk_ack.clone(); rooms.with(room_id, |room| Box::pin(async move { let (category_id, quest_id, datatype) = parse_filename(&quest_chunk_ack.filename)?; - let (_, category_quests) = room.quests[room.quest_group.value()].iter() + let (_, category_quests) = room.quests().iter() .nth(category_id as usize) .ok_or_else(|| ShipError::InvalidQuestCategory(category_id))?; diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 4cdf611..9198c63 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -7,7 +7,9 @@ use libpso::packet::ship::*; use libpso::packet::messages::*; use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; +use crate::entity::gateway::EntityGateway; use crate::entity::character::SectionID; +use crate::entity::room::{NewRoomEntity, RoomEntityMode, RoomNote}; use crate::ship::drops::DropTable; use crate::ship::ship::{SendShipPacket, Clients, ShipEvent}; use crate::ship::room::{Rooms, Episode, Difficulty, RoomState, RoomMode}; @@ -17,20 +19,25 @@ use crate::ship::packet::builder; use crate::ship::items::state::ItemState; #[allow(clippy::too_many_arguments)] -pub async fn create_room(id: ClientId, - create_room: CreateRoom, - client_location: &mut ClientLocation, - clients: &Clients, - item_state: &mut ItemState, - rooms: &Rooms, - map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, - event: ShipEvent) - -> Result, anyhow::Error> { +pub async fn create_room(id: ClientId, + create_room: CreateRoom, + entity_gateway: &mut EG, + client_location: &mut ClientLocation, + clients: &Clients, + item_state: &mut ItemState, + rooms: &Rooms, + map_builder: Arc Maps + Send + Sync>>, + drop_table_builder: Arc DropTable + Send + Sync>>, + event: ShipEvent) + -> Result, anyhow::Error> +where + EG: EntityGateway + Clone + 'static, +{ let level = clients.with(id, |client| Box::pin(async move { LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp) })).await?; - match Difficulty::try_from(create_room.difficulty)? { + let difficulty = Difficulty::try_from(create_room.difficulty)?; + match difficulty { Difficulty::Ultimate if level < 80 => { return Ok(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto create Ultimate rooms.".into())))]) }, @@ -44,15 +51,42 @@ pub async fn create_room(id: ClientId, }; let area = client_location.get_area(id).await?; - let area_client = client_location.get_local_client(id).await?; + let old_area_client = client_location.get_local_client(id).await?; let lobby_neighbors = client_location.get_client_neighbors(id).await?; let room_id = client_location.create_new_room(id).await?; + let new_area_client = client_location.get_local_client(id).await?; + + let name = String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).to_string(); + let mode = match (create_room.battle, create_room.challenge, create_room.single_player) { + (1, 0, 0) => RoomEntityMode::Battle, + (0, 1, 0) => RoomEntityMode::Challenge, + (0, 0, 1) => RoomEntityMode::Single, + _ => RoomEntityMode::Multi, + }; + let episode = create_room.episode.try_into()?; + let difficulty = create_room.difficulty.try_into()?; + let room = clients.with(id, |client| { let mut item_state = item_state.clone(); + let mut entity_gateway = entity_gateway.clone(); Box::pin(async move { - item_state.add_character_to_room(room_id, &client.character, area_client).await; - let mut room = RoomState::from_create_room(&create_room, map_builder, drop_table_builder, client.character.section_id, event)?; + item_state.add_character_to_room(room_id, &client.character, new_area_client).await; + let room_entity = entity_gateway.create_room(NewRoomEntity { + name: name.clone(), + section_id: client.character.section_id, + mode, + episode, + difficulty, + }).await?; + + entity_gateway.add_room_note(room_entity.id, RoomNote::Create { + character_id: client.character.id, + }).await?; + + let mut room = RoomState::new(room_entity.id, mode, episode, difficulty, + client.character.section_id, name, create_room.password, event, + map_builder, drop_table_builder)?; room.bursting = true; Ok::<_, anyhow::Error>(room) })}).await??; @@ -62,7 +96,7 @@ pub async fn create_room(id: ClientId, let mut result = vec![(id, SendShipPacket::JoinRoom(join_room))]; if let Ok(leader) = client_location.get_area_leader(area).await { - let leave_lobby = SendShipPacket::LeaveLobby(LeaveLobby::new(area_client.local_client.id(), leader.local_client.id())); + let leave_lobby = SendShipPacket::LeaveLobby(LeaveLobby::new(old_area_client.local_client.id(), leader.local_client.id())); result.extend(lobby_neighbors .into_iter() .map(move |c| { @@ -90,14 +124,19 @@ pub async fn room_name_request(id: ClientId, } } -pub async fn join_room(id: ClientId, - pkt: MenuSelect, - client_location: &mut ClientLocation, - clients: &Clients, - item_state: &mut ItemState, - rooms: &Rooms, - event: ShipEvent) - -> Result, anyhow::Error> { +#[allow(clippy::too_many_arguments)] +pub async fn join_room(id: ClientId, + pkt: MenuSelect, + entity_gateway: &mut EG, + client_location: &mut ClientLocation, + clients: &Clients, + item_state: &mut ItemState, + rooms: &Rooms, + event: ShipEvent) + -> Result, anyhow::Error> +where + EG: EntityGateway + Clone + 'static, +{ let room_id = RoomId(pkt.item as usize); if !rooms.exists(room_id).await { return Ok(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("This room no longer exists!".into())))]) @@ -105,8 +144,8 @@ pub async fn join_room(id: ClientId, let level = clients.with(id, |client| Box::pin(async move { LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp) })).await?; - let (difficulty, bursting) = rooms.with(room_id, |room| Box::pin(async move { - (room.mode.difficulty(), room.bursting) + let (difficulty, bursting, room_entity_id) = rooms.with(room_id, |room| Box::pin(async move { + (room.mode.difficulty(), room.bursting, room.room_id) })).await?; match difficulty { @@ -135,9 +174,14 @@ pub async fn join_room(id: ClientId, clients.with(id, |client| { let mut item_state = item_state.clone(); + let mut entity_gateway = entity_gateway.clone(); Box::pin(async move { + entity_gateway.add_room_note(room_entity_id, RoomNote::PlayerJoin { + character_id: client.character.id, + }).await?; item_state.add_character_to_room(room_id, &client.character, area_client).await; - })}).await?; + Ok::<_, anyhow::Error>(()) + })}).await??; let join_room = rooms.with(room_id, |room| { let clients = clients.clone(); @@ -154,7 +198,7 @@ pub async fn join_room(id: ClientId, rooms.with_mut(room_id, |room| Box::pin(async move { room.bursting = true; })).await?; - + Ok(vec![(id, SendShipPacket::JoinRoom(join_room))] .into_iter() .chain(original_room_clients.into_iter() diff --git a/src/ship/quests.rs b/src/ship/quests.rs index 02c1906..4f5eb26 100644 --- a/src/ship/quests.rs +++ b/src/ship/quests.rs @@ -11,7 +11,7 @@ use ages_prs::{LegacyPrsDecoder, LegacyPrsEncoder}; use byteorder::{LittleEndian, ReadBytesExt}; use libpso::util::array_to_utf16; use crate::ship::map::{MapArea, MapAreaError, MapObject, MapEnemy, enemy_data_from_stream, objects_from_stream}; -use crate::ship::room::Episode; +use crate::ship::room::{Episode, RoomMode}; use crate::ship::map::area::{MapAreaLookup, MapAreaLookupBuilder}; @@ -152,11 +152,14 @@ fn parse_dat(dat: &[u8], episode: &Episode, map_areas: &MapAreaLookup) -> Result } #[derive(Error, Debug)] -#[error("")] pub enum QuestLoadError { + #[error("io error {0}")] IoError(#[from] std::io::Error), + #[error("parse dat error {0}")] ParseDatError(#[from] ParseDatError), + #[error("could not read metadata")] CouldNotReadMetadata, + #[error("could not load config file")] CouldNotLoadConfigFile, } @@ -233,7 +236,7 @@ pub fn load_quest(bin_path: PathBuf, dat_path: PathBuf, quest_path: PathBuf) -> } -pub fn load_quests(mut quest_path: PathBuf) -> Result { +pub fn load_quests_path(mut quest_path: PathBuf) -> Result { let mut f = File::open(quest_path.clone()).map_err(|_| QuestLoadError::CouldNotLoadConfigFile)?; let mut s = String::new(); f.read_to_string(&mut s)?; @@ -242,28 +245,58 @@ pub fn load_quests(mut quest_path: PathBuf) -> Result let ql: BTreeMap = toml::from_str(s.as_str()).map_err(|_| QuestLoadError::CouldNotLoadConfigFile)?; Ok(ql.into_iter().map(|(category, category_details)| { - let quests = category_details.quests - .into_iter() - .filter_map(|quest| { - load_quest(quest.bin.into(), quest.dat.into(), quest_path.to_path_buf()) - .and_then(|quest | { - if used_quest_ids.contains(&quest.id) { - warn!("quest id already exists: {}", quest.id); - return None; - } - used_quest_ids.insert(quest.id); - Some(quest) - }) - }); - (QuestCategory{ - index: category_details.list_order, - name: category, - description: category_details.description, - }, quests.collect()) + ( + QuestCategory { + index: category_details.list_order, + name: category, + description: category_details.description, + }, + category_details.quests + .into_iter() + .filter_map(|quest| { + load_quest(quest.bin.into(), quest.dat.into(), quest_path.to_path_buf()) + .and_then(|quest | { + if used_quest_ids.contains(&quest.id) { + warn!("quest id already exists: {}", quest.id); + return None; + } + used_quest_ids.insert(quest.id); + Some(quest) + }) + }) + .collect() + ) }).collect()) } +pub fn load_standard_quests(mode: RoomMode) -> Result { + match mode { + RoomMode::Single {episode, .. } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "single", "quests.toml"])) + }, + RoomMode::Multi {episode, .. } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "multi", "quests.toml"])) + }, + _ => { + Ok(BTreeMap::new()) + } + } +} + +pub fn load_government_quests(mode: RoomMode) -> Result { + match mode { + RoomMode::Single {episode, .. } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) + }, + RoomMode::Multi {episode, .. } => { + load_quests_path(PathBuf::from_iter(["data", "quests", "bb", &episode.to_string(), "government", "quests.toml"])) + }, + _ => { + Ok(BTreeMap::new()) + } + } +} diff --git a/src/ship/room.rs b/src/ship/room.rs index 87e5585..b3a03c2 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use std::convert::{From, Into, TryFrom, TryInto}; -use std::path::PathBuf; +use std::convert::{From, Into, TryFrom}; use async_std::sync::{Arc, RwLock, RwLockReadGuard}; use futures::future::BoxFuture; use futures::stream::{FuturesOrdered, Stream}; @@ -11,6 +10,7 @@ use rand::Rng; use crate::ship::map::Maps; use crate::ship::drops::DropTable; use crate::entity::character::SectionID; +use crate::entity::room::{RoomEntityId, RoomEntityMode}; use crate::ship::monster::{load_monster_stats_table, MonsterType, MonsterStats}; use crate::ship::map::area::MapAreaLookup; use crate::ship::quests; @@ -55,7 +55,7 @@ impl Rooms { None => false, } } - + pub async fn with<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result where T: Send, @@ -92,7 +92,7 @@ impl Rooms { Err(ShipError::InvalidRoom(room_id.0 as u32).into()) } } - + pub async fn get(&self, room_id: RoomId) -> RwLockReadGuard> { self.0 .get(room_id.0) @@ -282,8 +282,15 @@ impl From for QuestCategoryType { fn from(f: usize) -> QuestCategoryType { match f { 0 => QuestCategoryType::Standard, - 1 => QuestCategoryType::Government, - _ => QuestCategoryType::Standard, // TODO: panic? + _ => QuestCategoryType::Government, + } + } +} +impl From for QuestCategoryType { + fn from(f: u32) -> QuestCategoryType { + match f { + 0 => QuestCategoryType::Standard, + _ => QuestCategoryType::Government, } } } @@ -298,6 +305,7 @@ impl QuestCategoryType { } pub struct RoomState { + pub room_id: RoomEntityId, pub mode: RoomMode, pub name: String, pub password: [u16; 16], @@ -309,22 +317,22 @@ pub struct RoomState { pub monster_stats: Box>, pub map_areas: MapAreaLookup, pub quest_group: QuestCategoryType, - pub quests: Vec, - // items on ground + pub standard_quests: quests::QuestList, + pub government_quests: quests::QuestList, // enemy info } impl RoomState { pub fn get_flags_for_room_list(&self) -> u8 { let mut flags = 0u8; - + match self.mode { RoomMode::Single {..} => {flags += 0x04} RoomMode::Battle {..} => {flags += 0x10}, RoomMode::Challenge {..} => {flags += 0x20}, _ => {flags += 0x40}, }; - + if self.password[0] > 0 { flags += 0x02; } @@ -345,85 +353,59 @@ impl RoomState { difficulty + 0x22 } - pub fn set_quest_group(&mut self, group: usize) { - self.quest_group = QuestCategoryType::from(group); - } - - pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom, - map_builder: Arc Maps + Send + Sync>>, - drop_table_builder: Arc DropTable + Send + Sync>>, - section_id: SectionID, - event: ShipEvent) - -> Result { - if [create_room.battle, create_room.challenge, create_room.single_player].iter().sum::() > 1 { - return Err(RoomCreationError::InvalidMode) - } - - let room_mode = if create_room.battle == 1 { - RoomMode::Battle { - episode: create_room.episode.try_into()?, - difficulty: create_room.difficulty.try_into()?, - } - } - else if create_room.challenge == 1 { - RoomMode::Challenge { - episode: create_room.episode.try_into()?, - } - } - else if create_room.single_player == 1 { - RoomMode::Single { - episode: create_room.episode.try_into()?, - difficulty: create_room.difficulty.try_into()?, - } + pub fn quests(&self) -> &quests::QuestList { + match self.quest_group { + QuestCategoryType::Standard => &self.standard_quests, + QuestCategoryType::Government => &self.government_quests, } - else { // normal multimode - RoomMode::Multi { - episode: create_room.episode.try_into()?, - difficulty: create_room.difficulty.try_into()?, - } - }; - + } - // push the usual set of quests for the selected mode - let mut qpath = PathBuf::from("data/quests/bb"); - qpath.push(room_mode.episode().to_string()); - qpath.push(room_mode.to_string()); - qpath.push("quests.toml"); - let mut room_quests = Vec::new(); - let quest_list = match quests::load_quests(qpath) { - Ok(qlist) => qlist, - Err(_) => return Err(RoomCreationError::CouldNotLoadQuests), + #[allow(clippy::too_many_arguments)] + pub fn new (room_id: RoomEntityId, + mode: RoomEntityMode, + episode: Episode, + difficulty: Difficulty, + section_id: SectionID, + name: String, + password: [u16; 16], + event: ShipEvent, + map_builder: Arc Maps + Send + Sync>>, + drop_table_builder: Arc DropTable + Send + Sync>>, + ) -> Result { + let mode = match mode { + RoomEntityMode::Single => RoomMode::Single { + episode, + difficulty, + }, + RoomEntityMode::Multi => RoomMode::Multi { + episode, + difficulty, + }, + RoomEntityMode::Challenge => RoomMode::Challenge { + episode, + }, + RoomEntityMode::Battle => RoomMode::Battle { + episode, + difficulty, + }, }; - room_quests.push(quest_list); - - // if multiplayer also push the government quests - if let RoomMode::Multi {..} = room_mode { - qpath = PathBuf::from("data/quests/bb/"); - qpath.push(room_mode.episode().to_string()); - qpath.push("government/quests.toml"); - - let quest_list = match quests::load_quests(qpath) { - Ok(qlist) => qlist, - Err(_) => return Err(RoomCreationError::CouldNotLoadQuests), - }; - - room_quests.push(quest_list); - } - Ok(RoomState { - monster_stats: Box::new(load_monster_stats_table(&room_mode).map_err(|_| RoomCreationError::CouldNotLoadMonsterStats(room_mode))?), - mode: room_mode, + room_id, + monster_stats: Box::new(load_monster_stats_table(&mode).map_err(|_| RoomCreationError::CouldNotLoadMonsterStats(mode))?), + mode, random_seed: rand::thread_rng().gen(), - name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(), - password: create_room.password, - maps: map_builder(room_mode, event), + name, + password, + maps: map_builder(mode, event), section_id, - drop_table: Box::new(drop_table_builder(room_mode.episode(), room_mode.difficulty(), section_id)), + drop_table: Box::new(drop_table_builder(episode, difficulty, section_id)), bursting: false, - map_areas: MapAreaLookup::new(&room_mode.episode()), + map_areas: MapAreaLookup::new(&episode), quest_group: QuestCategoryType::Standard, - quests: room_quests, + standard_quests: quests::load_standard_quests(mode)?, + government_quests: quests::load_government_quests(mode)?, }) + } } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 39e1075..cd40965 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -20,6 +20,7 @@ use crate::common::interserver::{AuthToken, Ship, ServerId, InterserverActor, Lo use crate::login::character::SHIP_MENU_ID; use crate::entity::gateway::{EntityGateway, GatewayError}; use crate::entity::character::SectionID; +use crate::entity::room::RoomNote; use crate::ship::location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; use crate::ship::drops::DropTable; use crate::ship::items; @@ -698,7 +699,7 @@ impl ServerState for ShipServerState { let select_block = handler::lobby::block_selected(id, menuselect, &self.clients, &self.item_state).await?.into_iter(); leave_lobby.chain(select_block).collect() } - ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?, + ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?, QUEST_CATEGORY_MENU_ID => handler::quest::select_quest_category(id, menuselect, &block.client_location, &block.rooms).await?, _ => unreachable!(), } @@ -723,7 +724,7 @@ impl ServerState for ShipServerState { menu: room_password_req.menu, item: room_password_req.item, }; - handler::room::join_room(id, menuselect, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? + handler::room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? } else { vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("Incorrect password".into())))] @@ -755,7 +756,8 @@ impl ServerState for ShipServerState { }, RecvShipPacket::CreateRoom(create_room) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::create_room(id, create_room, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.map_builder.clone(), self.drop_table_builder.clone(), self.event).await? + handler::room::create_room(id, create_room, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, + &block.rooms, self.map_builder.clone(), self.drop_table_builder.clone(), self.event).await? }, RecvShipPacket::RoomNameRequest(_req) => { let block = self.blocks.get_from_client(id, &self.clients).await?; @@ -850,6 +852,16 @@ impl ServerState for ShipServerState { let pkt = match block.client_location.get_area(id).await? { RoomLobby::Room(room) => { + let character_id = self.clients.with(id, |client| Box::pin(async { + client.character.id + })).await?; + block.rooms.with(room, |room| { + let mut entity_gateway = self.entity_gateway.clone(); + Box::pin(async move { + entity_gateway.add_room_note(room.room_id, RoomNote::PlayerJoin { + character_id, + }).await + })}).await; if neighbors.is_empty() { block.rooms.remove(room).await; }