diff --git a/.gitignore b/.gitignore index 4117f23..fd5588e 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ _visualizer.json # blender backup files *.blend1 + +# mods +/mods diff --git a/Cargo.lock b/Cargo.lock index 098f774..313a53e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f90148830dac590fac7ccfe78ec4a8ea404c60f75a24e16407a71f0f40de775" +checksum = "2e53b0a3d5760cd2ba9b787ae0c6440ad18ee294ff71b05e3381c900a7d16cfd" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -114,9 +114,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "arrayref" @@ -232,6 +232,16 @@ dependencies = [ "objc2", ] +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -240,9 +250,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" dependencies = [ "bytemuck_derive", ] @@ -255,7 +265,7 @@ checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -298,9 +308,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" dependencies = [ "jobserver", "libc", @@ -327,9 +337,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "cfg_aliases" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e53693616d3075149f4ead59bdeecd204ac6b8192d8969757601b74bddf00f" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" @@ -534,7 +544,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -545,7 +555,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -580,7 +590,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -651,10 +661,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "errno" -version = "0.3.8" +name = "erased-serde" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "2b73807008a3c7f171cc40312f37d95ef0396e048b5848d775f54b1a4dd4a0d3" +dependencies = [ + "serde", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -678,6 +697,18 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + [[package]] name = "flate2" version = "1.0.30" @@ -688,6 +719,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + [[package]] name = "flume" version = "0.11.0" @@ -713,7 +753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9099a2f86b8e674b75d03ff154b3fe4c5208ed249ced8d69cc313a9fa40bb488" dependencies = [ "hashbrown 0.14.5", - "ttf-parser", + "ttf-parser 0.20.0", ] [[package]] @@ -734,7 +774,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -767,9 +807,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -906,6 +946,16 @@ dependencies = [ "bitflags 2.5.0", ] +[[package]] +name = "halfbrown" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" +dependencies = [ + "hashbrown 0.14.5", + "serde", +] + [[package]] name = "hash32" version = "0.2.1" @@ -985,6 +1035,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "hui" version = "0.1.0-alpha.5" @@ -1011,7 +1070,7 @@ version = "0.1.0-alpha.5" source = "git+https://github.com/griffi-gh/hui?rev=6eb3d98ad4#6eb3d98ad4747b34a366d6d92ba6f1df3bec4ba4" dependencies = [ "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -1147,6 +1206,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1227,6 +1295,7 @@ dependencies = [ "hui-winit", "image", "kubi-logging", + "kubi-mod-rt", "kubi-shared", "log", "lz4_flex", @@ -1258,6 +1327,18 @@ dependencies = [ "log", ] +[[package]] +name = "kubi-mod-rt" +version = "0.1.0" +dependencies = [ + "anyhow", + "kubi-shared", + "mlua", + "serde", + "simd-json", + "tar", +] + [[package]] name = "kubi-server" version = "0.0.0" @@ -1310,6 +1391,70 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lexical-core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" +dependencies = [ + "lexical-parse-float", + "lexical-parse-integer", + "lexical-util", + "lexical-write-float", + "lexical-write-integer", +] + +[[package]] +name = "lexical-parse-float" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" +dependencies = [ + "lexical-parse-integer", + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-parse-integer" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" +dependencies = [ + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-util" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" +dependencies = [ + "static_assertions", +] + +[[package]] +name = "lexical-write-float" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862" +dependencies = [ + "lexical-util", + "lexical-write-integer", + "static_assertions", +] + +[[package]] +name = "lexical-write-integer" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446" +dependencies = [ + "lexical-util", + "static_assertions", +] + [[package]] name = "libc" version = "0.2.154" @@ -1391,6 +1536,25 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "lua-src" +version = "546.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da0daa7eee611a4c30c8f5ee31af55266e26e573971ba9336d2993e2da129b2" +dependencies = [ + "cc", +] + +[[package]] +name = "luajit-src" +version = "210.5.8+5790d25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "441f18d9ad792e871fc2f7f2cb8902c386f6f56fdbddef3b835b61475e375346" +dependencies = [ + "cc", + "which", +] + [[package]] name = "lz4_flex" version = "0.11.3" @@ -1455,6 +1619,51 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mlua" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9bed6bce296397a9d6a86f995dd10a547a4e6949825d45225906bdcbfe7367" +dependencies = [ + "bstr", + "erased-serde", + "mlua-sys", + "mlua_derive", + "num-traits", + "once_cell", + "rustc-hash", + "serde", + "serde-value", +] + +[[package]] +name = "mlua-sys" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16a9ba1dd2c6ac971b204262d434c24d65067038598f0638b64e5dca28d52b8" +dependencies = [ + "cc", + "cfg-if", + "lua-src", + "luajit-src", + "pkg-config", +] + +[[package]] +name = "mlua_derive" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaade5f94e5829db58791664ba98f35fea6a3ffebc783becb51dc97c7a21abee" +dependencies = [ + "itertools", + "once_cell", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 2.0.63", +] + [[package]] name = "naga" version = "0.20.0" @@ -1575,7 +1784,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -1665,12 +1874,21 @@ dependencies = [ ] [[package]] -name = "owned_ttf_parser" -version = "0.20.0" +name = "ordered-float" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" dependencies = [ - "ttf-parser", + "num-traits", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b41438d2fc63c46c74a2203bf5ccd82c41ba04347b2fcf5754f230b167067d5" +dependencies = [ + "ttf-parser 0.21.1", ] [[package]] @@ -1708,9 +1926,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "percent-encoding" @@ -1735,7 +1953,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -1824,10 +2042,34 @@ dependencies = [ ] [[package]] -name = "proc-macro2" -version = "1.0.81" +name = "proc-macro-error" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -1952,6 +2194,26 @@ dependencies = [ "bitflags 2.5.0", ] +[[package]] +name = "ref-cast" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.63", +] + [[package]] name = "regex" version = "1.10.4" @@ -2017,9 +2279,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" [[package]] name = "rusty-xinput" @@ -2034,9 +2296,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -2074,35 +2336,45 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] [[package]] -name = "serde_derive" -version = "1.0.200" +name = "serde-value" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.201" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -2145,7 +2417,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -2168,7 +2440,7 @@ source = "git+https://github.com/leudz/shipyard?rev=aacf3b1df5#aacf3b1df540c7d9d dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -2177,6 +2449,28 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd-json" +version = "0.13.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "570c430b3d902ea083097e853263ae782dfe40857d93db019a12356c8e8143fa" +dependencies = [ + "getrandom", + "halfbrown", + "lexical-core", + "ref-cast", + "serde", + "serde_json", + "simdutf8", + "value-trait", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + [[package]] name = "siphasher" version = "1.0.1" @@ -2234,9 +2528,9 @@ dependencies = [ [[package]] name = "smol_str" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" dependencies = [ "serde", ] @@ -2302,7 +2596,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -2318,15 +2612,26 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -2338,22 +2643,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] [[package]] @@ -2472,7 +2777,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.7", + "winnow 0.6.8", ] [[package]] @@ -2497,6 +2802,12 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" +[[package]] +name = "ttf-parser" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" + [[package]] name = "uflow" version = "0.7.1" @@ -2536,6 +2847,18 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +[[package]] +name = "value-trait" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad8db98c1e677797df21ba03fca7d3bf9bec3ca38db930954e4fe6e1ea27eb4" +dependencies = [ + "float-cmp", + "halfbrown", + "itoa", + "ryu", +] + [[package]] name = "vec_map" version = "0.8.2" @@ -2585,7 +2908,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", "wasm-bindgen-shared", ] @@ -2619,7 +2942,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2868,6 +3191,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "which" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7" +dependencies = [ + "either", + "home", + "rustix", + "winsafe", +] + [[package]] name = "widestring" version = "1.1.0" @@ -3132,7 +3467,7 @@ dependencies = [ "bitflags 2.5.0", "bytemuck", "calloop", - "cfg_aliases 0.2.0", + "cfg_aliases 0.2.1", "concurrent-queue", "core-foundation", "core-graphics", @@ -3181,13 +3516,19 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578" +checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" dependencies = [ "memchr", ] +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + [[package]] name = "x11-dl" version = "2.21.0" @@ -3220,6 +3561,17 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + [[package]] name = "xcursor" version = "0.3.5" @@ -3253,20 +3605,20 @@ checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.63", ] diff --git a/Cargo.toml b/Cargo.toml index 8e1cac3..bebf45b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [ "kubi", "kubi-server", "kubi-shared", - "kubi-logging", + "kubi-logging", "kubi-mod-rt", ] default-members = ["kubi"] resolver = "2" diff --git a/kubi-mod-rt/Cargo.toml b/kubi-mod-rt/Cargo.toml new file mode 100644 index 0000000..ca8219b --- /dev/null +++ b/kubi-mod-rt/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "kubi-mod-rt" +version = "0.1.0" +edition = "2021" + +[dependencies] +kubi-shared = { path = "../kubi-shared" } +mlua = { version = "0.9.7", features = ["luajit52", "macros", "vendored", "serialize"] } +serde = { version = "1.0", features = ["derive"] } +#serde_json = "1.0" +simd-json = "0.13" +tar = "0.4" +anyhow = "1.0" diff --git a/kubi-mod-rt/src/lib.rs b/kubi-mod-rt/src/lib.rs new file mode 100644 index 0000000..a88476e --- /dev/null +++ b/kubi-mod-rt/src/lib.rs @@ -0,0 +1,160 @@ +use std::{cell::RefCell, collections::HashMap, io::Read, path::{Path, PathBuf}}; +use kubi_shared::networking::messages::PROTOCOL_ID as NET_PROTOCOL_ID; +use mlua::prelude::*; +use anyhow::Result; +use serde::Deserialize; + +pub const LUA_GLOBAL_KEY: &str = "kubi"; +pub const MOD_RUNTIME_VERSION: i32 = -1; + +pub trait ContextImpl { + fn block(&self, x: i32, y: i32, z: i32) -> Option; + fn set_block(&mut self, x: i32, y: i32, z: i32, v: u8) -> bool; + fn chunk_loaded(&self, x: i32, y: i32, z: i32) -> bool; +} + +struct ContextLuaUserData<'a, T: ContextImpl + 'a>(&'a RefCell); + +impl<'a, T: ContextImpl> LuaUserData for ContextLuaUserData<'a, T> { + fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field("runtime_version", MOD_RUNTIME_VERSION); + fields.add_field("netcode_version", NET_PROTOCOL_ID); + } + + fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + // getblock(x: number, y: number, z: number) -> number? + // Returns the block at the given position, or nil if the chunk is not loaded + methods.add_method("getblock", |_lua, this, (x, y, z): (i32, i32, i32)| { + Ok(this.0.borrow().block(x, y, z)) + }); + + // setblock(x: number, y: number, z: number, v: number) + // Sets the block at the given position, or errors if the chunk is not loaded + methods.add_method("setblock", |_lua, this, (x, y, z, v): (i32, i32, i32, u8)| { + // if let Some(block) = this.0.borrow_mut().block_mut(x, y, z) { + // *block = v; + // Ok(true) + // } else { + // Err(LuaError::external("attempt to modify unloaded chunk")) + // } + this.0.borrow_mut() + .set_block(x, y, z, v) + .then_some(()) + .ok_or(LuaError::external("attempt to modify unloaded chunk")) + }); + + //returns true if the chunk is loaded, false otherwise + //TODO: return full state (e.g. loaded/rendered/etc) + methods.add_method("is_chunk_loaded", |_lua, this, (x, y, z): (i32, i32, i32)| { + Ok(this.0.borrow().chunk_loaded(x, y, z)) + }); + } +} + +#[derive(Deserialize, Clone, Debug, Default)] +pub struct ModMetadata { + pub id: String, + pub name: String, + pub version: String, + pub author: String, + pub description: String, + pub entry: PathBuf, +} + +pub struct ModLuaState { + //TODO +} + +pub struct ModInstance { + pub meta: ModMetadata, + pub unpackdata: HashMap>, + pub state: Option, +} + +pub struct ModdingRuntime { + lua_state: mlua::Lua, + mods: Vec, +} + +impl ModdingRuntime { + pub fn init() -> Self { + ModdingRuntime { + lua_state: mlua::Lua::new(), + mods: Vec::new(), + } + } + + /// Load a directory of mods into the runtime recursively + /// This will only work on non-wasm targets etc + pub fn load_mod_dir(&mut self, mod_dir: &Path) -> Result<()> { + for entry in std::fs::read_dir(mod_dir)? { + let entry = entry?; + let path = entry.path(); + if path.is_dir() { + self.load_mod_dir(&path)?; + } else { + self.load_mod(&path)?; + } + } + Ok(()) + } + + /// Load a mod into the runtime + pub fn load_mod(&mut self, mod_path: &Path) -> Result<()> { + let mod_file = std::fs::File::open(mod_path)?; + let mut files = tar::Archive::new(mod_file); + let mut meta = None; + let mut unpackdata = HashMap::new(); + for file in files.entries()? { + let mut file = file?; + + let mut file_data_buf = vec![]; + file.read_to_end(&mut file_data_buf)?; + + let path = file.path()?; + if path == Path::new("manifest.json") { + // meta = Some(simd_json::serde::from_reader(&file)?); + let file_cursor = std::io::Cursor::new(&file_data_buf[..]); + meta = Some(simd_json::serde::from_reader(file_cursor)?); + } + + unpackdata.insert(path.to_path_buf(), file_data_buf.into_boxed_slice()); + } + let meta = meta.ok_or_else(|| anyhow::anyhow!("No manifest.json found"))?; + let mod_instance = ModInstance { + meta, + unpackdata, + state: None, + }; + self.mods.push(mod_instance); + Ok(()) + } + + /// Initialize all loaded mods + pub fn run_init(&mut self, ctx: &RefCell) { + for instance in &mut self.mods { + if instance.state.is_some() { + continue + } + let entry_path = instance.meta.entry.as_path(); + //TODO handle error + let entry_file = instance.unpackdata.get(entry_path) + .expect("entry file not found"); + let source = std::str::from_utf8(entry_file).unwrap(); + self.lua_state.scope(|scope| { + let ctx = ContextLuaUserData(ctx); + let userdata = scope + .create_nonstatic_userdata(ctx)?; + self.lua_state + .globals() + .set(LUA_GLOBAL_KEY, userdata).unwrap(); + let chunk = self.lua_state.load(source); + chunk.exec() + }).unwrap(); + } + } + + pub fn mods(&self) -> &[ModInstance] { + &self.mods + } +} diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index b08759c..07dc927 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["lib", "cdylib"] [dependencies] kubi-shared = { path = "../kubi-shared" } kubi-logging = { path = "../kubi-logging" } +kubi-mod-rt = { path = "../kubi-mod-rt" } hui = { git = "https://github.com/griffi-gh/hui", rev = "6eb3d98ad4" } hui-wgpu = { git = "https://github.com/griffi-gh/hui", rev = "6eb3d98ad4" } hui-winit = { git = "https://github.com/griffi-gh/hui", rev = "6eb3d98ad4", features = ["winit_30"] } diff --git a/kubi/src/lib.rs b/kubi/src/lib.rs index c5f1c15..b4cc213 100644 --- a/kubi/src/lib.rs +++ b/kubi/src/lib.rs @@ -10,6 +10,7 @@ rust_2024_compatibility, )] + use shipyard::{ World, Workload, IntoWorkload, UniqueView, UniqueViewMut, @@ -55,6 +56,7 @@ pub(crate) mod fixed_timestamp; pub(crate) mod filesystem; pub(crate) mod client_physics; pub(crate) mod chat; +pub(crate) mod modding; use world::{ init_game_world, @@ -89,6 +91,7 @@ use chat::init_chat_manager; use crosshair_ui::{init_crosshair_image, draw_crosshair}; use settings_ui::render_settings_ui; use hui_integration::hui_process_winit_events; +use modding::init_modding; /// stuff required to init the renderer and other basic systems fn pre_startup() -> Workload { @@ -113,6 +116,7 @@ fn startup() -> Workload { init_client_physics, init_chat_manager, init_crosshair_image, + init_modding, ).into_sequential_workload() } @@ -159,6 +163,8 @@ fn update() -> Workload { exit_on_esc, disconnect_on_exit.run_if(is_multiplayer), update_rendering_late, + //XXX: REMOVE THIS! + modding::run_mod_init_stage, ).into_sequential_workload() } diff --git a/kubi/src/modding.rs b/kubi/src/modding.rs new file mode 100644 index 0000000..78b2cb1 --- /dev/null +++ b/kubi/src/modding.rs @@ -0,0 +1,80 @@ +use std::{cell::RefCell, path::Path}; +use glam::ivec3; +use kubi_shared::block::Block; +use shipyard::{AllStoragesView, IntoWorkload, NonSendSync, Unique, UniqueViewMut, Workload}; +use kubi_mod_rt::{ModdingRuntime, ContextImpl}; +use crate::world::{chunk::CurrentChunkState, ChunkStorage}; + +struct Context<'a> { + cs: Option<&'a mut ChunkStorage>, +} + +impl ContextImpl for Context<'_> { + fn block(&self, x: i32, y: i32, z: i32) -> Option { + self.cs.as_ref()? + .get_block(ivec3(x, y, z)) + .map(|b| b as u8) + } + + fn set_block(&mut self, x: i32, y: i32, z: i32, v: u8) -> bool { + //TODO should this enqueue instead of setting directly? + let Some(cs) = self.cs.as_mut() else { return false }; + let block = cs.get_block_mut(ivec3(x, y, z)); + if let Some(block) = block { + //TODO handle the error here + *block = Block::try_from(v).unwrap(); + true + } else { + false + } + } + + fn chunk_loaded(&self, x: i32, y: i32, z: i32) -> bool { + self.cs.as_ref().unwrap().chunks + .get(&ivec3(x, y, z)) + .map(|c| c.current_state >= CurrentChunkState::Loaded) + .unwrap_or(false) + } +} + +#[derive(Unique)] +pub struct ModState { + pub rt: ModdingRuntime, +} + +pub fn init_modrt(storages: AllStoragesView) { + storages.add_unique_non_send_sync(ModState { + rt: ModdingRuntime::init(), + }); +} + +pub fn load_mods( + mut state: NonSendSync>, +) { + log::info!("Loading mods"); + let path = Path::new("./mods"); + if path.exists() { + state.rt.load_mod_dir(path).unwrap(); + log::info!("mods loaded: {:?}", state.rt.mods().len()); + } else { + log::info!("no mod directory found, skipping"); + } +} + +pub fn run_mod_init_stage( + mut state: NonSendSync>, + mut cs: Option>, +) { + log::info!("running mod init stage"); + state.rt.run_init(&RefCell::new(Context { + cs: cs.as_deref_mut(), + })); +} + +pub fn init_modding() -> Workload { + ( + init_modrt, + load_mods, + run_mod_init_stage, + ).into_workload() +} diff --git a/kubi/src/world/chunk.rs b/kubi/src/world/chunk.rs index 27c52a9..d2682f3 100644 --- a/kubi/src/world/chunk.rs +++ b/kubi/src/world/chunk.rs @@ -21,7 +21,8 @@ pub struct ChunkMesh { pub trans: BufferPair, } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +//XXX: ord doesnt make much sense here? +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PartialOrd, Ord)] pub enum CurrentChunkState { #[default] Nothing, @@ -41,6 +42,7 @@ pub enum DesiredChunkState { Rendered, Unloaded, } + impl DesiredChunkState { pub fn matches_current(self, current: CurrentChunkState) -> bool { (matches!(self, DesiredChunkState::Nothing) && matches!(current, CurrentChunkState::Nothing)) ||