diff --git a/Cargo.lock b/Cargo.lock index 55b37e5b..1dccb4c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" [[package]] name = "argon2" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73" +checksum = "95c2fcf79ad1932ac6269a738109997a83c227c09b75842ae564dc8ede6a861c" dependencies = [ "base64ct", "blake2", @@ -96,9 +96,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.64" +version = "0.1.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" +checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc" dependencies = [ "proc-macro2", "quote", @@ -212,9 +212,9 @@ dependencies = [ [[package]] name = "blaze-pk" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd605ed57c7d763b61b516664002579d2ad0858111459885109550be23267e5" +checksum = "38e97dc56b568d199448b9080dc7a93ad8f8f3ec9e0f6e0a775842f226f4f8b9" dependencies = [ "blaze-pk-derive", "bytes", @@ -247,9 +247,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -286,9 +286,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ "iana-time-zone", "js-sys", @@ -387,9 +387,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62" +checksum = "9a140f260e6f3f79013b8bfc65e7ce630c9ab4388c6a89c71e07226f49487b72" dependencies = [ "cc", "cxxbridge-flags", @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690" +checksum = "da6383f459341ea689374bf0a42979739dc421874f112ff26f829b8040b8e613" dependencies = [ "cc", "codespan-reporting", @@ -414,15 +414,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf" +checksum = "90201c1a650e95ccff1c8c0bb5a343213bdd317c6e600a93075bca2eff54ec97" [[package]] name = "cxxbridge-macro" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" +checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56" dependencies = [ "proc-macro2", "quote", @@ -431,9 +431,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" dependencies = [ "darling_core", "darling_macro", @@ -441,9 +441,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", @@ -455,9 +455,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core", "quote", @@ -602,9 +602,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "futures" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" +checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549" dependencies = [ "futures-channel", "futures-core", @@ -617,9 +617,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" +checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" dependencies = [ "futures-core", "futures-sink", @@ -627,15 +627,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" +checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" [[package]] name = "futures-executor" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" +checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83" dependencies = [ "futures-core", "futures-task", @@ -655,15 +655,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" +checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" [[package]] name = "futures-macro" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" +checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6" dependencies = [ "proc-macro2", "quote", @@ -672,21 +672,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" +checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" [[package]] name = "futures-task" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" [[package]] name = "futures-util" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" dependencies = [ "futures-channel", "futures-core", @@ -839,9 +839,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.24" +version = "0.14.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c" +checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" dependencies = [ "bytes", "futures-channel", @@ -952,9 +952,9 @@ dependencies = [ [[package]] name = "interlink" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66dc4111cc70e6e2a1f4a8cd3afd56b08120bb156de3e411101a0d34a36f75e0" +checksum = "95672cfa6996c4b3095a137b027d13ead0f025859dd9f443d7f7177a87937241" dependencies = [ "futures-core", "futures-sink", @@ -1014,9 +1014,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "libm" @@ -1058,13 +1058,12 @@ dependencies = [ [[package]] name = "local-ip-address" version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa9d02443a1741e9f51dafdfcbffb3863b2a89c457d762b40337d6c5153ef81" +source = "git+https://github.com/jacobtread/local-ip-address.git#d451e57065ea6d8983213c84b30fdd3b124fb295" dependencies = [ "libc", "neli", "thiserror", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -1169,17 +1168,32 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] name = "neli" -version = "0.5.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9053554eb5dcb7e10d9cdab1206965bde870eed5d0d341532ca035e3ba221508" +checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43" dependencies = [ "byteorder", "libc", + "log", + "neli-proc-macros", +] + +[[package]] +name = "neli-proc-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4" +dependencies = [ + "either", + "proc-macro2", + "quote", + "serde", + "syn", ] [[package]] @@ -1335,14 +1349,14 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] name = "password-hash" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", "rand_core 0.6.4", @@ -1351,9 +1365,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pem-rfc7468" @@ -1463,7 +1477,7 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "pocket-relay" -version = "0.3.0" +version = "0.3.1" dependencies = [ "argon2", "axum", @@ -1530,18 +1544,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "5308e8208729c3e1504a6cfad0d5daacc4614c9a2e65d1ea312a34b5cb00fe84" dependencies = [ "proc-macro2", ] @@ -1767,9 +1781,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "6.4.2" +version = "6.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "283ffe2f866869428c92e0d61c2f35dfb4355293cdfdc48f49e895c15f1333d1" +checksum = "cb133b9a38b5543fad3807fb2028ea47c5f2b566f4f5e28a11902f1a358348b6" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -1778,9 +1792,9 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "6.3.1" +version = "6.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31ab23d42d71fb9be1b643fe6765d292c5e14d46912d13f3ae2815ca048ea04d" +checksum = "4d4e0f0ced47ded9a68374ac145edd65a6c1fa13a96447b873660b2a568a0fd7" dependencies = [ "proc-macro2", "quote", @@ -1791,9 +1805,9 @@ dependencies = [ [[package]] name = "rust-embed-utils" -version = "7.3.0" +version = "7.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1669d81dfabd1b5f8e2856b8bbe146c6192b0ba22162edc738ac0a5de18f054" +checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731" dependencies = [ "sha2", "walkdir", @@ -1828,9 +1842,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "ryu" @@ -1855,9 +1869,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scratch" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5e082f6ea090deaf0e6dd04b68360fd5cddb152af6ce8927c9d25db299f98c" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" [[package]] name = "sct" @@ -1871,9 +1885,9 @@ dependencies = [ [[package]] name = "sea-orm" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a0e3ec90718d849c73b167df7a476672b64c7ee5f3c582179069e63b2451e1" +checksum = "587b878d32666ec796da72f84263f7103072426d3f84faae38af5f2844e34aa7" dependencies = [ "async-stream", "async-trait", @@ -1894,9 +1908,9 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d89f7d4d2533c178e08a9e1990619c391e9ca7b402851d02a605938b15e03d9" +checksum = "6abb2f32ddb765e5a392975887ae3e0a7b90256a3fa7d3fbd7fe7ea4fb2237e5" dependencies = [ "bae", "heck 0.3.3", @@ -1907,9 +1921,9 @@ dependencies = [ [[package]] name = "sea-orm-migration" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355b1e2763e73d36de6f4539b04fc5d01b232e5c97785e0d08c4becbc2accad3" +checksum = "e83b3786e42c62bf54196910648da81011bae8d87edb121083b92b0a5711d072" dependencies = [ "async-trait", "futures", @@ -2000,18 +2014,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.152" +version = "1.0.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "71f2b4817415c6d4210bfe1c7bfcf4801b2d904cb4d0e1a8fdb651013c9e86b8" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "d071a94a3fac4aff69d023a7f411e33f40f3483f8c5190b1953822b6b76d7630" dependencies = [ "proc-macro2", "quote", @@ -2020,9 +2034,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" dependencies = [ "itoa", "ryu", @@ -2312,18 +2326,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" dependencies = [ "proc-macro2", "quote", @@ -2394,7 +2408,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -2553,15 +2567,15 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-bidi" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" +checksum = "524b68aca1d05e03fdf03fcdce2c6c94b6daf6d16861ddaa7e4f2b6638a9052c" [[package]] name = "unicode-ident" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -2820,21 +2834,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - [[package]] name = "windows-sys" version = "0.45.0" diff --git a/Cargo.toml b/Cargo.toml index 087c7f95..c6e8d904 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ features = ["std", "serde"] [package] name = "pocket-relay" -version = "0.3.0" +version = "0.3.1" description = "Pocket Relay Server" repository = "https://github.com/PocketRelay/Server" readme = "README.md" @@ -55,7 +55,7 @@ database = { path = "database", package = "pocket-relay-database", version = "^0 rust-embed = { version = "6.4.2", features = ["debug-embed"] } # Password hashing -argon2 = "0.4" +argon2 = "0.5" base64ct = { version = "1.5", features = ["alloc"] } flate2 = { version = "1", features = ["zlib"], default-features = false } @@ -65,12 +65,12 @@ ring = "0.16" dotenvy = "0.15" # Library for obtaining the local IP address of the device -local-ip-address = "0.5.0" +local-ip-address = "0.5" thiserror = "1" validator = { version = "0.16", features = ["derive"] } -interlink = "0.1.2" +interlink = "0.1" tokio-util = { version = "0.7", features = ["codec"] } futures = "0.3" @@ -105,6 +105,9 @@ version = "1.2.0" default-features = false features = ["console_appender", "file_appender"] +[patch.crates-io] +local-ip-address = { git = "https://github.com/jacobtread/local-ip-address.git" } + [profile.release] strip = true lto = true diff --git a/README.md b/README.md index ae69ba02..9a7303f2 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,13 @@ [Discord Server (https://discord.gg/yvycWW8RgR)](https://discord.gg/yvycWW8RgR) + +> **📌 Update Notice** +> If you are updating from a version lower than 0.3 you will need to +> delete the app.db file before launching or else the server will not +> work + + **Pocket Relay** Is a custom implementation of the Mass Effect 3 multiplayer servers all bundled into a easy to use server with a Dashboard for managing accounts and inventories. With **Pocket Relay** you can play Mass Effect 3 multiplayer offline by yourself, over LAN, or even over WAN as a public server diff --git a/database/src/interfaces/players.rs b/database/src/interfaces/players.rs index 3cb5f227..66591f42 100644 --- a/database/src/interfaces/players.rs +++ b/database/src/interfaces/players.rs @@ -72,10 +72,10 @@ impl Player { /// /// `id` The ID of the player /// `db` The database connection - pub fn all_data<'a>( + pub fn all_data( id: u32, - db: &'a DatabaseConnection, - ) -> impl Future>> + Send + 'a { + db: &DatabaseConnection, + ) -> impl Future>> + Send + '_ { player_data::Entity::find() .filter(player_data::Column::PlayerId.eq(id)) .all(db) @@ -214,10 +214,10 @@ impl Player { /// /// `db` The database instance /// `id` The ID of the player to find - pub fn by_id<'a>( - db: &'a DatabaseConnection, + pub fn by_id( + db: &DatabaseConnection, id: u32, - ) -> impl Future>> + Send + 'a { + ) -> impl Future>> + Send + '_ { players::Entity::find_by_id(id).one(db) } @@ -250,11 +250,7 @@ impl Player { /// /// `db` The database connection /// `password` The new hashed password - pub fn set_password<'a>( - self, - db: &'a DatabaseConnection, - password: String, - ) -> DbFuture<'a, Player> { + pub fn set_password(self, db: &DatabaseConnection, password: String) -> DbFuture<'_, Player> { let mut model = self.into_active_model(); model.password = Set(Some(password)); model.update(db) @@ -264,11 +260,7 @@ impl Player { /// /// `db` The database connection /// `role` The new role for the player - pub fn set_role<'a>( - self, - db: &'a DatabaseConnection, - role: PlayerRole, - ) -> DbFuture<'a, Player> { + pub fn set_role(self, db: &DatabaseConnection, role: PlayerRole) -> DbFuture<'_, Player> { let mut model = self.into_active_model(); model.role = Set(role); model.update(db) @@ -280,12 +272,12 @@ impl Player { /// `db` The database connection /// `username` Optional new username for the player /// `email` Optional new email for the player - pub fn set_details<'a>( + pub fn set_details( self, - db: &'a DatabaseConnection, + db: &DatabaseConnection, username: Option, email: Option, - ) -> DbFuture<'a, Player> { + ) -> DbFuture<'_, Player> { let mut model = self.into_active_model(); if let Some(username) = username { diff --git a/database/src/migration/m20221015_142649_players_table.rs b/database/src/migration/m20221015_142649_players_table.rs index b64cad80..f4c8473a 100644 --- a/database/src/migration/m20221015_142649_players_table.rs +++ b/database/src/migration/m20221015_142649_players_table.rs @@ -21,23 +21,55 @@ impl MigrationTrait for Migration { .auto_increment() .primary_key(), ) - .col(ColumnDef::new(Players::Email).string_len(254).not_null()) + .col( + ColumnDef::new(Players::Email) + .string_len(254) + .unique_key() + .not_null(), + ) .col( ColumnDef::new(Players::DisplayName) .string_len(99) .not_null(), ) - .col(ColumnDef::new(Players::SessionToken).string_len(254).null()) - .col(ColumnDef::new(Players::Origin).boolean().not_null()) - .col(ColumnDef::new(Players::Password).string().not_null()) + .col(ColumnDef::new(Players::Password).string().null()) + .col( + ColumnDef::new(Players::Role) + .tiny_integer() + .default(0) + .not_null(), + ) + .to_owned(), + ) + .await?; + + // Create index for email + manager + .create_index( + Index::create() + .name("idx-pr-email") + .table(Players::Table) + .col(Players::Email) + .unique() .to_owned(), ) .await } async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + // Drop the table manager .drop_table(Table::drop().table(Players::Table).to_owned()) + .await?; + + // Drop the index + manager + .drop_index( + Index::drop() + .name("idx-pr-email") + .table(Players::Table) + .to_owned(), + ) .await } } @@ -48,7 +80,6 @@ pub enum Players { Id, Email, DisplayName, - SessionToken, - Origin, Password, + Role, } diff --git a/database/src/migration/m20230130_174951_remove_session_token.rs b/database/src/migration/m20230130_174951_remove_session_token.rs deleted file mode 100644 index 4f7115c9..00000000 --- a/database/src/migration/m20230130_174951_remove_session_token.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! This migration removes the old session_token column from versions of the -//! database that used the old session token system - -use sea_orm_migration::prelude::*; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(Players::Table) - .drop_column(Players::SessionToken) - .to_owned(), - ) - .await - } - - async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { - Ok(()) - } -} - -#[derive(Iden)] -pub enum Players { - Table, - SessionToken, -} diff --git a/database/src/migration/m20230205_114724_add_players_role.rs b/database/src/migration/m20230205_114724_add_players_role.rs deleted file mode 100644 index c663efb9..00000000 --- a/database/src/migration/m20230205_114724_add_players_role.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! Migration for adding the role value to the player table and setting a default -//! value for all the players - -use sea_orm_migration::prelude::*; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(Players::Table) - .add_column( - ColumnDef::new(Players::Role) - .tiny_integer() - .default(0) - .not_null(), - ) - .to_owned(), - ) - .await - } - - async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(Players::Table) - .drop_column(Players::Role) - .to_owned(), - ) - .await - } -} - -#[derive(Iden)] -pub enum Players { - Table, - Role, -} diff --git a/database/src/migration/m20230223_190834_remove_origin_flag.rs b/database/src/migration/m20230223_190834_remove_origin_flag.rs deleted file mode 100644 index 9a555d0b..00000000 --- a/database/src/migration/m20230223_190834_remove_origin_flag.rs +++ /dev/null @@ -1,78 +0,0 @@ -//! This migration removes the origin flag from the players table and -//! adds the requirement that all emails are unique and creates an -//! email index -//! -//! Makes password field nullable for origin accounts - -use sea_orm_migration::prelude::*; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - // Make the email field unique - manager - .alter_table( - Table::alter() - .table(Players::Table) - // Drop origin column - .drop_column(Players::Origin) - // Make email unique - .modify_column( - ColumnDef::new(Players::Email) - .string_len(254) - .unique_key() - .not_null(), - ) - // Make password nullable - .modify_column(ColumnDef::new(Players::Password).string().null()) - .to_owned(), - ) - .await?; - // Create index for email - manager - .create_index( - Index::create() - .name("idx-pr-email") - .table(Players::Table) - .col(Players::Email) - .unique() - .to_owned(), - ) - .await - } - - async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - // Revert the unique key - // Make the email field unique - manager - .alter_table( - Table::alter() - .table(Players::Table) - .modify_column(ColumnDef::new(Players::Email).string_len(254).not_null()) - .to_owned(), - ) - .await?; - - // Drop the index - manager - .drop_index( - Index::drop() - .name("idx-pr-email") - .table(Players::Table) - .to_owned(), - ) - .await?; - Ok(()) - } -} - -#[derive(Iden)] -pub enum Players { - Table, - Origin, - Email, - Password, -} diff --git a/database/src/migration/mod.rs b/database/src/migration/mod.rs index 89098ecd..3b448e38 100644 --- a/database/src/migration/mod.rs +++ b/database/src/migration/mod.rs @@ -3,10 +3,6 @@ pub use sea_orm_migration::prelude::*; mod m20221015_142649_players_table; mod m20221015_153750_galaxy_at_war_table; mod m20221222_174733_player_data; -mod m20230130_174951_remove_session_token; -mod m20230205_114724_add_players_role; -mod m20230223_190834_remove_origin_flag; - pub struct Migrator; #[async_trait::async_trait] @@ -16,9 +12,6 @@ impl MigratorTrait for Migrator { Box::new(m20221015_142649_players_table::Migration), Box::new(m20221015_153750_galaxy_at_war_table::Migration), Box::new(m20221222_174733_player_data::Migration), - Box::new(m20230130_174951_remove_session_token::Migration), - Box::new(m20230205_114724_add_players_role::Migration), - Box::new(m20230223_190834_remove_origin_flag::Migration), ] } } diff --git a/src/servers/http/routes/gaw.rs b/src/servers/http/routes/gaw.rs index ef36d02b..d95e4b26 100644 --- a/src/servers/http/routes/gaw.rs +++ b/src/servers/http/routes/gaw.rs @@ -8,7 +8,7 @@ use crate::{ env, servers::http::ext::{ErrorStatusCode, Xml}, state::GlobalState, - utils::parsing::parse_player_class, + utils::parsing::PlayerClass, }; use axum::{ extract::{Path, Query}, @@ -127,7 +127,7 @@ async fn get_promotions(db: &DatabaseConnection, player: &Player) -> DbResult ServerResu return Ok(player); }; + debug!("Loaded origin data from official server"); + if let Err(err) = player.bulk_insert_data(db, settings.into_iter()).await { error!("Failed to set origin data: {err:?}"); return Err(ServerError::ServerUnavailable); diff --git a/src/servers/main/routes/game_manager.rs b/src/servers/main/routes/game_manager.rs index fc7ea55c..f2829e93 100644 --- a/src/servers/main/routes/game_manager.rs +++ b/src/servers/main/routes/game_manager.rs @@ -8,14 +8,16 @@ use crate::{ }, session::{GetGamePlayerMessage, GetIdMessage, SessionLink}, }, - services::game::{ - manager::{ - CreateMessage, GetGameMessage, RemovePlayerMessage, TryAddMessage, TryAddResult, + services::{ + game::{ + manager::{ + CreateMessage, GetGameMessage, RemovePlayerMessage, TryAddMessage, TryAddResult, + }, + player::GamePlayer, + RemovePlayerType, SetAttributesMessage, SetSettingMessage, SetStateMessage, + UpdateMeshMessage, }, matchmaking::{GameCreatedMessage, QueuePlayerMessage}, - player::GamePlayer, - RemovePlayerType, SetAttributesMessage, SetSettingMessage, SetStateMessage, - UpdateMeshMessage, }, state::GlobalState, utils::components::{Components as C, GameManager as G}, diff --git a/src/servers/main/routes/stats.rs b/src/servers/main/routes/stats.rs index 3f076bd5..c3f95b1a 100644 --- a/src/servers/main/routes/stats.rs +++ b/src/servers/main/routes/stats.rs @@ -105,7 +105,7 @@ async fn get_group(name: &str) -> ServerResult> { } fn get_locale_name(code: &str) -> &str { - match &code as &str { + match code as &str { "global" => "Global", "de" => "Germany", "en" => "English", diff --git a/src/servers/main/session.rs b/src/servers/main/session.rs index a3756754..c5b663aa 100644 --- a/src/servers/main/session.rs +++ b/src/servers/main/session.rs @@ -4,7 +4,7 @@ use super::router; use crate::services::game::manager::RemovePlayerMessage; -use crate::services::game::matchmaking::RemoveQueueMessage; +use crate::services::matchmaking::RemoveQueueMessage; use crate::utils::components; use crate::utils::types::PlayerID; use crate::{ @@ -151,6 +151,7 @@ impl PushExt for Link { let _ = self.do_send(WriteMessage(packet)); } } + #[derive(Message)] #[msg(rtype = "SessionID")] pub struct GetIdMessage; @@ -379,9 +380,9 @@ impl Session { Components::Util(components::Util::Ping) | Components::Util(components::Util::SuspendUserPing) ) - } else {false}; - - + } else { + false + }; if ignored { return; @@ -447,7 +448,9 @@ impl Debug for SessionPacketDebug<'_> { | Components::Util(components::Util::FetchClientConfig) | Components::Util(components::Util::UserSettingsLoadAll) ) - } else { false }; + } else { + false + }; PacketDebug { packet: self.packet, diff --git a/src/services/game/manager.rs b/src/services/game/manager.rs index 2fe85c74..0fac8e01 100644 --- a/src/services/game/manager.rs +++ b/src/services/game/manager.rs @@ -1,8 +1,8 @@ use super::{ - models::PlayerState, player::GamePlayer, rules::RuleSet, AddPlayerMessage, AttrMap, - CheckJoinableMessage, Game, GameJoinableState, GameSnapshot, RemovePlayerType, + models::PlayerState, player::GamePlayer, AddPlayerMessage, AttrMap, CheckJoinableMessage, Game, + GameJoinableState, GameSnapshot, RemovePlayerType, }; -use crate::utils::types::GameID; +use crate::{services::matchmaking::rules::RuleSet, utils::types::GameID}; use futures::FutureExt; use interlink::prelude::*; use log::debug; @@ -237,7 +237,6 @@ impl Handler for GameManager { } /// Message for removing a player from a game - #[derive(Message)] pub struct RemovePlayerMessage { /// The ID of the game to remove from diff --git a/src/services/game/mod.rs b/src/services/game/mod.rs index a077eef0..772c3834 100644 --- a/src/services/game/mod.rs +++ b/src/services/game/mod.rs @@ -1,4 +1,3 @@ -use self::rules::RuleSet; use crate::{ servers::main::session::{DetailsMessage, PushExt, SetGameMessage}, utils::{ @@ -14,11 +13,11 @@ use player::{GamePlayer, GamePlayerSnapshot}; use serde::Serialize; use std::sync::Arc; +use super::matchmaking::rules::RuleSet; + pub mod manager; -pub mod matchmaking; pub mod models; pub mod player; -pub mod rules; pub struct Game { /// Unique ID for this game diff --git a/src/services/leaderboard/mod.rs b/src/services/leaderboard/mod.rs index 87c3588b..0fa94a17 100644 --- a/src/services/leaderboard/mod.rs +++ b/src/services/leaderboard/mod.rs @@ -2,7 +2,7 @@ use self::models::*; use crate::{ state::GlobalState, utils::{ - parsing::{parse_player_character, parse_player_class}, + parsing::{KitNameDeployed, PlayerClass}, types::BoxFuture, }, }; @@ -230,12 +230,12 @@ async fn compute_n7_player(db: DatabaseConnection, player: Player) -> DbResult = classes .iter() - .filter_map(|value| parse_player_class(&value.value)) + .filter_map(|value| PlayerClass::parse(&value.value)) .collect(); let characters: Vec<_> = characters .iter() - .filter_map(|value| parse_player_character(&value.value)) + .filter_map(|value| KitNameDeployed::parse(&value.value)) .collect(); for class in classes { diff --git a/src/services/game/matchmaking.rs b/src/services/matchmaking/mod.rs similarity index 97% rename from src/services/game/matchmaking.rs rename to src/services/matchmaking/mod.rs index 7e684845..264ec13d 100644 --- a/src/services/game/matchmaking.rs +++ b/src/services/matchmaking/mod.rs @@ -1,13 +1,17 @@ -use super::{player::GamePlayer, rules::RuleSet, CheckJoinableMessage, Game, GameJoinableState}; use crate::{ - services::game::AddPlayerMessage, + services::game::{ + player::GamePlayer, AddPlayerMessage, CheckJoinableMessage, Game, GameJoinableState, + }, utils::types::{GameID, SessionID}, }; use futures::FutureExt; use interlink::prelude::*; use log::debug; +use rules::RuleSet; use std::{collections::VecDeque, sync::Arc, time::SystemTime}; +pub mod rules; + #[derive(Service)] pub struct Matchmaking { /// The queue of matchmaking entries diff --git a/src/services/game/rules.rs b/src/services/matchmaking/rules.rs similarity index 98% rename from src/services/game/rules.rs rename to src/services/matchmaking/rules.rs index 0580553a..25faae47 100644 --- a/src/services/game/rules.rs +++ b/src/services/matchmaking/rules.rs @@ -1,4 +1,4 @@ -use super::AttrMap; +use crate::services::game::AttrMap; /// Rulesets are fairly cheap to clone. Rule values are not usually /// very long. diff --git a/src/services/mod.rs b/src/services/mod.rs index 04b49f6a..d9a7be17 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -1,14 +1,13 @@ use self::{ - game::{manager::GameManager, matchmaking::Matchmaking}, - leaderboard::Leaderboard, - retriever::Retriever, - tokens::Tokens, + game::manager::GameManager, leaderboard::Leaderboard, matchmaking::Matchmaking, + retriever::Retriever, tokens::Tokens, }; use interlink::prelude::Link; use tokio::join; pub mod game; pub mod leaderboard; +pub mod matchmaking; pub mod retriever; pub mod tokens; diff --git a/src/services/retriever/mod.rs b/src/services/retriever/mod.rs index 26411c0f..afc1545d 100644 --- a/src/services/retriever/mod.rs +++ b/src/services/retriever/mod.rs @@ -163,7 +163,7 @@ impl RetSession { let request = Packet::request(self.id, component, contents); debug_log_packet(&request, "Sending to Official"); - let header = request.header.clone(); + let header = request.header; self.stream.send(request).await?; @@ -188,7 +188,7 @@ impl RetSession { pub async fn request_empty_raw(&mut self, component: Components) -> RetrieverResult { let request = Packet::request_empty(self.id, component); debug_log_packet(&request, "Sent to Official"); - let header = request.header.clone(); + let header = request.header; self.stream.send(request).await?; self.id += 1; self.expect_response(&header).await diff --git a/src/utils/env.rs b/src/utils/env.rs index 4950ea42..3e53e250 100644 --- a/src/utils/env.rs +++ b/src/utils/env.rs @@ -36,12 +36,10 @@ pub const LOGGING_DIR: (&str, &str) = ("PR_LOGGING_DIR", "data/logs"); pub const SUPER_ADMIN_EMAIL: &str = "PR_SUPER_ADMIN_EMAIL"; -#[inline] pub fn env(pair: (&str, &str)) -> String { std::env::var(pair.0).unwrap_or_else(|_| pair.1.to_string()) } -#[inline] pub fn from_env(pair: (&str, F)) -> F { if let Ok(value) = std::env::var(pair.0) { if let Ok(value) = F::from_str(&value) { @@ -50,26 +48,3 @@ pub fn from_env(pair: (&str, F)) -> F { } pair.1 } - -#[cfg(test)] -mod test { - use crate::env::from_env; - - #[test] - fn test_bool() { - std::env::set_var("TEST", "false"); - assert_eq!(from_env(("TEST", true)), false); - - std::env::set_var("TEST", "False"); - assert_eq!(from_env(("TEST", true)), true); - - std::env::set_var("TEST", "true"); - assert_eq!(from_env(("TEST", false)), true); - - std::env::set_var("TEST", "True"); - assert_eq!(from_env(("TEST", false)), false); - - std::env::set_var("TEST", "12"); - assert_eq!(from_env(("TEST", 0)), 12); - } -} diff --git a/src/utils/hashing.rs b/src/utils/hashing.rs index ab05a1ba..779f0c5c 100644 --- a/src/utils/hashing.rs +++ b/src/utils/hashing.rs @@ -30,19 +30,3 @@ pub fn verify_password(password: &str, hash: &str) -> bool { let argon2 = Argon2::default(); argon2.verify_password(password.as_bytes(), &hash).is_ok() } - -#[cfg(test)] -mod test { - use crate::utils::random::random_string; - - use super::{hash_password, verify_password}; - - /// Tests that password hashing works correctly - #[test] - fn test_password_hashing() { - let value = random_string(50); - let hash = hash_password(&value).unwrap(); - let valid = verify_password(&value, &hash); - assert_eq!(valid, true) - } -} diff --git a/src/utils/parsing.rs b/src/utils/parsing.rs index e83b8b22..f9df6836 100644 --- a/src/utils/parsing.rs +++ b/src/utils/parsing.rs @@ -2,36 +2,37 @@ use serde::Serialize; use std::str::{FromStr, Split}; -/// Structure for parsing ME3 format strings which are strings made up of sets -/// of data split by ; that each start with the 20;4; +/// Parser for parsing strings that are formatted using the ME3 +/// string format. For this format the values are split by a ; +/// and the first two values indicate the version /// -/// # Example -/// ```20;4;Sentinel;20;0.0000;50``` -pub struct MEStringParser<'a> { - split: Split<'a, char>, -} +/// VERSION1;VERSION2;DATA1;DATA2; +/// 20;4;Sentinel;20;0.00000;50 +struct MEParser<'a>(Split<'a, char>); -impl<'a> MEStringParser<'a> { - pub fn new(value: &'a str) -> Option> { - if !value.starts_with("20;4;") { - return None; - } - let split = value[5..].split(';'); - Some(MEStringParser { split }) +impl<'a> MEParser<'a> { + pub fn new(value: &'a str) -> Option> { + let mut split = value.split(';'); + + // Consume the version portion + let _v1 = split.next()?; + let _v2 = split.next()?; + + Some(MEParser(split)) } - pub fn next_str(&mut self) -> Option<&'a str> { - let next = self.split.next()?; - Some(next) + #[inline] + pub fn next(&mut self) -> Option<&'a str> { + self.0.next() } pub fn parse_next(&mut self) -> Option { - let next = self.split.next()?; + let next = self.next()?; next.parse::().ok() } pub fn next_bool(&mut self) -> Option { - let next = self.split.next()?; + let next = self.next()?; if next == "True" { Some(true) } else if next == "False" { @@ -40,6 +41,13 @@ impl<'a> MEStringParser<'a> { None } } + + pub fn skip(&mut self, n: usize) -> Option<()> { + for _ in 0..n { + self.next()?; + } + Some(()) + } } #[derive(Clone, Debug, PartialEq, Serialize)] @@ -48,159 +56,121 @@ pub struct PlayerClass<'a> { pub name: &'a str, /// The class level pub level: u8, - /// The amount of exp the class has - pub exp: f32, + // The amount of exp the class has (Field ignored for parsing) + // pub exp: f32, /// The number of promotions the class has pub promotions: u32, } -/// Attempts to parse the provided player character data string and update the fields -/// on the provided active player character model. Will return a None option if parsing -/// failed. -/// -/// # Format -/// ``` -/// 20;4;Adept;20;0;50 -/// 20;4;NAME;LEVEL;EXP;PROMOTIONS -/// ``` -pub fn parse_player_class(value: &str) -> Option> { - let mut parser = MEStringParser::new(value)?; - let name = parser.next_str()?; - let level = parser.parse_next()?; - let exp = parser.parse_next()?; - let promotions = parser.parse_next()?; - Some(PlayerClass { - name, - level, - exp, - promotions, - }) -} - -/// Structure for a player character model stored in the database -#[derive(Clone, Debug, PartialEq, Eq, Serialize)] -pub struct PlayerCharacter<'a> { - /// The name of the character kit contains the name of the class - pub kit_name: &'a str, - /// The name given to this character by the player - pub name: &'a str, - pub tint1: u16, - pub tint2: u16, - pub pattern: u16, - pub pattern_color: u16, - pub phong: u16, - pub emissive: u16, - pub skin_tone: u16, - /// The total number of seconds played as this character - pub seconds_played: u32, - pub timestamp_year: u32, - pub timestamp_month: u32, - pub timestamp_day: u32, - pub timestamp_seconds: u32, - /// Powers configuration string - /// - /// Name - /// Unlocked rank 0 - 6 - /// (1 if first split A is unlocked or 0 if not) - /// (1 if first split B is unlocked or 0 if not) - /// (2 if second split A is unlocked or 0 if not) - /// (2 if second split B is unlocked or 0 if not) - /// (3 if third split A is unlocked or 0 if not) - /// (3 if third split B is unlocked or 0 if not) - /// Unknown 0 - 6 - /// Charcter specific flag? True/False - /// - /// # Examples - /// ``` - /// AdrenalineRush 139 6.0000 1 0 2 0 3 0 0 True, - /// ConcussiveShot 148 6.0000 1 0 0 2 0 3 5 True, - /// FragGrenade 159 0.0000 0 0 0 0 0 0 2 True, - /// MPPassive 206 6.0000 0 1 2 0 0 3 5 True, - /// MPMeleePassive 204 6.0000 0 1 0 2 0 3 5 True, - /// ``` +impl PlayerClass<'_> { + /// Attempts to parse the provided player class data string /// + /// # Format /// ``` - /// # Standard abilities from mp - /// Consumable_Rocket 88 1.0000 0 0 0 0 0 0 3 False, - /// Consumable_Revive 87 1.0000 0 0 0 0 0 0 4 False, - /// Consumable_Shield 89 1.0000 0 0 0 0 0 0 5 False, - /// Consumable_Ammo 86 1.0000 0 0 0 0 0 0 6 False + /// 20;4;Adept;20;0;50 + /// 20;4;NAME;LEVEL;EXP;PROMOTIONS /// ``` - pub powers: &'a str, - /// Hotkey configuration string - pub hotkeys: &'a str, - /// Weapon configuration string - /// List of weapon IDs should not be more than two - /// 135,25 - pub weapons: &'a str, - /// Weapon mod configuration string - /// List of weapon mods split by spaces for each - /// gun. Can contain 1 or 2 - /// 135 34,25 47 - pub weapon_mods: &'a str, - /// Whether this character has been deployed before - /// (Aka used) - pub deployed: bool, - /// Whether this character has leveled up - pub leveled_up: bool, + pub fn parse(value: &str) -> Option> { + let mut parser = MEParser::new(value)?; + let name = parser.next()?; + let level = parser.parse_next()?; + parser.skip(1)?; + let promotions = parser.parse_next()?; + Some(PlayerClass { + name, + level, + promotions, + }) + } } -pub fn parse_player_character(value: &str) -> Option> { - let mut parser = MEStringParser::new(value)?; - let kit_name = parser.next_str()?; - let name = parser.next_str()?; - let tint1: u16 = parser.parse_next()?; - let tint2: u16 = parser.parse_next()?; - let pattern: u16 = parser.parse_next()?; - let pattern_color: u16 = parser.parse_next()?; - let phong: u16 = parser.parse_next()?; - let emissive: u16 = parser.parse_next()?; - let skin_tone: u16 = parser.parse_next()?; - let seconds_played: u32 = parser.parse_next()?; - let timestamp_year: u32 = parser.parse_next()?; - let timestamp_month: u32 = parser.parse_next()?; - let timestamp_day = parser.parse_next()?; - let timestamp_seconds: u32 = parser.parse_next()?; - let powers = parser.next_str()?; - let hotkeys = parser.next_str()?; - let weapons = parser.next_str()?; - let weapon_mods = parser.next_str()?; - let deployed: bool = parser.next_bool()?; - let leveled_up: bool = parser.next_bool()?; - Some(PlayerCharacter { - kit_name, - name, - tint1, - tint2, - pattern, - pattern_color, - phong, - emissive, - skin_tone, - seconds_played, - timestamp_year, - timestamp_month, - timestamp_day, - timestamp_seconds, - powers, - hotkeys, - weapons, - weapon_mods, - deployed, - leveled_up, - }) +/// Structure for holding the parsed kit_name and deployed state +/// for a player character as the result of parsing +pub struct KitNameDeployed<'a> { + pub kit_name: &'a str, + pub deployed: bool, } -#[cfg(test)] -mod test { - use crate::utils::parsing::MEStringParser; - - #[test] - fn test_a() { - let value = "20;4;AABB;123;DWADA"; - let mut parser = MEStringParser::new(value).unwrap(); - assert_eq!(parser.next_str().unwrap(), "AABB"); - assert_eq!(parser.parse_next::().unwrap(), 123); - assert_eq!(parser.next_str().unwrap(), "DWADA"); +impl KitNameDeployed<'_> { + pub fn parse(value: &str) -> Option> { + let mut parser = MEParser::new(value)?; + let kit_name = parser.next()?; + + // Skip the 17 other items + parser.skip(17)?; + + let deployed: bool = parser.next_bool()?; + + Some(KitNameDeployed { kit_name, deployed }) } } + +// Unused full format declaration for the player character data +// +// /// Structure for a player character model stored in the database +// #[derive(Clone, Debug, PartialEq, Eq, Serialize)] +// pub struct PlayerCharacter<'a> { +// /// The name of the character kit contains the name of the class +// pub kit_name: &'a str, +// /// The name given to this character by the player +// pub name: &'a str, +// pub tint1: u16, +// pub tint2: u16, +// pub pattern: u16, +// pub pattern_color: u16, +// pub phong: u16, +// pub emissive: u16, +// pub skin_tone: u16, +// /// The total number of seconds played as this character +// pub seconds_played: u32, +// pub timestamp_year: u32, +// pub timestamp_month: u32, +// pub timestamp_day: u32, +// pub timestamp_seconds: u32, +// /// Powers configuration string +// /// +// /// Name +// /// Unlocked rank 0 - 6 +// /// (1 if first split A is unlocked or 0 if not) +// /// (1 if first split B is unlocked or 0 if not) +// /// (2 if second split A is unlocked or 0 if not) +// /// (2 if second split B is unlocked or 0 if not) +// /// (3 if third split A is unlocked or 0 if not) +// /// (3 if third split B is unlocked or 0 if not) +// /// Unknown 0 - 6 +// /// Charcter specific flag? True/False +// /// +// /// # Examples +// /// ``` +// /// AdrenalineRush 139 6.0000 1 0 2 0 3 0 0 True, +// /// ConcussiveShot 148 6.0000 1 0 0 2 0 3 5 True, +// /// FragGrenade 159 0.0000 0 0 0 0 0 0 2 True, +// /// MPPassive 206 6.0000 0 1 2 0 0 3 5 True, +// /// MPMeleePassive 204 6.0000 0 1 0 2 0 3 5 True, +// /// ``` +// /// +// /// ``` +// /// # Standard abilities from mp +// /// Consumable_Rocket 88 1.0000 0 0 0 0 0 0 3 False, +// /// Consumable_Revive 87 1.0000 0 0 0 0 0 0 4 False, +// /// Consumable_Shield 89 1.0000 0 0 0 0 0 0 5 False, +// /// Consumable_Ammo 86 1.0000 0 0 0 0 0 0 6 False +// /// ``` +// pub powers: &'a str, +// /// Hotkey configuration string +// pub hotkeys: &'a str, +// /// Weapon configuration string +// /// List of weapon IDs should not be more than two +// /// 135,25 +// pub weapons: &'a str, +// /// Weapon mod configuration string +// /// List of weapon mods split by spaces for each +// /// gun. Can contain 1 or 2 +// /// 135 34,25 47 +// pub weapon_mods: &'a str, +// /// Whether this character has been deployed before +// /// (Aka used) +// pub deployed: bool, +// /// Whether this character has leveled up +// pub leveled_up: bool, +// } diff --git a/src/utils/random.rs b/src/utils/random.rs index 1ab294fe..caba3ff4 100644 --- a/src/utils/random.rs +++ b/src/utils/random.rs @@ -23,15 +23,3 @@ pub fn random_string(len: usize) -> String { output } - -#[cfg(test)] -mod test { - use super::random_string; - - #[test] - fn test_random() { - let value = random_string(128); - println!("Generated: {value:?}"); - assert!(value.len() == 128) - } -}