upgrade wasmer, implement basic WASI, turn off login events for now

This commit is contained in:
Christof Petig 2023-06-18 17:23:31 +02:00
parent 59e242dfb8
commit 28c3721ecf
23 changed files with 1079 additions and 796 deletions

3
.gitignore vendored
View File

@ -75,3 +75,6 @@ nix/result*
# Bash
.history
# Plugins
/assets/plugins/*

2
.gitlab/scripts/plugin.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
time cargo build --release --example=hello --target=wasm32-wasi

560
Cargo.lock generated
View File

@ -400,7 +400,7 @@ dependencies = [
"cfg-if 1.0.0",
"libc",
"miniz_oxide 0.6.2",
"object 0.30.3",
"object",
"rustc-demangle",
]
@ -767,7 +767,7 @@ version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
dependencies = [
"heck",
"heck 0.4.1",
"proc-macro2 1.0.56",
"quote 1.0.26",
"syn 2.0.15",
@ -950,6 +950,12 @@ name = "conrod_winit"
version = "0.63.0"
source = "git+https://gitlab.com/veloren/conrod.git?branch=copypasta_0.7#59fddc617696e68d28a75c2137a08c2572efb986"
[[package]]
name = "const_fn"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@ -1159,56 +1165,74 @@ dependencies = [
[[package]]
name = "cranelift-bforest"
version = "0.82.3"
version = "0.91.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75"
checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
version = "0.82.3"
version = "0.91.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b"
checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc"
dependencies = [
"arrayvec 0.7.2",
"bumpalo",
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-egraph",
"cranelift-entity",
"cranelift-isle",
"gimli 0.26.2",
"log",
"regalloc",
"regalloc2",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.82.3"
version = "0.91.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24"
checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.82.3"
version = "0.91.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc"
checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7"
[[package]]
name = "cranelift-egraph"
version = "0.91.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73"
dependencies = [
"cranelift-entity",
"fxhash",
"hashbrown 0.12.3",
"indexmap",
"log",
"smallvec",
]
[[package]]
name = "cranelift-entity"
version = "0.82.3"
version = "0.91.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf"
checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c"
[[package]]
name = "cranelift-frontend"
version = "0.82.3"
version = "0.91.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce"
checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6"
dependencies = [
"cranelift-codegen",
"log",
@ -1216,6 +1240,12 @@ dependencies = [
"target-lexicon",
]
[[package]]
name = "cranelift-isle"
version = "0.91.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb"
[[package]]
name = "crc32fast"
version = "1.3.2"
@ -1637,6 +1667,19 @@ dependencies = [
"syn 2.0.15",
]
[[package]]
name = "dashmap"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
dependencies = [
"cfg-if 1.0.0",
"hashbrown 0.12.3",
"lock_api 0.4.9",
"once_cell",
"parking_lot_core 0.9.7",
]
[[package]]
name = "deflate"
version = "1.0.0"
@ -1646,6 +1689,17 @@ dependencies = [
"adler32",
]
[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2 1.0.56",
"quote 1.0.26",
"syn 1.0.109",
]
[[package]]
name = "deunicode"
version = "1.3.3"
@ -1738,7 +1792,7 @@ dependencies = [
"serde_json",
"serde_repr",
"thiserror",
"time",
"time 0.3.20",
"tokio",
"tracing",
"url",
@ -2735,15 +2789,6 @@ dependencies = [
"ahash 0.4.7",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash 0.7.6",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -2786,6 +2831,15 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "heck"
version = "0.4.1"
@ -3009,6 +3063,12 @@ dependencies = [
"winit",
]
[[package]]
name = "id-arena"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]]
name = "ident_case"
version = "1.0.1"
@ -3049,7 +3109,6 @@ dependencies = [
"autocfg",
"hashbrown 0.12.3",
"rayon",
"serde",
]
[[package]]
@ -3469,27 +3528,6 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "loupe"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d"
dependencies = [
"indexmap",
"loupe-derive",
"rustversion",
]
[[package]]
name = "loupe-derive"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952"
dependencies = [
"quote 1.0.26",
"syn 1.0.109",
]
[[package]]
name = "lz-fear"
version = "0.1.1"
@ -4244,18 +4282,6 @@ dependencies = [
"objc",
]
[[package]]
name = "object"
version = "0.28.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
dependencies = [
"crc32fast",
"hashbrown 0.11.2",
"indexmap",
"memchr",
]
[[package]]
name = "object"
version = "0.30.3"
@ -4730,7 +4756,7 @@ version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
dependencies = [
"unicode-xid",
"unicode-xid 0.1.0",
]
[[package]]
@ -4817,6 +4843,17 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "pulldown-cmark"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8"
dependencies = [
"bitflags 1.3.2",
"memchr",
"unicase",
]
[[package]]
name = "quick-xml"
version = "0.28.2"
@ -5063,7 +5100,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b"
dependencies = [
"pem",
"ring",
"time",
"time 0.3.20",
"yasna",
]
@ -5127,7 +5164,7 @@ dependencies = [
"serde",
"siphasher",
"thiserror",
"time",
"time 0.3.20",
"toml 0.7.3",
"url",
"walkdir 2.3.3",
@ -5147,13 +5184,14 @@ dependencies = [
]
[[package]]
name = "regalloc"
version = "0.0.34"
name = "regalloc2"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02"
checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c"
dependencies = [
"fxhash",
"log",
"rustc-hash",
"slice-group-by",
"smallvec",
]
@ -5239,6 +5277,7 @@ checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e"
dependencies = [
"bytecheck",
"hashbrown 0.12.3",
"indexmap",
"ptr_meta",
"rend",
"rkyv_derive",
@ -5708,12 +5747,14 @@ dependencies = [
]
[[package]]
name = "serde_bytes"
version = "0.11.9"
name = "serde-wasm-bindgen"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294"
checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf"
dependencies = [
"js-sys",
"serde",
"wasm-bindgen",
]
[[package]]
@ -5943,6 +5984,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "slice-group-by"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
[[package]]
name = "slotmap"
version = "0.4.3"
@ -6126,6 +6173,15 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "standback"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
dependencies = [
"version_check",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
@ -6238,7 +6294,7 @@ version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
dependencies = [
"heck",
"heck 0.4.1",
"proc-macro2 1.0.56",
"quote 1.0.26",
"rustversion",
@ -6265,7 +6321,7 @@ checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
dependencies = [
"proc-macro2 0.4.30",
"quote 0.6.13",
"unicode-xid",
"unicode-xid 0.1.0",
]
[[package]]
@ -6380,6 +6436,21 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f685624f172cd0bde6f3363412455e81c018f2379fdf5a218e0be003f1bba642"
[[package]]
name = "time"
version = "0.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242"
dependencies = [
"const_fn",
"libc",
"standback",
"stdweb 0.4.20",
"time-macros 0.1.1",
"version_check",
"winapi 0.3.9",
]
[[package]]
name = "time"
version = "0.3.20"
@ -6389,7 +6460,7 @@ dependencies = [
"itoa",
"serde",
"time-core",
"time-macros",
"time-macros 0.2.8",
]
[[package]]
@ -6398,6 +6469,16 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
[[package]]
name = "time-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1"
dependencies = [
"proc-macro-hack",
"time-macros-impl",
]
[[package]]
name = "time-macros"
version = "0.2.8"
@ -6407,6 +6488,19 @@ dependencies = [
"time-core",
]
[[package]]
name = "time-macros-impl"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f"
dependencies = [
"proc-macro-hack",
"proc-macro2 1.0.56",
"quote 1.0.26",
"standback",
"syn 1.0.109",
]
[[package]]
name = "timer-queue"
version = "0.1.0"
@ -6571,7 +6665,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
"cfg-if 1.0.0",
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@ -6584,7 +6677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e"
dependencies = [
"crossbeam-channel",
"time",
"time 0.3.20",
"tracing-subscriber",
]
@ -6633,7 +6726,7 @@ dependencies = [
"sharded-slab",
"smallvec",
"thread_local",
"time",
"time 0.3.20",
"tracing",
"tracing-core",
"tracing-log",
@ -6722,7 +6815,7 @@ version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if 0.1.10",
"cfg-if 1.0.0",
"rand 0.8.5",
"static_assertions",
]
@ -6769,6 +6862,15 @@ dependencies = [
"tinystr",
]
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.13"
@ -6808,6 +6910,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "untrusted"
version = "0.7.1"
@ -7088,6 +7196,7 @@ dependencies = [
"veloren-common-net",
"veloren-plugin-api",
"wasmer",
"wasmer-wasix-types",
]
[[package]]
@ -7488,6 +7597,72 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wai-bindgen-gen-core"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aa3dc41b510811122b3088197234c27e08fcad63ef936306dd8e11e2803876c"
dependencies = [
"anyhow",
"wai-parser",
]
[[package]]
name = "wai-bindgen-gen-rust"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19bc05e8380515c4337c40ef03b2ff233e391315b178a320de8640703d522efe"
dependencies = [
"heck 0.3.3",
"wai-bindgen-gen-core",
]
[[package]]
name = "wai-bindgen-gen-rust-wasm"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6f35ce5e74086fac87f3a7bd50f643f00fe3559adb75c88521ecaa01c8a6199"
dependencies = [
"heck 0.3.3",
"wai-bindgen-gen-core",
"wai-bindgen-gen-rust",
]
[[package]]
name = "wai-bindgen-rust"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e5601c6f448c063e83a5e931b8fefcdf7e01ada424ad42372c948d2e3d67741"
dependencies = [
"bitflags 1.3.2",
"wai-bindgen-rust-impl",
]
[[package]]
name = "wai-bindgen-rust-impl"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdeeb5c1170246de8425a3e123e7ef260dc05ba2b522a1d369fe2315376efea4"
dependencies = [
"proc-macro2 1.0.56",
"syn 1.0.109",
"wai-bindgen-gen-core",
"wai-bindgen-gen-rust-wasm",
]
[[package]]
name = "wai-parser"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bd0acb6d70885ea0c343749019ba74f015f64a9d30542e66db69b49b7e28186"
dependencies = [
"anyhow",
"id-arena",
"pulldown-cmark",
"unicode-normalization",
"unicode-xid 0.2.4",
]
[[package]]
name = "walkdir"
version = "0.1.8"
@ -7555,6 +7730,29 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-downcast"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340"
dependencies = [
"js-sys",
"once_cell",
"wasm-bindgen",
"wasm-bindgen-downcast-macros",
]
[[package]]
name = "wasm-bindgen-downcast-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f"
dependencies = [
"proc-macro2 1.0.56",
"quote 1.0.26",
"syn 1.0.109",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.34"
@ -7607,73 +7805,65 @@ dependencies = [
[[package]]
name = "wasmer"
version = "2.3.0"
version = "4.0.0-beta.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf"
checksum = "d924829e1d14ca3b0ab2562ef7c958fd61ec3fdc6401fd09f20becf59c1f1d17"
dependencies = [
"bytes",
"cfg-if 1.0.0",
"derivative",
"indexmap",
"js-sys",
"loupe",
"more-asserts",
"rustc-demangle",
"serde",
"serde-wasm-bindgen",
"target-lexicon",
"thiserror",
"wasm-bindgen",
"wasmer-artifact",
"wasm-bindgen-downcast",
"wasmer-compiler",
"wasmer-compiler-cranelift",
"wasmer-derive",
"wasmer-engine",
"wasmer-engine-dylib",
"wasmer-engine-universal",
"wasmer-types",
"wasmer-vm",
"wat",
"winapi 0.3.9",
]
[[package]]
name = "wasmer-artifact"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325"
dependencies = [
"enumset",
"loupe",
"thiserror",
"wasmer-compiler",
"wasmer-types",
]
[[package]]
name = "wasmer-compiler"
version = "2.3.0"
version = "4.0.0-beta.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c"
checksum = "945e8cd172c68cf10fefcd40f9c97bd301ecc9bf0136972bf807474f1b5951de"
dependencies = [
"backtrace",
"cfg-if 1.0.0",
"enum-iterator 0.7.0",
"enumset",
"loupe",
"rkyv",
"serde",
"serde_bytes",
"lazy_static",
"leb128",
"memmap2 0.5.10",
"more-asserts",
"region",
"smallvec",
"target-lexicon",
"thiserror",
"wasmer-types",
"wasmer-vm",
"wasmparser",
"winapi 0.3.9",
]
[[package]]
name = "wasmer-compiler-cranelift"
version = "2.3.0"
version = "4.0.0-beta.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0"
checksum = "cdce36e48ec8c70e34d150073d6214e52757474bb375c013f2ae0bac85800cce"
dependencies = [
"cranelift-codegen",
"cranelift-entity",
"cranelift-frontend",
"gimli 0.26.2",
"loupe",
"more-asserts",
"rayon",
"smallvec",
@ -7685,9 +7875,9 @@ dependencies = [
[[package]]
name = "wasmer-derive"
version = "2.3.0"
version = "4.0.0-beta.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51"
checksum = "90277df86705920fefed23c2724ed652fa974af788f0983ca0493b51691a76bd"
dependencies = [
"proc-macro-error",
"proc-macro2 1.0.56",
@ -7695,152 +7885,80 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "wasmer-engine"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45"
dependencies = [
"backtrace",
"enumset",
"lazy_static",
"loupe",
"memmap2 0.5.10",
"more-asserts",
"rustc-demangle",
"serde",
"serde_bytes",
"target-lexicon",
"thiserror",
"wasmer-artifact",
"wasmer-compiler",
"wasmer-types",
"wasmer-vm",
]
[[package]]
name = "wasmer-engine-dylib"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53"
dependencies = [
"cfg-if 1.0.0",
"enum-iterator 0.7.0",
"enumset",
"leb128",
"libloading 0.7.4",
"loupe",
"object 0.28.4",
"rkyv",
"serde",
"tempfile",
"tracing",
"wasmer-artifact",
"wasmer-compiler",
"wasmer-engine",
"wasmer-object",
"wasmer-types",
"wasmer-vm",
"which",
]
[[package]]
name = "wasmer-engine-universal"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15"
dependencies = [
"cfg-if 1.0.0",
"enumset",
"leb128",
"loupe",
"region",
"rkyv",
"wasmer-compiler",
"wasmer-engine",
"wasmer-engine-universal-artifact",
"wasmer-types",
"wasmer-vm",
"winapi 0.3.9",
]
[[package]]
name = "wasmer-engine-universal-artifact"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41"
dependencies = [
"enum-iterator 0.7.0",
"enumset",
"loupe",
"rkyv",
"thiserror",
"wasmer-artifact",
"wasmer-compiler",
"wasmer-types",
]
[[package]]
name = "wasmer-object"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b"
dependencies = [
"object 0.28.4",
"thiserror",
"wasmer-compiler",
"wasmer-types",
]
[[package]]
name = "wasmer-types"
version = "2.3.0"
version = "4.0.0-beta.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f"
checksum = "918344b93266cf4efe56e6cd23f35c7325275524f534678145f7ead4b2b8c762"
dependencies = [
"backtrace",
"bytecheck",
"enum-iterator 0.7.0",
"enumset",
"indexmap",
"loupe",
"more-asserts",
"rkyv",
"serde",
"target-lexicon",
"thiserror",
]
[[package]]
name = "wasmer-vm"
version = "2.3.0"
version = "4.0.0-beta.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd"
checksum = "4e36cba570e0b2662ff52d40fe9a48fd368f6eb35183a84ce43f79bc51b9fd15"
dependencies = [
"backtrace",
"cc",
"cfg-if 1.0.0",
"corosensei",
"dashmap",
"derivative",
"enum-iterator 0.7.0",
"fnv",
"indexmap",
"lazy_static",
"libc",
"loupe",
"mach",
"memoffset 0.6.5",
"memoffset 0.8.0",
"more-asserts",
"region",
"rkyv",
"scopeguard",
"serde",
"thiserror",
"wasmer-artifact",
"wasmer-types",
"winapi 0.3.9",
]
[[package]]
name = "wasmparser"
version = "0.83.0"
name = "wasmer-wasix-types"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a"
checksum = "13597c9c4febf4a6b0f36a8c76d17f90a6be7f65bc4667472a50a93121a6f2c5"
dependencies = [
"anyhow",
"bitflags 1.3.2",
"byteorder",
"cfg-if 1.0.0",
"num_enum",
"time 0.2.27",
"wai-bindgen-gen-core",
"wai-bindgen-gen-rust",
"wai-bindgen-gen-rust-wasm",
"wai-bindgen-rust",
"wai-parser",
"wasmer",
"wasmer-derive",
"wasmer-types",
]
[[package]]
name = "wasmparser"
version = "0.95.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a"
dependencies = [
"indexmap",
"url",
]
[[package]]
name = "wast"
@ -8652,5 +8770,5 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
dependencies = [
"time",
"time 0.3.20",
]

View File

@ -38,7 +38,6 @@ sha2 = "0.10"
# Strum
strum = { workspace = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
approx = "0.4.0"
crossbeam-utils = { workspace = true }
crossbeam-channel = { workspace = true }

View File

@ -1,8 +1,7 @@
use crate::comp::buff::{Buff, BuffChange, BuffData, BuffKind, BuffSource};
#[cfg(not(target_arch = "wasm32"))]
use crate::{
comp::{
ability::Capability,
buff::{Buff, BuffChange, BuffData, BuffKind, BuffSource},
inventory::{
item::{
armor::Protection,
@ -12,29 +11,22 @@ use crate::{
slot::EquipSlot,
},
skillset::SkillGroupKind,
Alignment, Body, Buffs, CharacterState, Combo, Energy, Health, HealthChange, Inventory,
Ori, Player, Poise, PoiseChange, SkillSet, Stats,
Alignment, Body, Buffs, CharacterState, Combo, Energy, Group, Health, HealthChange,
Inventory, Ori, Player, Poise, PoiseChange, SkillSet, Stats,
},
event::ServerEvent,
outcome::Outcome,
resources::Secs,
resources::{Secs, Time},
states::utils::StageSection,
uid::{IdMaps, Uid},
util::Dir,
};
use rand::Rng;
use serde::{Deserialize, Serialize};
use specs::{Entity as EcsEntity, ReadStorage};
use std::ops::{Mul, MulAssign};
use vek::*;
use crate::{comp::Group, resources::Time};
#[cfg(not(target_arch = "wasm32"))]
use {
rand::Rng,
specs::{Entity as EcsEntity, ReadStorage},
std::ops::{Mul, MulAssign},
vek::*,
};
#[cfg(not(target_arch = "wasm32"))]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum GroupTarget {
InGroup,
@ -51,7 +43,6 @@ pub enum AttackSource {
Explosion,
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Copy, Clone)]
pub struct AttackerInfo<'a> {
pub entity: EcsEntity,
@ -63,7 +54,6 @@ pub struct AttackerInfo<'a> {
pub stats: Option<&'a Stats>,
}
#[cfg(not(target_arch = "wasm32"))]
pub struct TargetInfo<'a> {
pub entity: EcsEntity,
pub uid: Uid,
@ -84,7 +74,6 @@ pub struct AttackOptions {
pub target_group: GroupTarget,
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Debug, Serialize, Deserialize)] // TODO: Yeet clone derive
pub struct Attack {
damages: Vec<AttackDamage>,
@ -93,7 +82,6 @@ pub struct Attack {
crit_multiplier: f32,
}
#[cfg(not(target_arch = "wasm32"))]
impl Default for Attack {
fn default() -> Self {
Self {
@ -105,7 +93,6 @@ impl Default for Attack {
}
}
#[cfg(not(target_arch = "wasm32"))]
impl Attack {
#[must_use]
pub fn with_damage(mut self, damage: AttackDamage) -> Self {
@ -752,7 +739,6 @@ pub fn may_harm(
.map_or(true, |(a, t)| a.may_harm(t))
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AttackDamage {
damage: Damage,
@ -762,7 +748,6 @@ pub struct AttackDamage {
instance: u64,
}
#[cfg(not(target_arch = "wasm32"))]
impl AttackDamage {
pub fn new(damage: Damage, target: Option<GroupTarget>, instance: u64) -> Self {
Self {
@ -780,7 +765,6 @@ impl AttackDamage {
}
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AttackEffect {
target: Option<GroupTarget>,
@ -788,7 +772,6 @@ pub struct AttackEffect {
requirements: Vec<CombatRequirement>,
}
#[cfg(not(target_arch = "wasm32"))]
impl AttackEffect {
pub fn new(target: Option<GroupTarget>, effect: CombatEffect) -> Self {
Self {
@ -807,7 +790,6 @@ impl AttackEffect {
pub fn effect(&self) -> &CombatEffect { &self.effect }
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
pub enum CombatEffect {
Heal(f32),
@ -882,7 +864,6 @@ impl CombatEffect {
}
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum CombatRequirement {
AnyDamage,
@ -968,7 +949,6 @@ const PIERCING_PENETRATION_FRACTION: f32 = 1.5;
const SLASHING_ENERGY_FRACTION: f32 = 0.5;
const CRUSHING_POISE_FRACTION: f32 = 1.0;
#[cfg(not(target_arch = "wasm32"))]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Damage {
pub source: DamageSource,
@ -976,7 +956,6 @@ pub struct Damage {
pub value: f32,
}
#[cfg(not(target_arch = "wasm32"))]
impl Damage {
/// Returns the total damage reduction provided by all equipped items
pub fn compute_damage_reduction(
@ -1081,14 +1060,12 @@ impl Damage {
}
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Knockback {
pub direction: KnockbackDir,
pub strength: f32,
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum KnockbackDir {
Away,
@ -1097,7 +1074,6 @@ pub enum KnockbackDir {
TowardsUp,
}
#[cfg(not(target_arch = "wasm32"))]
impl Knockback {
pub fn calculate_impulse(self, dir: Dir, char_state: Option<&CharacterState>) -> Vec3<f32> {
let from_char = {
@ -1128,7 +1104,6 @@ impl Knockback {
}
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
pub struct CombatBuff {
pub kind: BuffKind,
@ -1137,14 +1112,12 @@ pub struct CombatBuff {
pub chance: f32,
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
pub enum CombatBuffStrength {
DamageFraction(f32),
Value(f32),
}
#[cfg(not(target_arch = "wasm32"))]
impl CombatBuffStrength {
fn to_strength(self, damage: f32, strength_modifier: f32) -> f32 {
match self {
@ -1170,7 +1143,6 @@ impl Mul<f32> for CombatBuffStrength {
}
}
#[cfg(not(target_arch = "wasm32"))]
impl CombatBuff {
fn to_buff(
self,
@ -1203,7 +1175,6 @@ impl CombatBuff {
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn get_weapon_kinds(inv: &Inventory) -> (Option<ToolKind>, Option<ToolKind>) {
(
inv.equipped(EquipSlot::ActiveMainhand).and_then(|i| {
@ -1223,7 +1194,6 @@ pub fn get_weapon_kinds(inv: &Inventory) -> (Option<ToolKind>, Option<ToolKind>)
)
}
#[cfg(not(target_arch = "wasm32"))]
// TODO: Either remove msm or use it as argument in fn kind
fn weapon_rating<T: ItemDesc>(item: &T, _msm: &MaterialStatManifest) -> f32 {
const POWER_WEIGHT: f32 = 2.0;
@ -1265,7 +1235,6 @@ fn weapon_rating<T: ItemDesc>(item: &T, _msm: &MaterialStatManifest) -> f32 {
rating.max(0.0)
}
#[cfg(not(target_arch = "wasm32"))]
fn weapon_skills(inventory: &Inventory, skill_set: &SkillSet) -> f32 {
let (mainhand, offhand) = get_weapon_kinds(inventory);
let mainhand_skills = if let Some(tool) = mainhand {
@ -1281,7 +1250,6 @@ fn weapon_skills(inventory: &Inventory, skill_set: &SkillSet) -> f32 {
mainhand_skills.max(offhand_skills)
}
#[cfg(not(target_arch = "wasm32"))]
fn get_weapon_rating(inventory: &Inventory, msm: &MaterialStatManifest) -> f32 {
let mainhand_rating = if let Some(item) = inventory.equipped(EquipSlot::ActiveMainhand) {
weapon_rating(item, msm)
@ -1298,7 +1266,6 @@ fn get_weapon_rating(inventory: &Inventory, msm: &MaterialStatManifest) -> f32 {
mainhand_rating.max(offhand_rating)
}
#[cfg(not(target_arch = "wasm32"))]
pub fn combat_rating(
inventory: &Inventory,
health: &Health,
@ -1359,7 +1326,6 @@ pub fn combat_rating(
combined_rating * body.combat_multiplier()
}
#[cfg(not(target_arch = "wasm32"))]
pub fn compute_crit_mult(inventory: Option<&Inventory>, msm: &MaterialStatManifest) -> f32 {
// Starts with a value of 1.25 when summing the stats from each armor piece, and
// defaults to a value of 1.25 if no inventory is equipped
@ -1379,7 +1345,6 @@ pub fn compute_crit_mult(inventory: Option<&Inventory>, msm: &MaterialStatManife
}
/// Computes the energy reward modifier from worn armor
#[cfg(not(target_arch = "wasm32"))]
pub fn compute_energy_reward_mod(inventory: Option<&Inventory>, msm: &MaterialStatManifest) -> f32 {
// Starts with a value of 1.0 when summing the stats from each armor piece, and
// defaults to a value of 1.0 if no inventory is present
@ -1400,7 +1365,6 @@ pub fn compute_energy_reward_mod(inventory: Option<&Inventory>, msm: &MaterialSt
/// Computes the additive modifier that should be applied to max energy from the
/// currently equipped items
#[cfg(not(target_arch = "wasm32"))]
pub fn compute_max_energy_mod(inventory: Option<&Inventory>, msm: &MaterialStatManifest) -> f32 {
// Defaults to a value of 0 if no inventory is present
inventory.map_or(0.0, |inv| {
@ -1420,7 +1384,6 @@ pub fn compute_max_energy_mod(inventory: Option<&Inventory>, msm: &MaterialStatM
/// Returns a value to be included as a multiplicative factor in perception
/// distance checks.
#[cfg(not(target_arch = "wasm32"))]
pub fn perception_dist_multiplier_from_stealth(
inventory: Option<&Inventory>,
character_state: Option<&CharacterState>,
@ -1436,7 +1399,6 @@ pub fn perception_dist_multiplier_from_stealth(
multiplier.clamp(0.0, 1.0)
}
#[cfg(not(target_arch = "wasm32"))]
pub fn stealth_multiplier_from_items(
inventory: Option<&Inventory>,
msm: &MaterialStatManifest,
@ -1459,7 +1421,6 @@ pub fn stealth_multiplier_from_items(
/// Computes the total protection provided from armor. Is used to determine the
/// damage reduction applied to damage received by an entity None indicates that
/// the armor equipped makes the entity invulnerable
#[cfg(not(target_arch = "wasm32"))]
pub fn compute_protection(
inventory: Option<&Inventory>,
msm: &MaterialStatManifest,

View File

@ -7,11 +7,9 @@ use crate::{
};
use core::cmp::Ordering;
#[cfg(not(target_arch = "wasm32"))]
use hashbrown::HashMap;
use itertools::Either;
use serde::{Deserialize, Serialize};
#[cfg(not(target_arch = "wasm32"))]
use specs::{Component, DerefFlaggedStorage, VecStorage};
use strum::EnumIter;
@ -121,7 +119,6 @@ pub enum BuffKind {
Lifesteal,
}
#[cfg(not(target_arch = "wasm32"))]
impl BuffKind {
/// Checks if buff is buff or debuff.
pub fn is_buff(self) -> bool {
@ -330,7 +327,6 @@ pub struct BuffData {
pub delay: Option<Secs>,
}
#[cfg(not(target_arch = "wasm32"))]
impl BuffData {
pub fn new(strength: f32, duration: Option<Secs>, delay: Option<Secs>) -> Self {
Self {
@ -456,7 +452,6 @@ pub enum BuffChange {
Refresh(BuffKind),
}
#[cfg(not(target_arch = "wasm32"))]
impl Buff {
/// Builder function for buffs
pub fn new(
@ -493,7 +488,6 @@ impl Buff {
pub fn elapsed(&self, time: Time) -> Secs { Secs(time.0 - self.start_time.0) }
}
#[cfg(not(target_arch = "wasm32"))]
impl PartialOrd for Buff {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self == other {
@ -516,12 +510,10 @@ impl PartialOrd for Buff {
}
}
#[cfg(not(target_arch = "wasm32"))]
fn compare_end_time(a: Option<Time>, b: Option<Time>) -> bool {
a.map_or(true, |time_a| b.map_or(false, |time_b| time_a.0 > time_b.0))
}
#[cfg(not(target_arch = "wasm32"))]
impl PartialEq for Buff {
fn eq(&self, other: &Self) -> bool {
self.data.strength == other.data.strength
@ -558,7 +550,6 @@ pub enum BuffSource {
/// and undone on removal of the buff (by the specs system).
/// Example could be decreasing max health, which, if repeated each tick,
/// would be probably an undesired effect).
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
pub struct Buffs {
/// Uid used for synchronization
@ -571,7 +562,6 @@ pub struct Buffs {
pub buffs: HashMap<BuffId, Buff>,
}
#[cfg(not(target_arch = "wasm32"))]
impl Buffs {
fn sort_kind(&mut self, kind: BuffKind) {
if let Some(buff_order) = self.kinds.get_mut(&kind) {
@ -686,7 +676,6 @@ impl Buffs {
pub type BuffId = u64;
#[cfg(not(target_arch = "wasm32"))]
impl Component for Buffs {
type Storage = DerefFlaggedStorage<Self, VecStorage<Self>>;
}

View File

@ -1,6 +1,7 @@
#[cfg(not(target_arch = "wasm32"))]
use super::body::{object, Body};
use super::{Density, Ori, Vel};
use super::{
body::{object, Body},
Density, Ori, Vel,
};
use crate::{
consts::{AIR_DENSITY, LAVA_DENSITY, WATER_DENSITY},
util::{Dir, Plane, Projection},
@ -128,7 +129,6 @@ pub struct Wings {
pub ori: Ori,
}
#[cfg(not(target_arch = "wasm32"))]
impl Body {
pub fn aerodynamic_forces(
&self,

View File

@ -1,14 +1,10 @@
#[cfg(not(target_arch = "wasm32"))]
use crate::{comp, consts::HP_PER_LEVEL};
use crate::{uid::Uid, DamageSource};
use crate::{
combat::DamageContributor, comp, consts::HP_PER_LEVEL, resources::Time, uid::Uid, DamageSource,
};
use hashbrown::HashMap;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use crate::{combat::DamageContributor, resources::Time};
#[cfg(not(target_arch = "wasm32"))]
use specs::{Component, DerefFlaggedStorage};
use std::ops::Mul;
use std::{convert::TryFrom, ops::Mul};
/// Specifies what and how much changed current health
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
@ -120,7 +116,6 @@ impl Health {
self.current = self.current.min(self.maximum);
}
#[cfg(not(target_arch = "wasm32"))]
pub fn new(body: comp::Body, level: u16) -> Self {
let health = u32::from(
body.base_health()
@ -144,7 +139,6 @@ impl Health {
}
// TODO: Delete this once stat points will be a thing
#[cfg(not(target_arch = "wasm32"))]
pub fn update_max_hp(&mut self, body: comp::Body, level: u16) {
let old_max = self.base_max;
self.base_max = u32::from(
@ -154,7 +148,6 @@ impl Health {
self.current = (self.current + self.base_max - old_max).min(self.maximum);
}
#[cfg(not(target_arch = "wasm32"))]
/// Returns a boolean if the delta was not zero.
pub fn change_by(&mut self, change: HealthChange) -> bool {
let prev_health = i64::from(self.current);
@ -203,7 +196,6 @@ impl Health {
pub fn kill(&mut self) { self.current = 0; }
#[cfg(not(target_arch = "wasm32"))]
pub fn revive(&mut self) {
self.current = self.maximum;
self.is_dead = false;
@ -229,7 +221,6 @@ impl Health {
}
}
#[cfg(not(target_arch = "wasm32"))]
impl Component for Health {
type Storage = DerefFlaggedStorage<Self, specs::VecStorage<Self>>;
}

View File

@ -1,56 +1,42 @@
#[cfg(not(target_arch = "wasm32"))]
pub mod ability;
#[cfg(not(target_arch = "wasm32"))] mod admin;
#[cfg(not(target_arch = "wasm32"))] pub mod agent;
#[cfg(not(target_arch = "wasm32"))]
mod admin;
pub mod agent;
pub mod anchor;
#[cfg(not(target_arch = "wasm32"))] pub mod aura;
#[cfg(not(target_arch = "wasm32"))] pub mod beam;
#[cfg(not(target_arch = "wasm32"))] pub mod body;
pub mod aura;
pub mod beam;
pub mod body;
pub mod buff;
#[cfg(not(target_arch = "wasm32"))]
pub mod character_state;
#[cfg(not(target_arch = "wasm32"))] pub mod chat;
#[cfg(not(target_arch = "wasm32"))] pub mod combo;
pub mod chat;
pub mod combo;
pub mod compass;
#[cfg(not(target_arch = "wasm32"))]
pub mod controller;
#[cfg(not(target_arch = "wasm32"))]
pub mod dialogue;
#[cfg(not(target_arch = "wasm32"))] mod energy;
#[cfg(not(target_arch = "wasm32"))]
mod energy;
pub mod fluid_dynamics;
#[cfg(not(target_arch = "wasm32"))] pub mod group;
pub mod group;
mod health;
#[cfg(not(target_arch = "wasm32"))] mod inputs;
#[cfg(not(target_arch = "wasm32"))]
mod inputs;
pub mod inventory;
#[cfg(not(target_arch = "wasm32"))]
pub mod invite;
#[cfg(not(target_arch = "wasm32"))] mod last;
#[cfg(not(target_arch = "wasm32"))] mod location;
mod last;
mod location;
pub mod loot_owner;
#[cfg(not(target_arch = "wasm32"))] pub mod melee;
#[cfg(not(target_arch = "wasm32"))] mod misc;
#[cfg(not(target_arch = "wasm32"))] pub mod ori;
#[cfg(not(target_arch = "wasm32"))] pub mod pet;
#[cfg(not(target_arch = "wasm32"))] mod phys;
#[cfg(not(target_arch = "wasm32"))] mod player;
#[cfg(not(target_arch = "wasm32"))] pub mod poise;
#[cfg(not(target_arch = "wasm32"))]
pub mod melee;
mod misc;
pub mod ori;
pub mod pet;
mod phys;
mod player;
pub mod poise;
pub mod presence;
#[cfg(not(target_arch = "wasm32"))]
pub mod projectile;
#[cfg(not(target_arch = "wasm32"))]
pub mod shockwave;
#[cfg(not(target_arch = "wasm32"))]
pub mod skillset;
#[cfg(not(target_arch = "wasm32"))] mod stats;
#[cfg(not(target_arch = "wasm32"))]
mod stats;
pub mod visual;
// Reexports
#[cfg(not(target_arch = "wasm32"))]
pub use self::{
ability::{
Ability, AbilityInput, ActiveAbilities, CharacterAbility, CharacterAbilityType, Stance,
@ -107,8 +93,7 @@ pub use self::{
Collider, Density, ForceUpdate, Immovable, Mass, PhysicsState, Pos, PosVelOriDefer,
PreviousPhysCache, Scale, Sticky, Vel,
},
player::DisconnectReason,
player::{AliasError, Player, MAX_ALIAS_LEN},
player::{AliasError, DisconnectReason, Player, MAX_ALIAS_LEN},
poise::{Poise, PoiseChange, PoiseState},
presence::{Presence, PresenceKind},
projectile::{Projectile, ProjectileConstructor},

View File

@ -16,15 +16,8 @@
)]
#![feature(hash_drain_filter)]
// Rustfmt can't expand macros to see module declarations inside them but it is
// hardcoded to parse `cfg_if`. https://github.com/rust-lang/rustfmt/issues/3253
use cfg_if::cfg_if;
// Re-exported crates
cfg_if! { if #[cfg(not(target_arch = "wasm32"))] {
pub use common_assets as assets;
pub use uuid;
} }
pub use common_assets as assets;
pub use uuid;
// Modules
@ -35,59 +28,54 @@ pub mod resources;
pub mod shared_server_config;
pub mod uid;
// NOTE: Comment out macro to get rustfmt to re-order these as needed.
cfg_if! { if #[cfg(not(target_arch = "wasm32"))] {
pub mod astar;
pub mod calendar;
pub mod character;
pub mod clock;
pub mod cmd;
pub mod depot;
pub mod effect;
pub mod event;
pub mod explosion;
pub mod figure;
pub mod generation;
pub mod grid;
pub mod link;
pub mod lod;
pub mod lottery;
pub mod mounting;
pub mod npc;
pub mod outcome;
pub mod path;
pub mod ray;
pub mod recipe;
pub mod region;
pub mod rtsim;
pub mod skillset_builder;
pub mod slowjob;
pub mod spiral;
pub mod states;
pub mod store;
pub mod terrain;
pub mod time;
pub mod trade;
pub mod util;
pub mod vol;
pub mod volumes;
pub mod weather;
pub mod astar;
pub mod calendar;
pub mod character;
pub mod clock;
pub mod cmd;
pub mod depot;
pub mod effect;
pub mod event;
pub mod explosion;
pub mod figure;
pub mod generation;
pub mod grid;
pub mod link;
pub mod lod;
pub mod lottery;
pub mod mounting;
pub mod npc;
pub mod outcome;
pub mod path;
pub mod ray;
pub mod recipe;
pub mod region;
pub mod rtsim;
pub mod skillset_builder;
pub mod slowjob;
pub mod spiral;
pub mod states;
pub mod store;
pub mod terrain;
pub mod time;
pub mod trade;
pub mod util;
pub mod vol;
pub mod volumes;
pub mod weather;
mod cached_spatial_grid;
mod view_distances;
} }
mod cached_spatial_grid;
mod view_distances;
// We declare a macro in this module so there are issues referring to it by path
// within this crate if typed module is declared in macro expansion.
#[cfg(not(target_arch = "wasm32"))] pub mod typed;
pub mod typed;
pub use combat::{DamageKind, DamageSource};
cfg_if! { if #[cfg(not(target_arch = "wasm32"))] {
pub use cached_spatial_grid::CachedSpatialGrid;
pub use combat::{Damage, GroupTarget, Knockback, KnockbackDir};
pub use comp::inventory::loadout_builder::LoadoutBuilder;
pub use explosion::{Explosion, RadiusEffect};
pub use skillset_builder::SkillSetBuilder;
pub use view_distances::ViewDistances;
} }
pub use cached_spatial_grid::CachedSpatialGrid;
pub use combat::{Damage, GroupTarget, Knockback, KnockbackDir};
pub use comp::inventory::loadout_builder::LoadoutBuilder;
pub use explosion::{Explosion, RadiusEffect};
pub use skillset_builder::SkillSetBuilder;
pub use view_distances::ViewDistances;

View File

@ -1,7 +1,5 @@
#[cfg(not(target_arch = "wasm32"))]
use crate::comp::Pos;
use serde::{Deserialize, Serialize};
#[cfg(not(target_arch = "wasm32"))]
use specs::Entity;
use std::ops::{Mul, MulAssign};
@ -38,7 +36,6 @@ impl MulAssign<f64> for Secs {
fn mul_assign(&mut self, mult: f64) { *self = *self * mult; }
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Default)]
pub struct EntitiesDiedLastTick(pub Vec<(Entity, Pos)>);
@ -59,7 +56,6 @@ pub enum GameMode {
/// A resource that stores the player's entity (on the client), and None on the
/// server
#[cfg(not(target_arch = "wasm32"))]
#[derive(Copy, Clone, Default, Debug)]
pub struct PlayerEntity(pub Option<Entity>);
@ -82,7 +78,6 @@ impl PlayerPhysicsSetting {
/// List of which players are using client-authoratative vs server-authoratative
/// physics, as a stop-gap until we can use server-authoratative physics for
/// everyone
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Default, Debug)]
pub struct PlayerPhysicsSettings {
pub settings: hashbrown::HashMap<uuid::Uuid, PlayerPhysicsSetting>,

View File

@ -1,15 +1,10 @@
use crate::{character::CharacterId, rtsim::RtSimEntity};
use core::hash::Hash;
use hashbrown::HashMap;
use serde::{Deserialize, Serialize};
use specs::{Component, Entity, FlaggedStorage, VecStorage};
use std::{fmt, u64};
#[cfg(not(target_arch = "wasm32"))]
use {
crate::character::CharacterId,
crate::rtsim::RtSimEntity,
core::hash::Hash,
hashbrown::HashMap,
specs::{Component, Entity, FlaggedStorage, VecStorage},
tracing::error,
};
use tracing::error;
// TODO: could we switch this to `NonZeroU64`?
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
@ -27,171 +22,165 @@ impl fmt::Display for Uid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
}
pub use not_wasm::*;
#[cfg(not(target_arch = "wasm32"))]
mod not_wasm {
use super::*;
impl Component for Uid {
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
}
impl Component for Uid {
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
}
#[derive(Debug)]
struct UidAllocator {
/// Next Uid.
next_uid: u64,
}
#[derive(Debug)]
struct UidAllocator {
/// Next Uid.
next_uid: u64,
}
impl UidAllocator {
fn new() -> Self { Self { next_uid: 0 } }
impl UidAllocator {
fn new() -> Self { Self { next_uid: 0 } }
fn allocate(&mut self) -> Uid {
let id = self.next_uid;
self.next_uid += 1;
Uid(id)
}
}
/// Mappings from various Id types to `Entity`s.
#[derive(Default, Debug)]
pub struct IdMaps {
/// "Universal" IDs (used to communicate entity identity over the
/// network).
uid_mapping: HashMap<Uid, Entity>,
// -- Fields below are only used on the server --
uid_allocator: UidAllocator,
/// Character IDs.
character_to_ecs: HashMap<CharacterId, Entity>,
/// Rtsim Entities.
rtsim_to_ecs: HashMap<RtSimEntity, Entity>,
}
impl IdMaps {
pub fn new() -> Self { Default::default() }
/// Given a `Uid` retrieve the corresponding `Entity`.
pub fn uid_entity(&self, id: Uid) -> Option<Entity> { self.uid_mapping.get(&id).copied() }
/// Given a `CharacterId` retrieve the corresponding `Entity`.
pub fn character_entity(&self, id: CharacterId) -> Option<Entity> {
self.character_to_ecs.get(&id).copied()
}
/// Given a `RtSimEntity` retrieve the corresponding `Entity`.
pub fn rtsim_entity(&self, id: RtSimEntity) -> Option<Entity> {
self.rtsim_to_ecs.get(&id).copied()
}
/// Removes mappings for the provided Id(s).
///
/// Returns the `Entity` that the provided `Uid` was mapped to.
///
/// Used on both the client and the server when deleting entities,
/// although the client only ever provides a Some value for the
/// `Uid` parameter since the other mappings are not used on the
/// client.
pub fn remove_entity(
&mut self,
expected_entity: Option<Entity>,
uid: Option<Uid>,
cid: Option<CharacterId>,
rid: Option<RtSimEntity>,
) -> Option<Entity> {
#[cold]
#[inline(never)]
fn unexpected_entity<ID>() {
let kind = core::any::type_name::<ID>();
error!("Provided {kind} was mapped to an unexpected entity!");
}
#[cold]
#[inline(never)]
fn not_present<ID>() {
let kind = core::any::type_name::<ID>();
error!("Provided {kind} was not mapped to any entity!");
}
fn remove<ID: Hash + Eq>(
mapping: &mut HashMap<ID, Entity>,
id: Option<ID>,
expected: Option<Entity>,
) -> Option<Entity> {
if let Some(id) = id {
if let Some(e) = mapping.remove(&id) {
if expected.map_or(false, |expected| e != expected) {
unexpected_entity::<ID>();
}
Some(e)
} else {
not_present::<ID>();
None
}
} else {
None
}
}
let maybe_entity = remove(&mut self.uid_mapping, uid, expected_entity);
let expected_entity = expected_entity.or(maybe_entity);
remove(&mut self.character_to_ecs, cid, expected_entity);
remove(&mut self.rtsim_to_ecs, rid, expected_entity);
maybe_entity
}
/// Only used on the client (server solely uses `Self::allocate` to
/// allocate and add Uid mappings and `Self::remap` to move the `Uid` to
/// a different entity).
pub fn add_entity(&mut self, uid: Uid, entity: Entity) {
Self::insert(&mut self.uid_mapping, uid, entity);
}
/// Only used on the server.
pub fn add_character(&mut self, cid: CharacterId, entity: Entity) {
Self::insert(&mut self.character_to_ecs, cid, entity);
}
/// Only used on the server.
pub fn add_rtsim(&mut self, rid: RtSimEntity, entity: Entity) {
Self::insert(&mut self.rtsim_to_ecs, rid, entity);
}
/// Allocates a new `Uid` and links it to the provided entity.
///
/// Only used on the server.
pub fn allocate(&mut self, entity: Entity) -> Uid {
let uid = self.uid_allocator.allocate();
self.uid_mapping.insert(uid, entity);
uid
}
/// Links an existing `Uid` to a new entity.
///
/// Only used on the server.
///
/// Used for `handle_exit_ingame` which moves the same `Uid` to a new
/// entity.
pub fn remap_entity(&mut self, uid: Uid, new_entity: Entity) {
if self.uid_mapping.insert(uid, new_entity).is_none() {
error!("Uid {uid:?} remaped but there was no existing entry for it!");
}
}
#[cold]
#[inline(never)]
fn already_present<ID>() {
let kind = core::any::type_name::<ID>();
error!("Provided {kind} was already mapped to an entity!!!");
}
fn insert<ID: Hash + Eq>(mapping: &mut HashMap<ID, Entity>, new_id: ID, entity: Entity) {
if let Some(_previous_entity) = mapping.insert(new_id, entity) {
Self::already_present::<ID>();
}
}
}
impl Default for UidAllocator {
fn default() -> Self { Self::new() }
fn allocate(&mut self) -> Uid {
let id = self.next_uid;
self.next_uid += 1;
Uid(id)
}
}
/// Mappings from various Id types to `Entity`s.
#[derive(Default, Debug)]
pub struct IdMaps {
/// "Universal" IDs (used to communicate entity identity over the
/// network).
uid_mapping: HashMap<Uid, Entity>,
// -- Fields below are only used on the server --
uid_allocator: UidAllocator,
/// Character IDs.
character_to_ecs: HashMap<CharacterId, Entity>,
/// Rtsim Entities.
rtsim_to_ecs: HashMap<RtSimEntity, Entity>,
}
impl IdMaps {
pub fn new() -> Self { Default::default() }
/// Given a `Uid` retrieve the corresponding `Entity`.
pub fn uid_entity(&self, id: Uid) -> Option<Entity> { self.uid_mapping.get(&id).copied() }
/// Given a `CharacterId` retrieve the corresponding `Entity`.
pub fn character_entity(&self, id: CharacterId) -> Option<Entity> {
self.character_to_ecs.get(&id).copied()
}
/// Given a `RtSimEntity` retrieve the corresponding `Entity`.
pub fn rtsim_entity(&self, id: RtSimEntity) -> Option<Entity> {
self.rtsim_to_ecs.get(&id).copied()
}
/// Removes mappings for the provided Id(s).
///
/// Returns the `Entity` that the provided `Uid` was mapped to.
///
/// Used on both the client and the server when deleting entities,
/// although the client only ever provides a Some value for the
/// `Uid` parameter since the other mappings are not used on the
/// client.
pub fn remove_entity(
&mut self,
expected_entity: Option<Entity>,
uid: Option<Uid>,
cid: Option<CharacterId>,
rid: Option<RtSimEntity>,
) -> Option<Entity> {
#[cold]
#[inline(never)]
fn unexpected_entity<ID>() {
let kind = core::any::type_name::<ID>();
error!("Provided {kind} was mapped to an unexpected entity!");
}
#[cold]
#[inline(never)]
fn not_present<ID>() {
let kind = core::any::type_name::<ID>();
error!("Provided {kind} was not mapped to any entity!");
}
fn remove<ID: Hash + Eq>(
mapping: &mut HashMap<ID, Entity>,
id: Option<ID>,
expected: Option<Entity>,
) -> Option<Entity> {
if let Some(id) = id {
if let Some(e) = mapping.remove(&id) {
if expected.map_or(false, |expected| e != expected) {
unexpected_entity::<ID>();
}
Some(e)
} else {
not_present::<ID>();
None
}
} else {
None
}
}
let maybe_entity = remove(&mut self.uid_mapping, uid, expected_entity);
let expected_entity = expected_entity.or(maybe_entity);
remove(&mut self.character_to_ecs, cid, expected_entity);
remove(&mut self.rtsim_to_ecs, rid, expected_entity);
maybe_entity
}
/// Only used on the client (server solely uses `Self::allocate` to
/// allocate and add Uid mappings and `Self::remap` to move the `Uid` to
/// a different entity).
pub fn add_entity(&mut self, uid: Uid, entity: Entity) {
Self::insert(&mut self.uid_mapping, uid, entity);
}
/// Only used on the server.
pub fn add_character(&mut self, cid: CharacterId, entity: Entity) {
Self::insert(&mut self.character_to_ecs, cid, entity);
}
/// Only used on the server.
pub fn add_rtsim(&mut self, rid: RtSimEntity, entity: Entity) {
Self::insert(&mut self.rtsim_to_ecs, rid, entity);
}
/// Allocates a new `Uid` and links it to the provided entity.
///
/// Only used on the server.
pub fn allocate(&mut self, entity: Entity) -> Uid {
let uid = self.uid_allocator.allocate();
self.uid_mapping.insert(uid, entity);
uid
}
/// Links an existing `Uid` to a new entity.
///
/// Only used on the server.
///
/// Used for `handle_exit_ingame` which moves the same `Uid` to a new
/// entity.
pub fn remap_entity(&mut self, uid: Uid, new_entity: Entity) {
if self.uid_mapping.insert(uid, new_entity).is_none() {
error!("Uid {uid:?} remaped but there was no existing entry for it!");
}
}
#[cold]
#[inline(never)]
fn already_present<ID>() {
let kind = core::any::type_name::<ID>();
error!("Provided {kind} was already mapped to an entity!!!");
}
fn insert<ID: Hash + Eq>(mapping: &mut HashMap<ID, Entity>, new_id: ID, entity: Entity) {
if let Some(_previous_entity) = mapping.insert(new_id, entity) {
Self::already_present::<ID>();
}
}
}
impl Default for UidAllocator {
fn default() -> Self { Self::new() }
}

View File

@ -32,10 +32,11 @@ scopeguard = "1.1.0"
serde = { workspace = true, optional = true }
toml = { version = "0.7", optional = true }
tar = { version = "0.4.37", optional = true }
wasmer = { version = "2.0.0", optional = true, default-features = false, features = ["wat", "default-cranelift", "default-universal"] }
wasmer = { version = "4.0.0-beta.3", optional = true, default-features = false, features = ["sys", "wat", "cranelift"] }
bincode = { workspace = true, optional = true }
plugin-api = { package = "veloren-plugin-api", path = "../../plugin/api", optional = true }
timer-queue = "0.1.0"
wasmer-wasix-types = { version = "0.8.0", default-features = false }
# Tweak running code
#inline_tweak = { version = "1.0.8", features = ["release_tweak"] }

View File

@ -1,5 +1,5 @@
use bincode::ErrorKind;
use wasmer::{ExportError, InstantiationError, RuntimeError};
use wasmer::{CompileError, ExportError, InstantiationError, RuntimeError};
#[derive(Debug)]
pub enum PluginError {
@ -14,12 +14,14 @@ pub enum PluginError {
#[derive(Debug)]
pub enum PluginModuleError {
InstantiationError(Box<InstantiationError>),
InvalidPointer,
MemoryAllocation(MemoryAllocationError),
MemoryUninit(ExportError),
FindFunction(ExportError),
RunFunction(RuntimeError),
InvalidArgumentType(),
Encoding(Box<ErrorKind>),
CompileError(CompileError),
}
#[derive(Debug)]

View File

@ -0,0 +1,125 @@
use crate::plugin::wasm_env::HostFunctionEnvironment;
use wasmer::{AsStoreMut, AsStoreRef, FunctionEnvMut, Memory32, Memory64, MemorySize, WasmPtr};
// there is no WASI defined for wasm64, yet, so always use 32bit pointers
type MemoryModel = wasmer::Memory32;
trait PtrConversion<T, M: MemorySize> {
fn convert(self) -> WasmPtr<T, M>
where
Self: Sized;
}
impl<T> PtrConversion<T, Memory64> for WasmPtr<T, Memory32> {
fn convert(self) -> WasmPtr<T, Memory64>
where
Self: Sized,
{
WasmPtr::new(self.offset().into())
}
}
fn print_impl(
env: &HostFunctionEnvironment,
store: &wasmer::StoreRef<'_>,
ptr: WasmPtr<u8, MemoryModel>,
len: <MemoryModel as wasmer::MemorySize>::Offset,
) -> Result<(), wasmer_wasix_types::wasi::Errno> {
env.read_bytes(store, ptr.convert(), len.into())
.map_err(|error| {
tracing::error!(
"Logging message from plugin {} failed with {:?}!",
env.name,
error
);
wasmer_wasix_types::wasi::Errno::Memviolation
})
.and_then(|bytes| {
std::str::from_utf8(bytes.as_slice())
.map(|msg| tracing::info!("[{}]: {}", env.name, msg))
.map_err(|error| {
tracing::error!(
"Logging message from plugin {} failed with {}!",
env.name,
error
);
wasmer_wasix_types::wasi::Errno::Inval
})
})
}
#[derive(Clone, Copy)]
pub(crate) struct CioVec {
buf: WasmPtr<u8, MemoryModel>,
buf_len: <MemoryModel as wasmer::MemorySize>::Offset,
}
// CioVec has no padding bytes, thus no action is necessary
unsafe impl wasmer::ValueType for CioVec {
fn zero_padding_bytes(&self, _bytes: &mut [std::mem::MaybeUninit<u8>]) {}
}
// fd_write(fd: fd, iovs: ciovec_array) -> Result<size, errno>
pub(crate) fn wasi_fd_write(
mut env: FunctionEnvMut<HostFunctionEnvironment>,
fd: i32,
iov_addr: WasmPtr<CioVec, MemoryModel>,
iov_len: <MemoryModel as wasmer::MemorySize>::Offset,
out_result: WasmPtr<<MemoryModel as wasmer::MemorySize>::Offset, MemoryModel>,
) -> i32 {
use wasmer_wasix_types::wasi::Errno;
if fd != 0 {
Errno::Badf as i32
} else {
let memory = env.data().memory().clone();
let mut written: u32 = 0;
for i in 0..iov_len {
let store = env.as_store_ref();
let Ok(cio) = iov_addr
.add_offset(i)
.and_then(|p| p.read(&memory.view(&store)))
else { return Errno::Memviolation as i32; };
if let Err(e) = print_impl(env.data(), &store, cio.buf, cio.buf_len) {
return e as i32;
}
written += cio.buf_len;
}
let store = env.as_store_mut();
let mem = memory.view(&store);
out_result
.write(&mem, written)
.map_or(Errno::Memviolation as i32, |()| Errno::Success as i32)
}
}
// environ_get(environ: Pointer<Pointer<u8>>, environ_buf: Pointer<u8>) ->
// Result<(), errno>
pub(crate) fn wasi_env_get(
_env: FunctionEnvMut<HostFunctionEnvironment>,
_environ: WasmPtr<WasmPtr<u8, MemoryModel>, MemoryModel>,
_environ_buf: WasmPtr<u8, MemoryModel>,
) -> i32 {
wasmer_wasix_types::wasi::Errno::Success as i32
}
// environ_sizes_get() -> Result<(size, size), errno>
pub(crate) fn wasi_env_sizes_get(
mut env: FunctionEnvMut<HostFunctionEnvironment>,
numptr: WasmPtr<u32, MemoryModel>,
bytesptr: WasmPtr<u32, MemoryModel>,
) -> i32 {
use wasmer_wasix_types::wasi::Errno;
let memory = env.data().memory().clone();
let store = env.as_store_mut();
let mem = memory.view(&store);
if numptr.write(&mem, 0).is_err() {
return Errno::Memviolation as i32;
}
bytesptr
.write(&mem, 0)
.map_or(Errno::Memviolation as i32, |()| Errno::Success as i32)
}
// proc_exit(rval: exitcode)
pub(crate) fn wasi_proc_exit(env: FunctionEnvMut<HostFunctionEnvironment>, _exitcode: i32) {
tracing::warn!("Plugin {} called exit().", env.data().name)
}

View File

@ -1,17 +1,20 @@
use std::sync::atomic::{AtomicPtr, AtomicU32, AtomicU64, Ordering};
use std::sync::atomic::{AtomicPtr, Ordering};
use serde::{de::DeserializeOwned, Serialize};
use serde::{Deserialize, Serialize};
use specs::{
storage::GenericReadStorage, Component, Entities, Entity, Read, ReadStorage, WriteStorage,
};
use wasmer::{Function, Memory, Value};
use wasmer::{Memory, StoreMut, StoreRef, TypedFunction, WasmPtr};
use common::{
comp::{Health, Player},
uid::{IdMaps, Uid},
};
use super::errors::{MemoryAllocationError, PluginModuleError};
use super::{
errors::{MemoryAllocationError, PluginModuleError},
MemoryModel,
};
pub struct EcsWorld<'a, 'b> {
pub entities: &'b Entities<'a>,
@ -55,10 +58,6 @@ impl<'a, 'b, T: Component> From<WriteStorage<'a, T>> for EcsComponentAccess<'a,
fn from(a: WriteStorage<'a, T>) -> Self { Self::WriteOwned(a) }
}
// pub enum EcsResourceAccess<'a, T> {
// Read(Read<'a, T>),
// }
/// This structure wraps the ECS pointer to ensure safety
pub struct EcsAccessManager {
ecs_pointer: AtomicPtr<EcsWorld<'static, 'static>>,
@ -104,19 +103,8 @@ impl EcsAccessManager {
}
}
pub struct MemoryManager {
pub pointer: AtomicU64,
pub length: AtomicU32,
}
impl Default for MemoryManager {
fn default() -> Self {
Self {
pointer: AtomicU64::new(0),
length: AtomicU32::new(0),
}
}
}
#[derive(Default)]
pub struct MemoryManager;
impl MemoryManager {
/// This function check if the buffer is wide enough if not it realloc the
@ -125,40 +113,49 @@ impl MemoryManager {
/// ordering
pub fn get_pointer(
&self,
object_length: u32,
allocator: &Function,
) -> Result<u64, MemoryAllocationError> {
if self.length.load(Ordering::SeqCst) >= object_length {
return Ok(self.pointer.load(Ordering::SeqCst));
}
let pointer = allocator
.call(&[Value::I32(object_length as i32)])
.map_err(MemoryAllocationError::CantAllocate)?;
let pointer = super::module::from_i64(
pointer[0]
.i64()
.ok_or(MemoryAllocationError::InvalidReturnType)?,
);
self.length.store(object_length, Ordering::SeqCst);
self.pointer.store(pointer, Ordering::SeqCst);
Ok(pointer)
store: &mut StoreMut,
object_length: <MemoryModel as wasmer::MemorySize>::Offset,
allocator: &TypedFunction<
<MemoryModel as wasmer::MemorySize>::Offset,
WasmPtr<u8, MemoryModel>,
>,
) -> Result<WasmPtr<u8, MemoryModel>, MemoryAllocationError> {
allocator
.call(store, object_length)
.map_err(MemoryAllocationError::CantAllocate)
}
/// This function writes an object to WASM memory returning a pointer and a
/// length. Will realloc the buffer is not wide enough
pub fn write_data<T: Serialize>(
&self,
store: &mut StoreMut,
memory: &Memory,
allocator: &Function,
allocator: &TypedFunction<
<MemoryModel as wasmer::MemorySize>::Offset,
WasmPtr<u8, MemoryModel>,
>,
object: &T,
) -> Result<(u64, u64), PluginModuleError> {
) -> Result<
(
WasmPtr<u8, MemoryModel>,
<MemoryModel as wasmer::MemorySize>::Offset,
),
PluginModuleError,
> {
self.write_bytes(
store,
memory,
allocator,
&bincode::serialize(object).map_err(PluginModuleError::Encoding)?,
)
}
/// This functions wraps the serialization process
pub fn serialize_data<T: Serialize>(object: &T) -> Result<Vec<u8>, PluginModuleError> {
bincode::serialize(object).map_err(PluginModuleError::Encoding)
}
/// This function writes an object to the wasm memory using the allocator if
/// necessary using length padding.
///
@ -166,34 +163,46 @@ impl MemoryManager {
/// following slice (The object serialized).
pub fn write_data_as_pointer<T: Serialize>(
&self,
store: &mut StoreMut,
memory: &Memory,
allocator: &Function,
allocator: &TypedFunction<
<MemoryModel as wasmer::MemorySize>::Offset,
WasmPtr<u8, MemoryModel>,
>,
object: &T,
) -> Result<u64, PluginModuleError> {
self.write_bytes_as_pointer(
memory,
allocator,
&bincode::serialize(object).map_err(PluginModuleError::Encoding)?,
)
) -> Result<WasmPtr<u8, MemoryModel>, PluginModuleError> {
self.write_bytes_as_pointer(store, memory, allocator, &Self::serialize_data(object)?)
}
/// This function writes an raw bytes to WASM memory returning a pointer and
/// a length. Will realloc the buffer is not wide enough
pub fn write_bytes(
&self,
store: &mut StoreMut,
memory: &Memory,
allocator: &Function,
allocator: &TypedFunction<
<MemoryModel as wasmer::MemorySize>::Offset,
WasmPtr<u8, MemoryModel>,
>,
bytes: &[u8],
) -> Result<(u64, u64), PluginModuleError> {
let len = bytes.len();
let mem_position = self
.get_pointer(len as u32, allocator)
.map_err(PluginModuleError::MemoryAllocation)? as usize;
memory.view()[mem_position..mem_position + len]
.iter()
.zip(bytes.iter())
.for_each(|(cell, byte)| cell.set(*byte));
Ok((mem_position as u64, len as u64))
) -> Result<
(
WasmPtr<u8, MemoryModel>,
<MemoryModel as wasmer::MemorySize>::Offset,
),
PluginModuleError,
> {
let len = bytes.len() as <MemoryModel as wasmer::MemorySize>::Offset;
let ptr = self
.get_pointer(store, len, allocator)
.map_err(PluginModuleError::MemoryAllocation)?;
ptr.slice(
&memory.view(store),
bytes.len() as <MemoryModel as wasmer::MemorySize>::Offset,
)
.and_then(|s| s.write_slice(bytes))
.map_err(|_| PluginModuleError::InvalidPointer)?;
Ok((ptr, len))
}
/// This function writes bytes to the wasm memory using the allocator if
@ -203,38 +212,44 @@ impl MemoryManager {
/// following slice.
pub fn write_bytes_as_pointer(
&self,
store: &mut StoreMut,
memory: &Memory,
allocator: &Function,
allocator: &TypedFunction<
<MemoryModel as wasmer::MemorySize>::Offset,
WasmPtr<u8, MemoryModel>,
>,
bytes: &[u8],
) -> Result<u64, PluginModuleError> {
let len = bytes.len();
let mem_position = self
.get_pointer(len as u32 + 8, allocator)
.map_err(PluginModuleError::MemoryAllocation)? as usize;
// Here we write the length as le bytes followed by the slice data itself in
// WASM memory
memory.view()[mem_position..mem_position + len + 8]
.iter()
.zip((len as u64).to_le_bytes().iter().chain(bytes.iter()))
.for_each(|(cell, byte)| cell.set(*byte));
Ok(mem_position as u64)
) -> Result<WasmPtr<u8, MemoryModel>, PluginModuleError> {
let len = bytes.len() as <MemoryModel as wasmer::MemorySize>::Offset;
let new_bytes = [&len.to_le_bytes(), bytes].concat();
// TODO: could make write_bytes take an IntoIterator to avoid this concat?
self.write_bytes(store, memory, allocator, &new_bytes)
.map(|val| val.0)
}
}
/// This function read data from memory at a position with the array length and
/// This function reads data from memory at a position with the array length and
/// converts it to an object using bincode
pub fn read_data<T: DeserializeOwned>(
memory: &Memory,
position: u64,
length: u64,
pub fn read_data<'a, T: for<'b> Deserialize<'b>>(
memory: &'a Memory,
store: &StoreRef,
ptr: WasmPtr<u8, MemoryModel>,
len: <MemoryModel as wasmer::MemorySize>::Offset,
) -> Result<T, bincode::Error> {
bincode::deserialize(&read_bytes(memory, position, length))
bincode::deserialize(
&read_bytes(memory, store, ptr, len).map_err(|_| bincode::ErrorKind::SizeLimit)?,
)
}
/// This function read raw bytes from memory at a position with the array length
pub fn read_bytes(memory: &Memory, position: u64, length: u64) -> Vec<u8> {
memory.view()[(position as usize)..(position as usize) + length as usize]
.iter()
.map(|x| x.get())
.collect()
/// This function reads raw bytes from memory at a position with the array
/// length
pub fn read_bytes(
memory: &Memory,
store: &StoreRef,
ptr: WasmPtr<u8, MemoryModel>,
len: <MemoryModel as wasmer::MemorySize>::Offset,
) -> Result<Vec<u8>, PluginModuleError> {
ptr.slice(&memory.view(store), len)
.and_then(|s| s.read_to_vec())
.map_err(|_| PluginModuleError::InvalidPointer)
}

View File

@ -1,4 +1,5 @@
pub mod errors;
pub mod exports;
pub mod memory_manager;
pub mod module;
pub mod wasm_env;
@ -13,6 +14,7 @@ use std::{
path::{Path, PathBuf},
};
use tracing::{error, info};
use wasmer::Memory64;
use plugin_api::Event;
@ -24,6 +26,8 @@ use self::{
use rayon::prelude::*;
pub type MemoryModel = Memory64;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PluginData {
name: String,
@ -31,7 +35,6 @@ pub struct PluginData {
dependencies: HashSet<String>,
}
#[derive(Clone)]
pub struct Plugin {
data: PluginData,
modules: Vec<PluginModule>,
@ -87,7 +90,7 @@ impl Plugin {
}
pub fn execute_prepared<T>(
&self,
&mut self,
ecs: &EcsWorld,
event: &PreparedEventQuery<T>,
) -> Result<Vec<T::Response>, PluginError>
@ -95,7 +98,7 @@ impl Plugin {
T: Event,
{
self.modules
.iter()
.iter_mut()
.flat_map(|module| {
module.try_execute(ecs, event).map(|x| {
x.map_err(|e| {
@ -111,7 +114,7 @@ impl Plugin {
}
}
#[derive(Clone, Default)]
#[derive(Default)]
pub struct PluginMgr {
plugins: Vec<Plugin>,
}
@ -125,7 +128,7 @@ impl PluginMgr {
}
pub fn execute_prepared<T>(
&self,
&mut self,
ecs: &EcsWorld,
event: &PreparedEventQuery<T>,
) -> Result<Vec<T::Response>, PluginError>
@ -134,7 +137,7 @@ impl PluginMgr {
{
Ok(self
.plugins
.par_iter()
.par_iter_mut()
.map(|plugin| plugin.execute_prepared(ecs, event))
.collect::<Result<Vec<_>, _>>()?
.into_iter()
@ -143,7 +146,7 @@ impl PluginMgr {
}
pub fn execute_event<T>(
&self,
&mut self,
ecs: &EcsWorld,
event: &T,
) -> Result<Vec<T::Response>, PluginError>

View File

@ -1,29 +1,31 @@
use std::{
collections::HashSet,
convert::TryInto,
marker::PhantomData,
sync::{Arc, Mutex},
};
use hashbrown::HashSet;
use std::{convert::TryInto, marker::PhantomData, sync::Arc};
use wasmer::{imports, Cranelift, Function, Instance, Memory, Module, Store, Universal, Value};
use wasmer::{
imports, AsStoreMut, AsStoreRef, Function, FunctionEnv, FunctionEnvMut, Instance, Memory,
Module, Store, TypedFunction, WasmPtr,
};
use super::{
errors::{PluginError, PluginModuleError},
exports,
memory_manager::{self, EcsAccessManager, EcsWorld, MemoryManager},
wasm_env::HostFunctionEnvironement,
wasm_env::HostFunctionEnvironment,
MemoryModel,
};
use plugin_api::{Action, EcsAccessError, Event, Retrieve, RetrieveError, RetrieveResult};
#[derive(Clone)]
// #[derive(Clone)]
/// This structure represent the WASM State of the plugin.
pub struct PluginModule {
ecs: Arc<EcsAccessManager>,
wasm_state: Arc<Mutex<Instance>>,
wasm_state: Arc<Instance>,
memory_manager: Arc<MemoryManager>,
events: HashSet<String>,
allocator: Function,
allocator: TypedFunction<<MemoryModel as wasmer::MemorySize>::Offset, WasmPtr<u8, MemoryModel>>,
memory: Memory,
store: Store,
#[allow(dead_code)]
name: String,
}
@ -31,16 +33,21 @@ pub struct PluginModule {
impl PluginModule {
/// This function takes bytes from a WASM File and compile them
pub fn new(name: String, wasm_data: &[u8]) -> Result<Self, PluginModuleError> {
// This is creating the engine is this case a JIT based on Cranelift
let engine = Universal::new(Cranelift::default()).engine();
// We are creating an enironnement
let store = Store::new(&engine);
// The store contains all data for a specific instance, including the linear
// memory
let mut store = Store::default();
// We are compiling the WASM file in the previously generated environement
let module = Module::new(&store, wasm_data).expect("Can't compile");
let module = Module::from_binary(store.engine(), wasm_data)
.map_err(PluginModuleError::CompileError)?;
// This is the function imported into the wasm environement
fn raw_emit_actions(env: &HostFunctionEnvironement, ptr: i64, len: i64) {
handle_actions(match env.read_data(from_i64(ptr), from_i64(len)) {
fn raw_emit_actions(
env: FunctionEnvMut<HostFunctionEnvironment>,
// store: &wasmer::StoreRef<'_>,
ptr: WasmPtr<u8, MemoryModel>,
len: <MemoryModel as wasmer::MemorySize>::Offset,
) {
handle_actions(match env.data().read_data(&env.as_store_ref(), ptr, len) {
Ok(e) => e,
Err(e) => {
tracing::error!(?e, "Can't decode action");
@ -49,15 +56,23 @@ impl PluginModule {
});
}
fn raw_retrieve_action(env: &HostFunctionEnvironement, ptr: i64, len: i64) -> i64 {
let out = match env.read_data(from_i64(ptr), from_i64(len)) {
Ok(data) => retrieve_action(&env.ecs, data),
fn raw_retrieve_action(
mut env: FunctionEnvMut<HostFunctionEnvironment>,
// store: &wasmer::StoreRef<'_>,
ptr: WasmPtr<u8, MemoryModel>,
len: <MemoryModel as wasmer::MemorySize>::Offset,
) -> <MemoryModel as wasmer::MemorySize>::Offset {
let out = match env.data().read_data(&env.as_store_ref(), ptr, len) {
Ok(data) => retrieve_action(&env.data().ecs, data),
Err(e) => Err(RetrieveError::BincodeError(e.to_string())),
};
let data = env.data().clone();
// If an error happen set the i64 to 0 so the WASM side can tell an error
// occured
to_i64(env.write_data_as_pointer(&out).unwrap())
data.write_data_as_pointer(&mut env.as_store_mut(), &out)
.unwrap_or_else(|_e| WasmPtr::null())
.offset()
}
fn dbg(a: i32) {
@ -67,18 +82,36 @@ impl PluginModule {
let ecs = Arc::new(EcsAccessManager::default());
let memory_manager = Arc::new(MemoryManager::default());
// Environment to pass ecs and memory_manager to callbacks
let env = FunctionEnv::new(
&mut store,
HostFunctionEnvironment::new(
name.clone(),
Arc::clone(&ecs),
Arc::clone(&memory_manager),
),
);
// Create an import object.
let import_object = imports! {
"env" => {
"raw_emit_actions" => Function::new_native_with_env(&store, HostFunctionEnvironement::new(name.clone(), ecs.clone(),memory_manager.clone()), raw_emit_actions),
"raw_retrieve_action" => Function::new_native_with_env(&store, HostFunctionEnvironement::new(name.clone(), ecs.clone(),memory_manager.clone()), raw_retrieve_action),
"dbg" => Function::new_native(&store, dbg),
}
"raw_emit_actions" => Function::new_typed_with_env(&mut store, &env, raw_emit_actions),
"raw_retrieve_action" => Function::new_typed_with_env(&mut store, &env, raw_retrieve_action),
"dbg" => Function::new_typed(&mut store, dbg),
},
"wasi_snapshot_preview1" => {
"fd_write" => Function::new_typed_with_env(&mut store, &env, exports::wasi_fd_write),
"environ_get" => Function::new_typed_with_env(&mut store, &env, exports::wasi_env_get),
"environ_sizes_get" => Function::new_typed_with_env(&mut store, &env, exports::wasi_env_sizes_get),
"proc_exit" => Function::new_typed_with_env(&mut store, &env, exports::wasi_proc_exit),
},
};
// Create an instance (Code execution environement)
let instance = Instance::new(&module, &import_object)
let instance = Instance::new(&mut store, &module, &import_object)
.map_err(|err| PluginModuleError::InstantiationError(Box::new(err)))?;
let init_args = HostFunctionEnvironment::args_from_instance(&store, &instance)
.map_err(PluginModuleError::FindFunction)?;
env.as_mut(&mut store).init_with_instance(init_args);
Ok(Self {
memory_manager,
ecs,
@ -89,15 +122,15 @@ impl PluginModule {
.clone(),
allocator: instance
.exports
.get_function("wasm_prepare_buffer")
.map_err(PluginModuleError::MemoryUninit)?
.clone(),
.get_typed_function(&store, "wasm_prepare_buffer")
.map_err(PluginModuleError::MemoryUninit)?,
events: instance
.exports
.iter()
.map(|(name, _)| name.to_string())
.collect(),
wasm_state: Arc::new(Mutex::new(instance)),
wasm_state: Arc::new(instance),
store,
name,
})
}
@ -105,7 +138,7 @@ impl PluginModule {
/// This function tries to execute an event for the current module. Will
/// return None if the event doesn't exists
pub fn try_execute<T>(
&self,
&mut self,
ecs: &EcsWorld,
request: &PreparedEventQuery<T>,
) -> Option<Result<T::Response, PluginModuleError>>
@ -116,9 +149,9 @@ impl PluginModule {
return None;
}
// Store the ECS Pointer for later use in `retreives`
let bytes = match self.ecs.execute_with(ecs, || {
let mut state = self.wasm_state.lock().unwrap();
execute_raw(self, &mut state, &request.function_name, &request.bytes)
let s_ecs = self.ecs.clone();
let bytes = match s_ecs.execute_with(ecs, || {
execute_raw(self, &request.function_name, &request.bytes)
}) {
Ok(e) => e,
Err(e) => return Some(Err(e)),
@ -178,52 +211,85 @@ pub fn from_i64(i: i64) -> u64 { u64::from_le_bytes(i.to_le_bytes()) }
// This function is not public because this function should not be used without
// an interface to limit unsafe behaviours
fn execute_raw(
module: &PluginModule,
instance: &mut Instance,
module: &mut PluginModule,
// instance: &mut Instance,
event_name: &str,
bytes: &[u8],
) -> Result<Vec<u8>, PluginModuleError> {
// This write into memory `bytes` using allocation if necessary returning a
// pointer and a length
let (mem_position, len) =
module
.memory_manager
.write_bytes(&module.memory, &module.allocator, bytes)?;
let (ptr, len) = module.memory_manager.write_bytes(
&mut module.store.as_store_mut(),
&module.memory,
&module.allocator,
bytes,
)?;
// This gets the event function from module exports
let func = instance
let func: TypedFunction<
(
WasmPtr<u8, MemoryModel>,
<MemoryModel as wasmer::MemorySize>::Offset,
),
WasmPtr<u8, MemoryModel>,
> = module
.wasm_state
.exports
.get_function(event_name)
.get_typed_function(&module.store.as_store_ref(), event_name)
.map_err(PluginModuleError::MemoryUninit)?;
// We call the function with the pointer and the length
let function_result = func
.call(&[Value::I64(to_i64(mem_position)), Value::I64(to_i64(len))])
let result_ptr = func
.call(&mut module.store.as_store_mut(), ptr, len)
.map_err(PluginModuleError::RunFunction)?;
// Waiting for `multi-value` to be added to LLVM. So we encode a pointer to a
// u128 that represent [u64; 2]
// The first 4 bytes correspond to the length of the result
let result_len: Vec<u8> = result_ptr
.slice(
&module.memory.view(&module.store.as_store_ref()),
std::mem::size_of::<<MemoryModel as wasmer::MemorySize>::Offset>()
as <MemoryModel as wasmer::MemorySize>::Offset,
)
.and_then(|s| s.read_to_vec())
.map_err(|_| PluginModuleError::InvalidPointer)?;
let result_len =
<MemoryModel as wasmer::MemorySize>::Offset::from_le_bytes(result_len.try_into().unwrap());
let u128_pointer = from_i64(
function_result[0]
.i64()
.ok_or_else(PluginModuleError::InvalidArgumentType)?,
);
// Read the result of the function with the pointer and the length
let bytes = memory_manager::read_bytes(
&module.memory,
&module.store.as_store_ref(),
WasmPtr::new(
result_ptr.offset()
+ std::mem::size_of::<<MemoryModel as wasmer::MemorySize>::Offset>()
as <MemoryModel as wasmer::MemorySize>::Offset,
),
result_len,
)?;
Ok(bytes)
// Waiting for `multi-value` to be added to LLVM. So we encode a pointer to
// a u128 that represent [u64; 2]
let bytes = memory_manager::read_bytes(&module.memory, u128_pointer, 16);
// let u128_pointer = from_i64(
// function_result[0]
// .i64()
// .ok_or_else(PluginModuleError::InvalidArgumentType)?,
// );
// let bytes = memory_manager::read_bytes(&module.memory, u128_pointer, 16);
// We read the return object and deserialize it
// The first 8 bytes are encoded as le and represent the pointer to the data
// The next 8 bytes are encoded as le and represent the length of the data
Ok(memory_manager::read_bytes(
&module.memory,
u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
))
// Ok(memory_manager::read_bytes(
// &module.memory,
// u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
// u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
// ))
}
fn retrieve_action(

View File

@ -1,26 +1,34 @@
use std::sync::Arc;
use serde::{de::DeserializeOwned, Serialize};
use wasmer::{Function, HostEnvInitError, Instance, LazyInit, Memory, WasmerEnv};
use wasmer::{ExportError, Instance, Memory, Store, StoreMut, StoreRef, TypedFunction, WasmPtr};
use super::{
errors::PluginModuleError,
memory_manager::{self, EcsAccessManager, MemoryManager},
MemoryModel,
};
#[derive(Clone)]
pub struct HostFunctionEnvironement {
pub struct HostFunctionEnvironment {
pub ecs: Arc<EcsAccessManager>, /* This represent the pointer to the ECS object (set to
* i32::MAX if to ECS is
* availible) */
pub memory: LazyInit<Memory>, // This object represent the WASM Memory
pub allocator: LazyInit<Function>, // Linked to: wasm_prepare_buffer
pub memory: Option<Memory>, // This object represent the WASM Memory
pub allocator: Option<
TypedFunction<<MemoryModel as wasmer::MemorySize>::Offset, WasmPtr<u8, MemoryModel>>,
>, /* Linked to: wasm_prepare_buffer */
pub memory_manager: Arc<MemoryManager>, /* This object represent the current buffer size and
* pointer */
* pointer */
pub name: String, // This represent the plugin name
}
impl HostFunctionEnvironement {
pub struct HostFunctionEnvironmentInit {
allocator: TypedFunction<<MemoryModel as wasmer::MemorySize>::Offset, WasmPtr<u8, MemoryModel>>,
memory: Memory,
}
impl HostFunctionEnvironment {
pub fn new(
name: String,
ecs: Arc<EcsAccessManager>,
@ -29,55 +37,97 @@ impl HostFunctionEnvironement {
Self {
memory_manager,
ecs,
allocator: LazyInit::new(),
memory: LazyInit::new(),
allocator: Default::default(),
memory: Default::default(),
name,
}
}
#[inline]
pub fn ecs(&self) -> &Arc<EcsAccessManager> { &self.ecs }
#[inline]
pub fn memory(&self) -> &Memory { self.memory.as_ref().unwrap() }
#[inline]
pub fn allocator(
&self,
) -> &TypedFunction<<MemoryModel as wasmer::MemorySize>::Offset, WasmPtr<u8, MemoryModel>> {
self.allocator.as_ref().unwrap()
}
#[inline]
pub fn memory_manager(&self) -> &Arc<MemoryManager> { &self.memory_manager }
#[inline]
pub fn name(&self) -> &str { &self.name }
/// This function is a safe interface to WASM memory that writes data to the
/// memory returning a pointer and length
pub fn write_data<T: Serialize>(&self, object: &T) -> Result<(u64, u64), PluginModuleError> {
self.memory_manager.write_data(
self.memory.get_ref().unwrap(),
self.allocator.get_ref().unwrap(),
object,
)
pub fn write_data<T: Serialize>(
&self,
store: &mut StoreMut,
object: &T,
) -> Result<
(
WasmPtr<u8, MemoryModel>,
<MemoryModel as wasmer::MemorySize>::Offset,
),
PluginModuleError,
> {
self.memory_manager
.write_data(store, self.memory(), self.allocator(), object)
}
/// This function is a safe interface to WASM memory that writes data to the
/// memory returning a pointer and length
pub fn write_data_as_pointer<T: Serialize>(
&self,
store: &mut StoreMut,
object: &T,
) -> Result<u64, PluginModuleError> {
self.memory_manager.write_data_as_pointer(
self.memory.get_ref().unwrap(),
self.allocator.get_ref().unwrap(),
object,
)
) -> Result<WasmPtr<u8, MemoryModel>, PluginModuleError> {
self.memory_manager
.write_data_as_pointer(store, self.memory(), self.allocator(), object)
}
/// This function is a safe interface to WASM memory that reads memory from
/// pointer and length returning an object
pub fn read_data<T: DeserializeOwned>(
&self,
position: u64,
length: u64,
store: &StoreRef,
position: WasmPtr<u8, MemoryModel>,
length: <MemoryModel as wasmer::MemorySize>::Offset,
) -> Result<T, bincode::Error> {
memory_manager::read_data(self.memory.get_ref().unwrap(), position, length)
memory_manager::read_data(self.memory(), store, position, length)
}
}
impl WasmerEnv for HostFunctionEnvironement {
fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> {
let memory = instance.exports.get_memory("memory").unwrap();
self.memory.initialize(memory.clone());
/// This function is a safe interface to WASM memory that reads memory from
/// a pointer and a length and returns some bytes
pub fn read_bytes(
&self,
store: &StoreRef,
ptr: WasmPtr<u8, MemoryModel>,
len: <MemoryModel as wasmer::MemorySize>::Offset,
) -> Result<Vec<u8>, PluginModuleError> {
self.memory.as_ref().map_or_else(
|| Err(PluginModuleError::InvalidPointer),
|m| memory_manager::read_bytes(m, store, ptr, len),
)
}
pub fn args_from_instance(
store: &Store,
instance: &Instance,
) -> Result<HostFunctionEnvironmentInit, ExportError> {
let memory = instance.exports.get_memory("memory")?.clone();
let allocator = instance
.exports
.get_function("wasm_prepare_buffer")
.expect("Can't get allocator");
self.allocator.initialize(allocator.clone());
Ok(())
.get_typed_function(store, "wasm_prepare_buffer")?;
Ok(HostFunctionEnvironmentInit { memory, allocator })
}
pub fn init_with_instance(&mut self, args: HostFunctionEnvironmentInit) {
self.memory = Some(args.memory);
self.allocator = Some(args.allocator);
}
}

View File

@ -304,7 +304,7 @@ impl State {
// Load plugins from asset directory
#[cfg(feature = "plugins")]
ecs.insert(match PluginMgr::from_assets() {
Ok(plugin_mgr) => {
Ok(mut plugin_mgr) => {
let ecs_world = EcsWorld {
entities: &ecs.entities(),
health: ecs.read_component().into(),

View File

@ -1214,7 +1214,7 @@ impl Server {
} else {
#[cfg(feature = "plugins")]
{
let plugin_manager = self.state.ecs().read_resource::<PluginMgr>();
let mut plugin_manager = self.state.ecs().write_resource::<PluginMgr>();
let ecs_world = EcsWorld {
entities: &self.state.ecs().entities(),
health: self.state.ecs().read_component().into(),

View File

@ -9,11 +9,7 @@ use std::{str::FromStr, sync::Arc};
use tokio::{runtime::Runtime, sync::oneshot};
use tracing::{error, info};
#[cfg(feature = "plugins")]
use {
common_state::plugin::{memory_manager::EcsWorld, PluginMgr},
plugin_api::event::{PlayerJoinEvent, PlayerJoinResult},
};
// #[cfg(feature = "plugins")] use {};
fn derive_uuid(username: &str) -> Uuid {
let mut state = 144066263297769815596495629667062367629;
@ -99,8 +95,8 @@ impl LoginProvider {
pub(crate) fn login<R>(
pending: &mut PendingLogin,
#[cfg(feature = "plugins")] world: &EcsWorld,
#[cfg(feature = "plugins")] plugin_manager: &PluginMgr,
// #[cfg(feature = "plugins")] world: &EcsWorld,
// #[cfg(feature = "plugins")] plugin_manager: &PluginMgr,
admins: &HashMap<Uuid, AdminRecord>,
whitelist: &HashMap<Uuid, WhitelistRecord>,
banlist: &HashMap<Uuid, BanEntry>,
@ -139,28 +135,33 @@ impl LoginProvider {
#[cfg(feature = "plugins")]
{
// Plugin player join hooks execute for all players, but are only allowed to
// filter non-admins.
// Plugin player join hooks execute for all players, but are
// only allowed to filter non-admins.
//
// We also run it before checking player count, to avoid lock contention in the
// plugin.
match plugin_manager.execute_event(world, &PlayerJoinEvent {
player_name: username.clone(),
player_id: *uuid.as_bytes(),
}) {
Ok(e) => {
if admin.is_none() {
for i in e.into_iter() {
if let PlayerJoinResult::Kick(a) = i {
return Some(Err(RegisterError::Kicked(a)));
}
}
}
},
Err(e) => {
error!("Error occured while executing `on_join`: {:?}", e);
},
};
// We also run it before checking player count, to avoid
// lock contention in the plugin.
// Two events can't be handled on the same plugin in
// parallel, so this needs rework
// match plugin_manager.execute_event(world,
// &PlayerJoinEvent { player_name:
// username.clone(), player_id:
// *uuid.as_bytes(), }) {
// Ok(e) => {
// if admin.is_none() {
// for i in e.into_iter() {
// if let PlayerJoinResult::Kick(a) = i {
// return
// Some(Err(RegisterError::Kicked(a)));
// }
// }
// }
// },
// Err(e) => {
// error!("Error occured while executing `on_join`:
// {:?}", e); },
// };
}
// non-admins can only join if the player count has not been exceeded.

View File

@ -30,7 +30,7 @@ use specs::{
use tracing::{debug, info, trace, warn};
#[cfg(feature = "plugins")]
use {common_state::plugin::memory_manager::EcsWorld, common_state::plugin::PluginMgr};
use common_state::plugin::PluginMgr;
#[cfg(feature = "plugins")]
type ReadPlugin<'a> = Read<'a, PluginMgr>;
@ -138,16 +138,16 @@ impl<'a> System<'a> for Sys {
}
let old_player_count = player_list.len();
#[cfg(feature = "plugins")]
let ecs_world = EcsWorld {
entities: &read_data.entities,
health: (&read_data._healths).into(),
uid: (&read_data.uids).into(),
// NOTE: Only the old player list is provided, to avoid scalability
// bottlenecks.
player: (&players).into(),
id_maps: &read_data._id_maps,
};
// #[cfg(feature = "plugins")]
// let ecs_world = EcsWorld {
// entities: &read_data.entities,
// health: (&read_data._healths).into(),
// uid: (&read_data.uids).into(),
// // NOTE: Only the old player list is provided, to avoid scalability
// // bottlenecks.
// player: (&players).into(),
// id_maps: &read_data._id_maps,
// };
// NOTE: this is just default value.
//
@ -225,10 +225,10 @@ impl<'a> System<'a> for Sys {
mut new_players_guard,
) = match LoginProvider::login(
pending,
#[cfg(feature = "plugins")]
&ecs_world,
#[cfg(feature = "plugins")]
&read_data._plugin_mgr,
// #[cfg(feature = "plugins")]
// &ecs_world,
// #[cfg(feature = "plugins")]
// &read_data._plugin_mgr,
&read_data.editable_settings.admins,
&read_data.editable_settings.whitelist,
&read_data.editable_settings.banlist,