From 3d9e0f7ee708e7ec7f531a2012c309aa75633ddd Mon Sep 17 00:00:00 2001 From: Akulij Date: Wed, 18 Jun 2025 21:59:47 +0600 Subject: [PATCH] fast commit --- Cargo.lock | 538 +++++++++++++++++++++++- Cargo.toml | 5 + mainbot.js | 14 +- src/bot_handler.rs | 104 +++-- src/bot_manager.rs | 32 +- src/botscript.rs | 992 +-------------------------------------------- src/db/mod.rs | 11 + src/main.rs | 15 +- 8 files changed, 664 insertions(+), 1047 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be62640..37c5543 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,6 +106,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + [[package]] name = "backtrace" version = "0.3.74" @@ -139,6 +145,25 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.71.1" @@ -159,6 +184,21 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" version = "1.3.2" @@ -216,6 +256,16 @@ dependencies = [ "uuid", ] +[[package]] +name = "bstr" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "build-time" version = "0.1.3" @@ -253,6 +303,26 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "capacity_builder" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2d24a6dcf0cd402a21b65d35340f3a49ff3475dc5fdac91d22d2733e6641c6" +dependencies = [ + "capacity_builder_macros", + "itoa", +] + +[[package]] +name = "capacity_builder_macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b4a6cae9efc04cc6cbb8faf338d2c497c165c83e74509cf4dbedea948bbf6e5" +dependencies = [ + "quote", + "syn 2.0.100", +] + [[package]] name = "cc" version = "1.2.17" @@ -370,6 +440,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "cooked-waker" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147be55d677052dabc6b22252d5dd0fd4c29c8c27aa4f2fbef0f94aa003b406f" + [[package]] name = "copy_dir" version = "0.1.3" @@ -419,6 +495,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-queue" version = "0.3.12" @@ -491,6 +576,126 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid", +] + +[[package]] +name = "deno_core" +version = "0.350.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e273b731fce500130790e777cb2631dc451db412975304d23816c1e444a10c5b" +dependencies = [ + "anyhow", + "az", + "bincode", + "bit-set", + "bit-vec", + "bytes", + "capacity_builder", + "cooked-waker", + "deno_core_icudata", + "deno_error", + "deno_ops", + "deno_path_util", + "deno_unsync", + "futures", + "indexmap 2.8.0", + "libc", + "parking_lot", + "percent-encoding", + "pin-project", + "serde", + "serde_json", + "serde_v8", + "smallvec", + "sourcemap", + "static_assertions", + "thiserror 2.0.12", + "tokio", + "url", + "v8", + "wasm_dep_analyzer", +] + +[[package]] +name = "deno_core_icudata" +version = "0.74.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695" + +[[package]] +name = "deno_error" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612ec3fc481fea759141b0c57810889b0a4fb6fee8f10748677bfe492fd30486" +dependencies = [ + "deno_error_macro", + "libc", + "serde", + "serde_json", + "tokio", + "url", +] + +[[package]] +name = "deno_error_macro" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8380a4224d5d2c3f84da4d764c4326cac62e9a1e3d4960442d29136fc07be863" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "deno_ops" +version = "0.226.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28b12489187c71fa123731cc783d48beb17ae5df04da991909cc2ae5a3d0ef9" +dependencies = [ + "indexmap 2.8.0", + "proc-macro-rules", + "proc-macro2", + "quote", + "stringcase", + "strum", + "strum_macros", + "syn 2.0.100", + "thiserror 2.0.12", +] + +[[package]] +name = "deno_path_util" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516f813389095889776b81cc9108ff6f336fd9409b4b12fc0138aea23d2708e1" +dependencies = [ + "deno_error", + "percent-encoding", + "sys_traits", + "thiserror 2.0.12", + "url", +] + +[[package]] +name = "deno_unsync" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6742a724e8becb372a74c650a1aefb8924a5b8107f7d75b3848763ea24b27a87" +dependencies = [ + "futures-util", + "parking_lot", + "tokio", +] + [[package]] name = "deranged" version = "0.4.1" @@ -676,6 +881,16 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "erased-serde" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" version = "0.3.10" @@ -761,6 +976,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fslock" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04412b8935272e3a9bae6f48c7bfff74c2911f60525404edfdd28e49884c3bfb" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "funty" version = "2.0.0" @@ -926,11 +1151,13 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" name = "gongbotrs" version = "0.1.0" dependencies = [ + "anyhow", "async-trait", "bson", "build-time", "chrono", "chrono-tz", + "deno_core", "dotenvy", "enum_stringify", "envconfig", @@ -939,14 +1166,26 @@ dependencies = [ "itertools 0.14.0", "lazy_static", "log", + "mlua", "mongodb", "pretty_env_logger", "quickjs-rusty", "serde", "serde_json", + "serde_v8", "teloxide", "thiserror 2.0.12", "tokio", + "v8", +] + +[[package]] +name = "gzip-header" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95cc527b92e6029a62960ad99aa8a6660faa4555fe5f731aab13aa6a921795a2" +dependencies = [ + "crc32fast", ] [[package]] @@ -1345,6 +1584,12 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + [[package]] name = "include_dir" version = "0.7.4" @@ -1508,6 +1753,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "linux-raw-sys" version = "0.9.3" @@ -1545,6 +1796,15 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "luau0-src" +version = "0.12.3+luau663" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ae337c644bbf86a8d8e9ce3ee023311833d41741baf5e51acc31b37843aba1" +dependencies = [ + "cc", +] + [[package]] name = "macro_magic" version = "0.5.1" @@ -1633,9 +1893,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] @@ -1651,6 +1911,37 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "mlua" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1f5f8fbebc7db5f671671134b9321c4b9aa9adeafccfd9a8c020ae45c6a35d0" +dependencies = [ + "bstr", + "either", + "erased-serde", + "libloading", + "mlua-sys", + "num-traits", + "parking_lot", + "rustc-hash", + "rustversion", + "serde", + "serde-value", +] + +[[package]] +name = "mlua-sys" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380c1f7e2099cafcf40e51d3a9f20a346977587aa4d012eae1f043149a728a93" +dependencies = [ + "cc", + "cfg-if", + "luau0-src", + "pkg-config", +] + [[package]] name = "mongodb" version = "3.2.3" @@ -1747,6 +2038,7 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "rand 0.8.5", ] [[package]] @@ -1832,6 +2124,21 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + [[package]] name = "parking" version = "2.2.1" @@ -1870,6 +2177,12 @@ dependencies = [ "regex", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pbkdf2" version = "0.11.0" @@ -2017,6 +2330,29 @@ dependencies = [ "quote", ] +[[package]] +name = "proc-macro-rules" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c277e4e643ef00c1233393c673f655e3672cf7eb3ba08a00bdd0ea59139b5f" +dependencies = [ + "proc-macro-rules-macros", + "proc-macro2", + "syn 2.0.100", +] + +[[package]] +name = "proc-macro-rules-macros" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "207fffb0fe655d1d47f6af98cc2793405e85929bdbc420d685554ff07be27ac7" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "proc-macro2" version = "1.0.94" @@ -2275,6 +2611,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + [[package]] name = "rustix" version = "1.0.3" @@ -2284,7 +2633,7 @@ dependencies = [ "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.9.3", "windows-sys 0.59.0", ] @@ -2418,6 +2767,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.17" @@ -2463,6 +2822,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_v8" +version = "0.259.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e4c5f439cffc03021c8bfd380cd1ef6acb4788a72b7e54bf4a83c73f91f8a0" +dependencies = [ + "deno_error", + "num-bigint", + "serde", + "smallvec", + "thiserror 2.0.12", + "v8", +] + [[package]] name = "serde_with" version = "3.12.0" @@ -2564,6 +2937,24 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "sourcemap" +version = "9.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22afbcb92ce02d23815b9795523c005cb9d3c214f8b7a66318541c240ea7935" +dependencies = [ + "base64-simd", + "bitvec", + "data-encoding", + "debugid", + "if_chain", + "rustc-hash", + "serde", + "serde_json", + "unicode-id-start", + "url", +] + [[package]] name = "spin" version = "0.9.8" @@ -2723,6 +3114,18 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stringcase" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72abeda133c49d7bddece6c154728f83eec8172380c80ab7096da9487e20d27c" + [[package]] name = "stringprep" version = "0.1.5" @@ -2740,6 +3143,28 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.100", +] + [[package]] name = "subtle" version = "2.6.1" @@ -2788,6 +3213,26 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "sys_traits" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc4707edf3196e8037ee45018d1bb1bfb233b0e4fc440fa3d3f25bc69bfdaf26" +dependencies = [ + "sys_traits_macros", +] + +[[package]] +name = "sys_traits_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "181f22127402abcf8ee5c83ccd5b408933fec36a6095cf82cda545634692657e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "take_mut" version = "0.2.2" @@ -2885,7 +3330,7 @@ dependencies = [ "fastrand", "getrandom 0.3.2", "once_cell", - "rustix", + "rustix 1.0.3", "windows-sys 0.59.0", ] @@ -3013,6 +3458,7 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -3152,6 +3598,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.18.0" @@ -3170,6 +3622,12 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" +[[package]] +name = "unicode-id-start" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f322b60f6b9736017344fa0635d64be2f458fbc04eef65f6be22976dd1ffd5b" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -3245,6 +3703,22 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "v8" +version = "137.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b387c1c5731284e756c03280032068e68e5b52f6c4714492403c30f650ad52" +dependencies = [ + "bindgen", + "bitflags 2.9.0", + "fslock", + "gzip-header", + "home", + "miniz_oxide", + "paste", + "which", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -3257,6 +3731,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "walkdir" version = "2.5.0" @@ -3381,6 +3861,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasm_dep_analyzer" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51cf5f08b357e64cd7642ab4bbeb11aecab9e15520692129624fb9908b8df2c" +dependencies = [ + "deno_error", + "thiserror 2.0.12", +] + [[package]] name = "web-sys" version = "0.3.77" @@ -3397,6 +3887,18 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "which" +version = "6.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" +dependencies = [ + "either", + "home", + "rustix 0.38.44", + "winsafe", +] + [[package]] name = "whoami" version = "1.6.0" @@ -3413,6 +3915,22 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +[[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.9" @@ -3422,6 +3940,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" @@ -3688,6 +4212,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + [[package]] name = "wit-bindgen-rt" version = "0.39.0" diff --git a/Cargo.toml b/Cargo.toml index 97d5367..a83a47c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,13 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0.98" async-trait = "0.1.88" bson = { version = "2.14.0", features = ["chrono-0_4"] } build-time = "0.1.3" chrono = { version = "0.4.40", features = ["serde"] } chrono-tz = "0.10.3" +deno_core = "0.350.0" dotenvy = "0.15.7" enum_stringify = "0.6.3" envconfig = "0.11.0" @@ -19,14 +21,17 @@ git-const = "1.1.0" itertools = "0.14.0" lazy_static = "1.5.0" log = "0.4.27" +mlua = { version = "0.10.5", features = ["luau", "serialize"] } mongodb = "3.2.3" pretty_env_logger = "0.5.0" quickjs-rusty = { git = "https://github.com/akulij/quickjs-rusty.git", rev = "549f830" } serde = { version = "1.0.219", features = ["derive", "serde_derive"] } serde_json = "1.0.140" +serde_v8 = "0.259.0" teloxide = { version = "0.14.0", features = ["macros", "postgres-storage-nativetls"] } thiserror = "2.0.12" tokio = { version = "1.44.1", features = ["rt-multi-thread", "macros"] } +v8 = "137.2.0" [lints.clippy] print_stdout = "warn" diff --git a/mainbot.js b/mainbot.js index 828655f..9f39da9 100644 --- a/mainbot.js +++ b/mainbot.js @@ -93,14 +93,22 @@ print(JSON.stringify(dialog.buttons)) const config = { version: 1.1, - timezone: 3, + timezone: 5, } const notifications = [ + { + // time: "17:38", + time: {once: "17:49"}, + message: {literal: "show_projects"}, + }, // { - // time: "18:14", + // time: { + // hour: 0, + // delta_minutes: 2, + // }, // message: {literal: "show_projects"}, - // }, + // } ] // {config, dialog} diff --git a/src/bot_handler.rs b/src/bot_handler.rs index a7930cb..405b75f 100644 --- a/src/bot_handler.rs +++ b/src/bot_handler.rs @@ -15,8 +15,13 @@ use teloxide::{ }; use crate::{ - botscript::{self, message_info::MessageInfoBuilder, BotMessage, ScriptError}, + botscript::{self, message_info::MessageInfoBuilder, ScriptError}, commands::BotCommand, + config::{ + dialog::{button::ButtonLayout, message::BotMessage}, + traits::ProviderSerialize, + Provider, + }, db::{callback_info::CallbackInfo, CallDB, DB}, message_answerer::MessageAnswerer, notify_admin, update_user_tg, @@ -29,7 +34,7 @@ pub type BotHandler = type CallbackStore = CallbackInfo; -pub fn script_handler(r: Arc>) -> BotHandler { +pub fn script_handler(r: Arc>>) -> BotHandler { let cr = r.clone(); dptree::entry() .branch( @@ -91,8 +96,13 @@ pub fn script_handler(r: Arc>) -> BotHandler { ) } -async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) -> BotResult<()> { - info!("Eval BM: {:?}", bm); +async fn handle_botmessage( + bot: Bot, + mut db: DB, + bm: BotMessage

, + msg: Message, +) -> BotResult<()> { + // info!("Eval BM: {:?}", bm); let tguser = match msg.from.clone() { Some(user) => user, None => return Ok(()), // do nothing, cause its not usecase of function @@ -116,31 +126,34 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - let is_propagate: bool = match bm.get_handler() { Some(handler) => 'prop: { - let ctx = match handler.context() { - Some(ctx) => ctx, - // falling back to propagation - None => break 'prop true, - }; - let jsuser = to_js(ctx, &tguser).map_err(ScriptError::from)?; + // let ctx = match handler.context() { + // Some(ctx) => ctx, + // // falling back to propagation + // None => break 'prop true, + // }; + // let jsuser = to_js(ctx, &tguser).map_err(ScriptError::from)?; + let puser = ::se_from(&tguser).unwrap(); let mi = MessageInfoBuilder::new() .set_variant(variant.clone()) .build(); - let mi = to_js(ctx, &mi).map_err(ScriptError::from)?; - info!( - "Calling handler {:?} with msg literal: {:?}", - handler, - bm.literal() - ); - match handler.call_args(vec![jsuser, mi]) { + // let mi = to_js(ctx, &mi).map_err(ScriptError::from)?; + let pmi = ::se_from(&mi).unwrap(); + // info!( + // "Calling handler {:?} with msg literal: {:?}", + // handler, + // bm.literal() + // ); + match handler.call_args(vec![puser, pmi]) { Ok(v) => { - if v.is_bool() { - v.to_bool().unwrap_or(true) - } else if v.is_int() { - v.to_int().unwrap_or(1) != 0 - } else { - // falling back to propagation - true - } + todo!() + // if v.is_bool() { + // v.to_bool().unwrap_or(true) + // } else if v.is_int() { + // v.to_int().unwrap_or(1) != 0 + // } else { + // // falling back to propagation + // true + // } } Err(err) => { error!("Failed to get return of handler, err: {err}"); @@ -161,7 +174,7 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - join_all(buttons.iter().map(async |r| { join_all(r.iter().map(async |b| { match b { - botscript::ButtonLayout::Callback { + ButtonLayout::Callback { name, literal: _, callback, @@ -198,9 +211,14 @@ async fn handle_botmessage(bot: Bot, mut db: DB, bm: BotMessage, msg: Message) - Ok(()) } -async fn handle_callback(bot: Bot, mut db: DB, bm: BotMessage, q: CallbackQuery) -> BotResult<()> { +async fn handle_callback( + bot: Bot, + mut db: DB, + bm: BotMessage

, + q: CallbackQuery, +) -> BotResult<()> { bot.answer_callback_query(&q.id).await?; - info!("Eval BM: {:?}", bm); + // info!("Eval BM: {:?}", bm); let tguser = q.from.clone(); let user = db .get_or_init_user(tguser.id.0 as i64, &tguser.first_name) @@ -210,24 +228,20 @@ async fn handle_callback(bot: Bot, mut db: DB, bm: BotMessage, q: CallbackQuery) let is_propagate: bool = match bm.get_handler() { Some(handler) => 'prop: { - let ctx = match handler.context() { - Some(ctx) => ctx, - // falling back to propagation - None => break 'prop true, - }; - let jsuser = to_js(ctx, &tguser).map_err(ScriptError::from)?; + let puser = ::se_from(&tguser).unwrap(); let mi = MessageInfoBuilder::new().build(); - let mi = to_js(ctx, &mi).map_err(ScriptError::from)?; - match handler.call_args(vec![jsuser, mi]) { + let pmi = ::se_from(&mi).unwrap(); + match handler.call_args(vec![puser, pmi]) { Ok(v) => { - if v.is_bool() { - v.to_bool().unwrap_or(true) - } else if v.is_int() { - v.to_int().unwrap_or(1) != 0 - } else { - // falling back to propagation - true - } + todo!() + // if v.is_bool() { + // v.to_bool().unwrap_or(true) + // } else if v.is_int() { + // v.to_int().unwrap_or(1) != 0 + // } else { + // // falling back to propagation + // true + // } } Err(err) => { error!("Failed to get return of handler, err: {err}"); @@ -248,7 +262,7 @@ async fn handle_callback(bot: Bot, mut db: DB, bm: BotMessage, q: CallbackQuery) join_all(buttons.iter().map(async |r| { join_all(r.iter().map(async |b| { match b { - botscript::ButtonLayout::Callback { + ButtonLayout::Callback { name, literal: _, callback, diff --git a/src/bot_manager.rs b/src/bot_manager.rs index 7b7595e..d6c6c0c 100644 --- a/src/bot_manager.rs +++ b/src/bot_manager.rs @@ -40,32 +40,28 @@ pub struct BotInfo { pub static DEFAULT_SCRIPT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/default_script.js")); -pub struct BotManager +pub struct BotManager where - BIG: FnMut() -> FBIS, - FBIS: Future, - BIS: Iterator, - HM: FnMut(BotInstance) -> FHI, - FHI: Future, - HI: Iterator, + BIG: AsyncFnMut() -> BII, // BotInstance Getter + BII: Iterator, // BotInstance Iterator + BHG: AsyncFnMut(BotInstance) -> BHI, // BotHandler Getter + BHI: Iterator, // BotHandler Iterator { bot_pool: HashMap, bi_getter: BIG, - h_mapper: HM, + h_mapper: BHG, } -impl BotManager +impl BotManager where - BIG: FnMut() -> FBIS, - FBIS: Future, - BIS: Iterator, - HM: FnMut(BotInstance) -> FHI, - FHI: Future, - HI: Iterator, + BIG: AsyncFnMut() -> BII, // BotInstance Getter + BII: Iterator, // BotInstance Iterator + BHG: AsyncFnMut(BotInstance) -> BHI, // BotHandler Getter + BHI: Iterator, // BotHandler Iterator { - /// bi_getter - fnmut that returns iterator over BotInstance - /// h_map - fnmut that returns iterator over handlers by BotInstance - pub fn with(bi_getter: BIG, h_mapper: HM) -> Self { + /// bi_getter - async fnmut that returns iterator over BotInstance + /// h_map - async fnmut that returns iterator over handlers by BotInstance + pub fn with(bi_getter: BIG, h_mapper: BHG) -> Self { Self { bot_pool: Default::default(), bi_getter, diff --git a/src/botscript.rs b/src/botscript.rs index d5d917a..6b35edb 100644 --- a/src/botscript.rs +++ b/src/botscript.rs @@ -5,24 +5,17 @@ use std::collections::HashMap; use std::sync::{Mutex, PoisonError}; use std::time::Duration; +use crate::config::Provider; use crate::db::raw_calls::RawCallError; use crate::db::{CallDB, DbError, User, DB}; use crate::message_answerer::MessageAnswererError; +use crate::runtimes::v8::V8Runtime; use crate::utils::parcelable::{ParcelType, Parcelable, ParcelableError, ParcelableResult}; -use crate::{notify_admin, BotError}; +use crate::{notify_admin, runtimes, BotError}; use chrono::{DateTime, Days, NaiveTime, ParseError, TimeDelta, Timelike, Utc}; use db::attach_db_obj; use futures::future::join_all; use itertools::Itertools; -use quickjs_rusty::serde::{from_js, to_js}; -use quickjs_rusty::utils::create_empty_object; -use quickjs_rusty::utils::create_string; -use quickjs_rusty::ContextError; -use quickjs_rusty::ExecutionError; -use quickjs_rusty::JsFunction; -use quickjs_rusty::OwnedJsValue as JsValue; -use quickjs_rusty::ValueError; -use quickjs_rusty::{Context, OwnedJsObject}; use serde::Deserialize; use serde::Serialize; @@ -75,987 +68,42 @@ pub enum ResolveError { pub type ScriptResult = Result; -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BotFunction { - func: FunctionMarker, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(untagged)] -pub enum FunctionMarker { - /// serde is not able to (de)serialize this, so ignore it and fill - /// in runtime with injection in DeserializeJS - #[serde(skip)] - Function(JsFunction), - StrTemplate(String), -} - -impl FunctionMarker { - pub fn as_str_template(&self) -> Option<&String> { - if let Self::StrTemplate(v) = self { - Some(v) - } else { - None - } - } - - pub fn as_function(&self) -> Option<&JsFunction> { - if let Self::Function(v) = self { - Some(v) - } else { - None - } - } - - pub fn set_js_function(&mut self, f: JsFunction) { - *self = Self::Function(f) - } -} - -impl Parcelable for BotFunction { - fn get_field( - &mut self, - _name: &str, - ) -> crate::utils::parcelable::ParcelableResult> { - todo!() - } - - fn resolve(&mut self) -> ParcelableResult> - where - Self: Sized + 'static, - { - Ok(ParcelType::Function(self)) - } -} - -impl BotFunction { - pub fn by_name(name: String) -> Self { - Self { - func: FunctionMarker::StrTemplate(name), - } - } - - pub fn call_context(&self, runner: &Runner) -> ScriptResult { - match &self.func { - FunctionMarker::Function(f) => { - let val = f.call(Default::default())?; - Ok(val) - } - FunctionMarker::StrTemplate(func_name) => runner.run_script(&format!("{func_name}()")), - } - } - - pub fn context(&self) -> Option<*mut quickjs_rusty::JSContext> { - match &self.func { - FunctionMarker::Function(js_function) => Some(js_function.context()), - FunctionMarker::StrTemplate(_) => None, - } - } - - pub fn call(&self) -> ScriptResult { - self.call_args(Default::default()) - } - - pub fn call_args(&self, args: Vec) -> ScriptResult { - if let FunctionMarker::Function(f) = &self.func { - let val = f.call(args)?; - Ok(val) - } else { - Err(ScriptError::BotFunctionError( - "Js Function is not defined".to_string(), - )) - } - } - - pub fn set_js_function(&mut self, f: JsFunction) { - self.func.set_js_function(f); - } -} - -pub trait DeserializeJS { - fn js_into<'a, T: Deserialize<'a>>(&'a self) -> ScriptResult; -} - -impl DeserializeJS for JsValue { - fn js_into<'a, T: Deserialize<'a>>(&'a self) -> ScriptResult { - let rc = from_js(self.context(), self)?; - - Ok(rc) - } -} - -#[derive(Default)] -pub struct DeserializerJS { - fn_map: HashMap, -} - -impl DeserializerJS { - pub fn new() -> Self { - Self { - fn_map: HashMap::new(), - } - } - - pub fn deserialize_js<'a, T: Deserialize<'a> + Parcelable + 'static>( - value: &'a JsValue, - ) -> ScriptResult { - let mut s = Self::new(); - - s.inject_templates(value, "".to_string())?; - - let mut res = value.js_into()?; - - for (k, jsf) in s.fn_map { - let item: ParcelType<'_, BotFunction> = - match Parcelable::::get_nested(&mut res, &k) { - Ok(item) => item, - Err(err) => { - log::error!("Failed to inject original functions to structs, error: {err}"); - continue; - } - }; - if let ParcelType::Function(f) = item { - f.set_js_function(jsf); - } - } - - Ok(res) - } - - pub fn inject_templates( - &mut self, - value: &JsValue, - path: String, - ) -> ScriptResult> { - if let Ok(f) = value.clone().try_into_function() { - self.fn_map.insert(path.clone(), f); - return Ok(Some(path)); - } else if let Ok(o) = value.clone().try_into_object() { - let path = if path.is_empty() { path } else { path + "." }; // trying to avoid . in the start - // of stringified path - let res = o - .properties_iter()? - .chunks(2) - .into_iter() - // since chunks(2) is used and properties iterator over object - // always has even elements, unwrap will not fail - .map( - #[allow(clippy::unwrap_used)] - |mut chunk| (chunk.next().unwrap(), chunk.next().unwrap()), - ) - .map(|(k, p)| k.and_then(|k| p.map(|p| (k, p)))) - .filter_map(|m| m.ok()) - .try_for_each(|(k, p)| { - let k = match k.to_string() { - Ok(k) => k, - Err(err) => return Err(ScriptError::ValueError(err)), - }; - let res = match self.inject_templates(&p, path.clone() + &k)? { - Some(_) => { - let fo = JsValue::new( - o.context(), - create_empty_object(o.context()).expect("couldn't create object"), - ) - .try_into_object() - .expect("the object created was not an object :/"); - fo.set_property( - "func", - JsValue::new( - o.context(), - create_string(o.context(), "somefunc") - .expect("couldn't create string"), - ), - ) - .expect("wasn't able to set property on object :/"); - o.set_property(&k, fo.into_value()) - } - None => Ok(()), - }; - match res { - Ok(res) => Ok(res), - Err(err) => Err(ScriptError::ExecutionError(err)), - } - }); - res?; - }; - - Ok(None) - } -} - // TODO: remove this function since it is suitable only for early development #[allow(clippy::print_stdout)] fn print(s: String) { println!("{s}"); } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BotConfig { - version: f64, - /// relative to UTC, for e.g., - /// timezone = 3 will be UTC+3, - /// timezone =-2 will be UTC-2, - #[serde(default)] - timezone: i8, -} - -pub trait ResolveValue { - type Value; - - fn resolve(self) -> ScriptResult; - fn resolve_with(self, runner: &Runner) -> ScriptResult; -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(untagged)] -pub enum KeyboardDefinition { - Rows(Vec), - Function(BotFunction), -} - -impl Parcelable for KeyboardDefinition { - fn get_field(&mut self, _name: &str) -> ParcelableResult> { - todo!() - } - fn resolve(&mut self) -> ParcelableResult> - where - Self: Sized + 'static, - { - match self { - KeyboardDefinition::Rows(rows) => Ok(rows.resolve()?), - KeyboardDefinition::Function(f) => Ok(f.resolve()?), - } - } -} - -impl ResolveValue for KeyboardDefinition { - type Value = Vec<::Value>; - - fn resolve(self) -> ScriptResult { - match self { - KeyboardDefinition::Rows(rows) => rows.into_iter().map(|r| r.resolve()).collect(), - KeyboardDefinition::Function(f) => { - ::resolve(f.call()?.js_into()?) - } - } - } - - fn resolve_with(self, runner: &Runner) -> ScriptResult { - match self { - KeyboardDefinition::Rows(rows) => { - rows.into_iter().map(|r| r.resolve_with(runner)).collect() - } - KeyboardDefinition::Function(f) => { - ::resolve_with(f.call_context(runner)?.js_into()?, runner) - } - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(untagged)] -pub enum RowDefinition { - Buttons(Vec), - Function(BotFunction), -} - -impl Parcelable for RowDefinition { - fn get_field(&mut self, _name: &str) -> ParcelableResult> { - todo!() - } - fn resolve(&mut self) -> ParcelableResult> - where - Self: Sized + 'static, - { - match self { - Self::Buttons(buttons) => Ok(buttons.resolve()?), - Self::Function(f) => Ok(f.resolve()?), - } - } -} - -impl ResolveValue for RowDefinition { - type Value = Vec<::Value>; - - fn resolve(self) -> ScriptResult { - match self { - RowDefinition::Buttons(buttons) => buttons.into_iter().map(|b| b.resolve()).collect(), - RowDefinition::Function(f) => ::resolve(f.call()?.js_into()?), - } - } - - fn resolve_with(self, runner: &Runner) -> ScriptResult { - match self { - RowDefinition::Buttons(buttons) => buttons - .into_iter() - .map(|b| b.resolve_with(runner)) - .collect(), - RowDefinition::Function(f) => { - ::resolve_with(f.call_context(runner)?.js_into()?, runner) - } - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(untagged)] -pub enum ButtonDefinition { - Button(ButtonRaw), - ButtonLiteral(String), - Function(BotFunction), -} - -impl ResolveValue for ButtonDefinition { - type Value = ButtonRaw; - - fn resolve(self) -> ScriptResult { - match self { - ButtonDefinition::Button(button) => Ok(button), - ButtonDefinition::ButtonLiteral(l) => Ok(ButtonRaw::from_literal(l)), - ButtonDefinition::Function(f) => ::resolve(f.call()?.js_into()?), - } - } - - fn resolve_with(self, runner: &Runner) -> ScriptResult { - match self { - ButtonDefinition::Button(button) => Ok(button), - ButtonDefinition::ButtonLiteral(l) => Ok(ButtonRaw::from_literal(l)), - ButtonDefinition::Function(f) => { - ::resolve_with(f.call_context(runner)?.js_into()?, runner) - } - } - } -} - -impl Parcelable for ButtonDefinition { - fn get_field(&mut self, _name: &str) -> ParcelableResult> { - todo!() - } - fn resolve(&mut self) -> ParcelableResult> - where - Self: Sized + 'static, - { - match self { - Self::Button(braw) => Ok(braw.resolve()?), - Self::ButtonLiteral(s) => Ok(s.resolve()?), - Self::Function(f) => Ok(f.resolve()?), - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ButtonRaw { - name: ButtonName, - callback_name: String, -} - -impl Parcelable for ButtonRaw { - fn get_field(&mut self, _name: &str) -> ParcelableResult> { - todo!() - } -} - -impl ButtonRaw { - pub fn from_literal(literal: String) -> Self { - ButtonRaw { - name: ButtonName::Literal { - literal: literal.clone(), - }, - callback_name: literal, - } - } - - pub fn name(&self) -> &ButtonName { - &self.name - } - - pub fn callback_name(&self) -> &str { - &self.callback_name - } - - pub fn literal(&self) -> Option { - match self.name() { - ButtonName::Value { .. } => None, - ButtonName::Literal { literal } => Some(literal.to_string()), - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(untagged)] -pub enum ButtonName { - Value { name: String }, - Literal { literal: String }, -} - -impl ButtonName { - pub async fn resolve_name(self, db: &mut DB) -> ScriptResult { - match self { - ButtonName::Value { name } => Ok(name), - ButtonName::Literal { literal } => { - let value = db.get_literal_value(&literal).await?; - - Ok(match value { - Some(value) => Ok(value), - None => { - notify_admin(&format!("Literal `{literal}` is not set!!!")).await; - Err(ResolveError::IncorrectLiteral(format!( - "not found literal `{literal}` in DB" - ))) - } - }?) - } - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Button { - name: String, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BotMessage { - // buttons: Vec