M Cargo.lock => Cargo.lock +478 -1
@@ 86,6 86,81 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
+name = "aeronet"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c7a1ae9f2a25a6ce704cdcac85aa2d62f12cd34e8c6b5e259a400bfb4bde573"
+dependencies = [
+ "aeronet_io",
+ "aeronet_transport",
+ "bevy_app",
+]
+
+[[package]]
+name = "aeronet_io"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bdc30d6e77d611cffd0e6c418299de1eccf21696205de3368f75afc71413a98"
+dependencies = [
+ "anyhow",
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_platform",
+ "bevy_reflect",
+ "bytes",
+ "derive_more",
+ "log",
+]
+
+[[package]]
+name = "aeronet_transport"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "460e73efd6b13dfd43992aff40d0a7a74202ae90b37dd31f4c0db7e368d10e63"
+dependencies = [
+ "aeronet_io",
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_platform",
+ "bevy_reflect",
+ "bevy_time",
+ "bit-vec 0.8.0",
+ "derive_more",
+ "either",
+ "log",
+ "octs",
+ "ringbuf",
+ "typesize",
+]
+
+[[package]]
+name = "aeronet_websocket"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6a721edcf893daea9bf5f565e81b58162c986b0c70d985d7a4ecf3e32e94edd"
+dependencies = [
+ "aeronet_io",
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_platform",
+ "bytes",
+ "cfg-if",
+ "derive_more",
+ "futures",
+ "js-sys",
+ "rcgen",
+ "rustls",
+ "rustls-native-certs",
+ "tokio",
+ "tokio-rustls",
+ "tokio-tungstenite",
+ "tracing",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
name = "ahash"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 389,6 464,34 @@ dependencies = [
]
[[package]]
+name = "aws-lc-rs"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00"
+dependencies = [
+ "aws-lc-sys",
+ "zeroize",
+]
+
+[[package]]
+name = "aws-lc-sys"
+version = "0.41.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4"
+dependencies = [
+ "cc",
+ "cmake",
+ "dunce",
+ "fs_extra",
+]
+
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
name = "bevy"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 1793,6 1896,9 @@ name = "bytes"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
+dependencies = [
+ "portable-atomic",
+]
[[package]]
name = "calloop"
@@ 1943,6 2049,15 @@ dependencies = [
]
[[package]]
+name = "cmake"
+version = "0.1.58"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
+dependencies = [
+ "cc",
+]
+
+[[package]]
name = "codespan-reporting"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2350,6 2465,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
[[package]]
+name = "deranged"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
name = "derive_builder"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2462,7 2586,7 @@ dependencies = [
"subsecond",
"thiserror 2.0.18",
"tracing",
- "tungstenite",
+ "tungstenite 0.28.0",
]
[[package]]
@@ 2553,6 2677,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
[[package]]
+name = "dunce"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
+
+[[package]]
name = "dyn-clone"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2829,6 2959,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
[[package]]
+name = "fs_extra"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
+
+[[package]]
name = "fsevent-sys"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2838,12 2974,28 @@ dependencies = [
]
[[package]]
+name = "futures"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
name = "futures-channel"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
+ "futures-sink",
]
[[package]]
@@ 2853,6 3005,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
+name = "futures-executor"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
name = "futures-io"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2883,6 3046,12 @@ dependencies = [
]
[[package]]
+name = "futures-sink"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
+
+[[package]]
name = "futures-task"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2894,9 3063,13 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
+ "futures-channel",
"futures-core",
+ "futures-io",
"futures-macro",
+ "futures-sink",
"futures-task",
+ "memchr",
"pin-project-lite",
"slab",
]
@@ 2933,6 3106,17 @@ dependencies = [
[[package]]
name = "getrandom"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
@@ 3965,6 4149,12 @@ dependencies = [
]
[[package]]
+name = "num-conv"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967"
+
+[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4301,6 4491,15 @@ dependencies = [
]
[[package]]
+name = "octs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3beef54705459f4a421ff43b6c9b8381f5b84769e4ae69942783dd8918837b7"
+dependencies = [
+ "bytes",
+]
+
+[[package]]
name = "offset-allocator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4323,6 4522,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
[[package]]
+name = "openssl-probe"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
+
+[[package]]
name = "orbclient"
version = "0.3.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4452,6 4657,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
+name = "pem"
+version = "3.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
+dependencies = [
+ "base64",
+ "serde_core",
+]
+
+[[package]]
name = "percent-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4583,6 4798,12 @@ dependencies = [
]
[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
name = "pp-rs"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4820,6 5041,19 @@ dependencies = [
]
[[package]]
+name = "rcgen"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2"
+dependencies = [
+ "pem",
+ "ring",
+ "rustls-pki-types",
+ "time",
+ "yasna",
+]
+
+[[package]]
name = "rdst"
version = "0.20.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4923,6 5157,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
+name = "ring"
+version = "0.17.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "getrandom 0.2.17",
+ "libc",
+ "untrusted",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "ringbuf"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c"
+dependencies = [
+ "crossbeam-utils",
+ "portable-atomic",
+ "portable-atomic-util",
+]
+
+[[package]]
name = "robust"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4996,6 5255,54 @@ dependencies = [
]
[[package]]
+name = "rustls"
+version = "0.23.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
+dependencies = [
+ "aws-lc-rs",
+ "log",
+ "once_cell",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-native-certs"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
+dependencies = [
+ "openssl-probe",
+ "rustls-pki-types",
+ "schannel",
+ "security-framework",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
+dependencies = [
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.103.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
+dependencies = [
+ "aws-lc-rs",
+ "ring",
+ "rustls-pki-types",
+ "untrusted",
+]
+
+[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5029,6 5336,15 @@ dependencies = [
]
[[package]]
+name = "schannel"
+version = "0.1.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5054,6 5370,29 @@ dependencies = [
]
[[package]]
+name = "security-framework"
+version = "3.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
+dependencies = [
+ "bitflags 2.11.1",
+ "core-foundation 0.10.1",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
name = "self_cell"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5293,6 5632,16 @@ dependencies = [
]
[[package]]
+name = "socket2"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
+dependencies = [
+ "libc",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
name = "spade"
version = "2.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5351,6 5700,9 @@ dependencies = [
name = "starkingdoms"
version = "0.1.0"
dependencies = [
+ "aeronet",
+ "aeronet_transport",
+ "aeronet_websocket",
"avian2d",
"bevy",
"bevy_common_assets",
@@ 5416,6 5768,12 @@ dependencies = [
]
[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
name = "svg_fmt"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5566,6 5924,25 @@ dependencies = [
]
[[package]]
+name = "time"
+version = "0.3.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
+dependencies = [
+ "deranged",
+ "num-conv",
+ "powerfmt",
+ "serde_core",
+ "time-core",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
+
+[[package]]
name = "tiny-skia"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5616,6 5993,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
+name = "tokio"
+version = "1.52.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
+dependencies = [
+ "bytes",
+ "libc",
+ "mio",
+ "pin-project-lite",
+ "socket2",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
+dependencies = [
+ "rustls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-tungstenite"
+version = "0.26.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084"
+dependencies = [
+ "futures-util",
+ "log",
+ "rustls",
+ "rustls-native-certs",
+ "rustls-pki-types",
+ "tokio",
+ "tokio-rustls",
+ "tungstenite 0.26.2",
+]
+
+[[package]]
name = "toml"
version = "0.9.12+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5795,6 6212,25 @@ dependencies = [
[[package]]
name = "tungstenite"
+version = "0.26.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13"
+dependencies = [
+ "bytes",
+ "data-encoding",
+ "http",
+ "httparse",
+ "log",
+ "rand 0.9.4",
+ "rustls",
+ "rustls-pki-types",
+ "sha1",
+ "thiserror 2.0.18",
+ "utf-8",
+]
+
+[[package]]
+name = "tungstenite"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442"
@@ 5829,6 6265,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
[[package]]
+name = "typesize"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da66c62c5b7017a2787e77373c03e6a5aafde77a73bff1ff96e91cd2e128179"
+dependencies = [
+ "typesize-derive",
+]
+
+[[package]]
+name = "typesize-derive"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "536b6812192bda8551cfa0e52524e328c6a951b48e66529ee4522d6c721243d6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
name = "typewit"
version = "1.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5877,6 6333,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 7216,6 7678,15 @@ dependencies = [
]
[[package]]
+name = "yasna"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
+dependencies = [
+ "time",
+]
+
+[[package]]
name = "yazi"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 7248,6 7719,12 @@ dependencies = [
]
[[package]]
+name = "zeroize"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+
+[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
M Cargo.toml => Cargo.toml +3 -0
@@ 62,6 62,9 @@ console_error_panic_hook = "0.1"
test_each_file = "0.3.7"
colored = "3"
qsv-tabwriter = "2"
+aeronet = { version = "0.20" }
+aeronet_websocket = { version = "0.20" }
+aeronet_transport = { version = "0.20" }
[profile.dev]
opt-level = 1
M crates/unified/Cargo.toml => crates/unified/Cargo.toml +4 -0
@@ 18,14 18,18 @@ pico-args = { workspace = true }
leafwing-input-manager = { workspace = true }
good_lp = { workspace = true }
web-time = { workspace = true }
+aeronet = { workspace = true }
+aeronet_transport = { workspace = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
ctrlc = { workspace = true, optional = true }
+aeronet_websocket = { workspace = true, features = ["client", "server"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { workspace = true }
tracing-web = { workspace = true }
console_error_panic_hook = { workspace = true }
+aeronet_websocket = { workspace = true, features = ["client"] }
[features]
native_dev = [
M crates/unified/src/cli.rs => crates/unified/src/cli.rs +51 -9
@@ 4,7 4,14 @@ compile_error!("You need to enable one of native, wasm features");
compile_error!("You cannot enable both native and wasm features");
pub enum StkArgs {
- Play,
+ Client {
+ server: String,
+ },
+ #[cfg(not(target_arch = "wasm32"))]
+ Server {
+ bind_to: std::net::SocketAddr,
+ with_client: bool
+ },
}
#[cfg(not(target_arch = "wasm32"))]
@@ 21,12 28,27 @@ pub fn parse_args() -> StkArgs {
std::process::exit(0);
}
- let subcommand = pargs.subcommand().unwrap();
+ let Some(subcommand) = pargs.subcommand().unwrap() else {
+ eprintln!("a subcommand is required");
+ print_help();
+ std::process::exit(1);
+ };
- match subcommand.as_deref() {
- None | Some("play") => StkArgs::Play,
- Some(unknown) => {
- eprintln!("unknown subcommand: {unknown}");
+ match subcommand.as_str() {
+ "client" => {
+ StkArgs::Client {
+ server: pargs.value_from_str(["-s", "--server"]).unwrap(),
+ }
+ },
+ #[cfg(not(target_arch = "wasm32"))]
+ "server" => {
+ StkArgs::Server {
+ bind_to: pargs.value_from_str(["-b", "--bind-to"]).unwrap(),
+ with_client: pargs.contains("--with-client"),
+ }
+ },
+ unknown => {
+ eprintln!("unknown subcommand: {unknown} (is that feature supported on this platform?)");
eprintln!("-h, --help for help");
std::process::exit(1);
}
@@ 36,12 58,32 @@ pub fn parse_args() -> StkArgs {
fn print_help() {
println!("\
USAGE:
- starkingdoms [FLAGS] [subcommand]
+ starkingdoms [FLAGS] <subcommand> [<args>...]
FLAGS:
-h, --help Prints help information
-v, --version Prints version information
SUBCOMMANDS:
- play Run the game (default)");
-}
+ ");
+
+ println!(" client Run the client (see CLIENT for options)");
+
+ if cfg!(not(target_arch = "wasm32")) {
+ println!(" server Run the server (see SERVER for options)");
+ }
+
+ println!("\n");
+
+ println!("\
+CLIENT:
+ -s, --server <URL> WebSocket URL to connect to
+ ");
+ if cfg!(not(target_arch = "wasm32")) {
+ print!("\
+SERVER:
+ -b, --bind-to <IP:PORT> Socket address to bind to
+ --with-client Start a client connected to this server
+ \n");
+ }
+}<
\ No newline at end of file
M crates/unified/src/client/mod.rs => crates/unified/src/client/mod.rs +58 -1
@@ 1,3 1,7 @@
+use aeronet::io::{Session, SessionEndpoint};
+use aeronet::io::connection::{DisconnectReason, Disconnected};
+use aeronet_transport::{Transport, TransportConfig};
+use aeronet_websocket::client::{ClientConfig, WebSocketClient};
use crate::client::crafting::ui::crafting_ui_plugin;
use crate::client::key_input::key_input_plugin;
use crate::client::parts::parts_plugin;
@@ 14,6 18,7 @@ use crate::prelude::*;
use planet::incoming_planets::incoming_planets_plugin;
use crate::client::ship::attachment::client_attachment_plugin;
use crate::shared::ecs::GameplayState;
+use crate::shared::net::LANES;
pub mod colors;
pub mod key_input;
@@ 30,7 35,9 @@ pub mod crafting;
pub mod components;
pub mod plugins;
-pub struct ClientPlugin;
+pub struct ClientPlugin {
+ pub server: Option<String>
+}
impl Plugin for ClientPlugin {
fn build(&self, app: &mut App) {
@@ 52,5 59,55 @@ impl Plugin for ClientPlugin {
.add_plugins(crafting_ui_plugin)
.insert_state(GameplayState::Main)
.insert_resource(DebugPickingMode::Disabled);
+
+ let server = self.server.clone();
+ app.add_systems(Startup, move |mut commands: Commands| {
+ let Some(server) = server.as_ref() else { return };
+ commands.spawn((Name::new("default-session"), TransportConfig { max_memory_usage: 536_870_912, ..default() }))
+ .queue(WebSocketClient::connect(ClientConfig::builder().with_no_cert_validation(), server.clone()));
+ });
+ if self.server.is_some() {
+ app.add_observer(on_connecting);
+ app.add_observer(on_connected);
+ app.add_observer(on_disconnected);
+ }
}
}
+
+pub fn on_connecting(
+ trigger: On<Add, SessionEndpoint>,
+ names: Query<&Name>,
+ mut commands: Commands,
+) {
+ let entity = trigger.event_target();
+ let name = names.get(entity).unwrap();
+ info!("{name} is connecting");
+}
+pub fn on_connected(trigger: On<Add, Session>, names: Query<&Name>, mut sessions: Query<(&Session)>, mut commands: Commands) {
+ let entity = trigger.event_target();
+ let name = names.get(entity).unwrap();
+ info!("{name} is connected");
+ let session = sessions.get_mut(entity).expect("should exist");
+ commands.entity(entity).insert(Transport::new(
+ session,
+ LANES,
+ LANES,
+ bevy::platform::time::Instant::now()
+ ).expect("MTU cannot support"));
+}
+pub fn on_disconnected(trigger: On<Disconnected>, names: Query<&Name>) {
+ let session = trigger.event_target();
+ let name = names.get(session).unwrap();
+
+ match &trigger.reason {
+ DisconnectReason::ByUser(reason) => {
+ info!(?name, ?reason, "session disconnected by user");
+ }
+ DisconnectReason::ByPeer(reason) => {
+ info!(?name, ?reason, "session disconnected by peer");
+ }
+ DisconnectReason::ByError(err) => {
+ warn!(?name, "session disconnected due to error: {err:?}");
+ }
+ }
+}<
\ No newline at end of file
M crates/unified/src/client/plugins.rs => crates/unified/src/client/plugins.rs +21 -5
@@ 1,10 1,16 @@
+use aeronet_websocket::client::WebSocketClientPlugin;
+use bevy::a11y::AccessibilityPlugin;
use crate::client::ClientPlugin;
-use bevy::app::{PluginGroup, PluginGroupBuilder};
+use bevy::app::{PanicHandlerPlugin, PluginGroup, PluginGroupBuilder, ScheduleRunnerPlugin};
use bevy::dev_tools::picking_debug::DebugPickingPlugin;
+use bevy::diagnostic::{DiagnosticsPlugin, FrameCountPlugin};
use bevy::ecs::schedule::ScheduleLabel;
+use bevy::input::InputPlugin;
use bevy::input_focus::InputDispatchPlugin;
+use bevy::log::LogPlugin;
+use bevy::state::app::StatesPlugin;
+use bevy::time::TimePlugin;
use crate::prelude::*;
-use bevy::ui::UiPlugin;
use leafwing_input_manager::plugin::InputManagerPlugin;
pub struct ClientPluginGroup;
@@ 12,12 18,22 @@ pub struct ClientPluginGroup;
impl PluginGroup for ClientPluginGroup {
fn build(self) -> PluginGroupBuilder {
PluginGroupBuilder::start::<Self>()
- .add(MeshPickingPlugin)
+ .add_group(
+ DefaultPlugins.build()
+ .disable::<LogPlugin>()
+ .disable::<TaskPoolPlugin>()
+ .disable::<FrameCountPlugin>()
+ .disable::<TimePlugin>()
+ .disable::<TransformPlugin>()
+ .disable::<DiagnosticsPlugin>()
+ .disable::<AssetPlugin>()
+ .disable::<StatesPlugin>()
+ )
.add(DebugPickingPlugin)
- .add(ClientPlugin)
- .add(UiPlugin)
.add(InputDispatchPlugin)
.add(InputManagerPlugin::<crate::client::input::ClientAction>::default())
+ .add(WebSocketClientPlugin
+ )
}
}
M crates/unified/src/main.rs => crates/unified/src/main.rs +5 -25
@@ 15,6 15,7 @@
#![allow(clippy::missing_panics_doc, reason = "Gamedev! We panic a lot")]
#![allow(clippy::too_many_arguments, reason = "Le Bevy:tm:")]
#![allow(clippy::too_many_lines, reason = "With the three of us, this is impossible")]
+#![allow(dead_code, unused, reason = "We have a lot of this and it's getting annoying")]
pub mod client;
pub mod server;
@@ 23,37 24,16 @@ pub mod prelude;
#[cfg(target_arch = "wasm32")]
pub mod wasm_entrypoint;
-mod cli;
+pub mod cli;
pub mod shared;
+pub mod universal_entrypoint;
use std::str::FromStr;
-use shared::plugins;
#[cfg(target_arch = "wasm32")]
pub use wasm_entrypoint::*;
-use crate::cli::StkArgs;
-use client::plugins::ClientPluginGroup;
use crate::prelude::*;
-use server::plugins::ServerPluginGroup;
-
-fn run(cli: StkArgs) -> AppExit {
- let mut app = App::new();
-
- match cli {
- StkArgs::Play => {
- app.add_plugins(
- DefaultPlugins.build()
- .disable::<bevy::log::LogPlugin>()
- .disable::<bevy::ui::UiPlugin>()
- );
- app.add_plugins(plugins::SharedPluginGroup);
- app.add_plugins(ServerPluginGroup);
- app.add_plugins(ClientPluginGroup);
- }
- }
-
- app.run()
-}
+use crate::universal_entrypoint::run;
#[cfg(feature = "wasm")]
fn main() {
@@ 65,7 45,7 @@ fn main() -> AppExit {
use tracing_subscriber::util::SubscriberInitExt;
use bevy::log::tracing_subscriber;
- let cli = crate::cli::parse_args();
+ let cli = cli::parse_args();
tracing_subscriber::fmt()
.with_env_filter(
M crates/unified/src/server/mod.rs => crates/unified/src/server/mod.rs +107 -16
@@ 12,6 12,13 @@ pub mod orbit;
pub mod plugins;
pub mod components;
+use std::net::SocketAddr;
+use aeronet::io::connection::{DisconnectReason, Disconnected, LocalAddr};
+use aeronet::io::server::Server;
+use aeronet::io::Session;
+use aeronet_transport::lane::LaneKind;
+use aeronet_transport::Transport;
+use aeronet_websocket::server::{ServerConfig, WebSocketServer};
use crate::server::craft::craft_plugin;
use crate::server::damping::damping_plugin;
use crate::server::drill::drill_plugin;
@@ 24,26 31,39 @@ use crate::server::system_sets::{PlayerInputSet, WorldUpdateSet};
use crate::prelude::*;
use crate::server::orbit::OrbitPlugin;
use crate::server::player::thrust::server_thrust_plugin;
+use crate::shared::net::LANES;
-pub struct ServerPlugin;
+pub struct ServerPlugin {
+ pub bind: SocketAddr
+}
impl Plugin for ServerPlugin {
fn build(&self, app: &mut App) {
- app.add_systems(Startup, player::join::spawn_singleplayer_player)
- .add_plugins(planets_plugin)
- .add_plugins(newtonian_gravity_plugin)
- .add_plugins(player_management_plugin)
- .add_plugins(spawn_parts_plugin)
- .add_plugins(part_management_plugin)
- .add_plugins(server_thrust_plugin)
- /*.add_plugins(heat_cooling_plugin)
- .add_plugins(heat_radiation_plugin)
- .add_plugins(heat_conduction_plugin)*/
- .add_plugins(drill_plugin)
- .add_plugins(craft_plugin)
- .add_plugins(OrbitPlugin)
- .add_plugins(damping_plugin)
- .configure_sets(Update, WorldUpdateSet.before(PlayerInputSet));
+ let bind = self.bind;
+ app
+ .add_plugins(planets_plugin)
+ .add_plugins(newtonian_gravity_plugin)
+ .add_plugins(player_management_plugin)
+ .add_plugins(spawn_parts_plugin)
+ .add_plugins(part_management_plugin)
+ .add_plugins(server_thrust_plugin)
+ /*.add_plugins(heat_cooling_plugin)
+ .add_plugins(heat_radiation_plugin)
+ .add_plugins(heat_conduction_plugin)*/
+ .add_plugins(drill_plugin)
+ .add_plugins(craft_plugin)
+ .add_plugins(OrbitPlugin)
+ .add_plugins(damping_plugin)
+ .configure_sets(Update, WorldUpdateSet.before(PlayerInputSet))
+ .add_observer(on_opened)
+ .add_observer(on_connected)
+ .add_observer(on_disconnected)
+ .add_systems(Startup, move |mut commands: Commands| {
+ commands.spawn(Name::new("websocket-server"))
+ .queue(WebSocketServer::open(ServerConfig::builder()
+ .with_bind_address(bind)
+ .with_no_encryption()));
+ });
}
}
@@ 55,3 75,74 @@ pub struct ConnectedGameEntity {
pub struct ConnectedNetworkEntity {
pub game_entity: Entity,
}
+
+
+fn on_opened(trigger: On<Add, Server>, servers: Query<&LocalAddr>) {
+ let server = trigger.event_target();
+ let local_addr = servers.get(server).unwrap();
+ info!(server_entity=?server, "websocket server opened on {:?}", *local_addr);
+}
+
+fn on_connected(
+ trigger: On<Add, Session>,
+ clients: Query<&ChildOf>,
+ sessions: Query<&Session>,
+ mut commands: Commands,
+) {
+ let client = trigger.event_target();
+ let Ok(&ChildOf(server)) = clients.get(client) else {
+ return;
+ };
+ info!(?client, ?server, "client connected");
+
+ let session = sessions.get(client).expect("must exist");
+
+ commands.entity(client).insert(Transport::new(
+ session,
+ LANES,
+ LANES,
+ bevy::platform::time::Instant::now()
+ ).expect("MTU is too small"));
+
+ let player = commands
+ .spawn(ConnectedGameEntity {
+ network_entity: client,
+ })
+ .id();
+
+ commands.entity(client).insert((
+ //TODO: Replicated,
+ ConnectedNetworkEntity {
+ game_entity: player,
+ },
+ ));
+}
+fn on_disconnected(
+ trigger: On<Disconnected>,
+ clients: Query<&ChildOf>,
+ player_entity: Query<&ConnectedNetworkEntity>,
+ mut commands: Commands,
+) {
+ let client = trigger.event_target();
+ let Ok(&ChildOf(server)) = clients.get(client) else {
+ return;
+ };
+ match &trigger.reason {
+ DisconnectReason::ByUser(reason) => {
+ info!(?client, ?server, ?reason, "client disconnected by user");
+ }
+ DisconnectReason::ByPeer(reason) => {
+ info!(?client, ?server, ?reason, "client disconnected by peer");
+ }
+ DisconnectReason::ByError(err) => {
+ warn!(?client, ?server, "client disconnected with error: {err:?}");
+ }
+ }
+ let Ok(other_entity) = player_entity.get(client) else {
+ return;
+ };
+ let Ok(mut commands) = commands.get_entity(other_entity.game_entity) else {
+ return;
+ };
+ commands.despawn();
+}
M crates/unified/src/server/player/join.rs => crates/unified/src/server/player/join.rs +2 -0
@@ 68,6 68,7 @@ pub fn handle_new_players(
planets: Query<(&Transform, &LinearVelocity, &Planet)>,
asset_server: Res<AssetServer>,
) {
+ if q_new_clients.is_empty() { return }
let Some(wc) = &world_config.config else {
warn!("got a joined player, but world config is not loaded! waiting until it is...");
for joined_player in &q_new_clients {
@@ 87,6 88,7 @@ pub fn handle_pending_players(
planets: Query<(&Transform, &LinearVelocity, &Planet)>,
asset_server: Res<AssetServer>,
) {
+ if pending_players.is_empty() { return };
let Some(wc) = &world_config.config else {
warn!("there are pending players, but world config is not loaded! waiting until it is...");
return;
M crates/unified/src/server/plugins.rs => crates/unified/src/server/plugins.rs +7 -4
@@ 1,12 1,15 @@
-use bevy::app::{PluginGroup, PluginGroupBuilder};
-use avian2d::PhysicsPlugins;
-use avian2d::prelude::IslandPlugin;
+use std::time::Duration;
+use aeronet_transport::AeronetTransportPlugin;
+use aeronet_websocket::server::WebSocketServerPlugin;
+use bevy::app::{PluginGroup, PluginGroupBuilder, ScheduleRunnerPlugin};
+use crate::shared::plugins::TICK_RATE;
pub struct ServerPluginGroup;
impl PluginGroup for ServerPluginGroup {
fn build(self) -> PluginGroupBuilder {
PluginGroupBuilder::start::<Self>()
- .add(crate::server::ServerPlugin)
+ .add(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1.0 / TICK_RATE)))
+ .add(WebSocketServerPlugin)
}
}
M crates/unified/src/shared/mod.rs => crates/unified/src/shared/mod.rs +2 -1
@@ 4,4 4,5 @@ pub mod physics;
pub mod thrust;
pub mod world_config;
pub mod plugins;
-pub mod ecs;>
\ No newline at end of file
+pub mod ecs;
+pub mod net;<
\ No newline at end of file
A crates/unified/src/shared/net.rs => crates/unified/src/shared/net.rs +3 -0
@@ 0,0 1,3 @@
+use aeronet_transport::lane::LaneKind;
+
+pub const LANES: [LaneKind; 1] = [LaneKind::ReliableOrdered];
M crates/unified/src/shared/plugins.rs => crates/unified/src/shared/plugins.rs +10 -2
@@ 1,6 1,9 @@
+use aeronet_transport::AeronetTransportPlugin;
use crate::shared::ecs::{CraftPartRequest, DragRequestEvent, ToggleDrillEvent};
use crate::shared::thrust::ThrustSolution;
use bevy::app::{App, PluginGroup, PluginGroupBuilder};
+use bevy::diagnostic::DiagnosticsPlugin;
+use bevy::state::app::StatesPlugin;
use bevy_common_assets::toml::TomlAssetPlugin;
use crate::prelude::*;
use crate::shared::config::part::PartConfig;
@@ 9,7 12,7 @@ use crate::shared::config::recipe::RecipesConfig;
use crate::shared::config::world::GlobalWorldConfig;
use crate::shared::world_config::world_config_plugin;
-const PHYSICS_TICK_RATE: f64 = 20.0;
+pub const TICK_RATE: f64 = 20.0;
const PHYSICS_LENGTH_UNIT: f64 = 100.0;
pub struct SharedPluginGroup;
@@ 17,8 20,13 @@ pub struct SharedPluginGroup;
impl PluginGroup for SharedPluginGroup {
fn build(self) -> PluginGroupBuilder {
PluginGroupBuilder::start::<Self>()
+ .add(AssetPlugin::default())
+ .add(StatesPlugin)
+ .add(TransformPlugin)
+ .add(DiagnosticsPlugin)
+ .add(AeronetTransportPlugin)
.add(|app: &mut App| {
- app.insert_resource(Time::from_hz(PHYSICS_TICK_RATE));
+ app.insert_resource(Time::from_hz(TICK_RATE));
})
.add_group(
PhysicsPlugins::default()
A crates/unified/src/universal_entrypoint.rs => crates/unified/src/universal_entrypoint.rs +35 -0
@@ 0,0 1,35 @@
+use bevy::app::ScheduleRunnerPlugin;
+use bevy::prelude::Startup;
+use crate::cli::StkArgs;
+use crate::client::ClientPlugin;
+use crate::client::plugins::ClientPluginGroup;
+use crate::prelude::{App, AppExit, MinimalPlugins, PluginGroup};
+use crate::server::player::join::spawn_singleplayer_player;
+use crate::server::plugins::ServerPluginGroup;
+use crate::server::ServerPlugin;
+use crate::shared::plugins::SharedPluginGroup;
+
+pub fn run(cli: StkArgs) -> AppExit {
+ let mut app = App::new();
+
+ app.add_plugins(MinimalPlugins.build().disable::<ScheduleRunnerPlugin>());
+ app.add_plugins(SharedPluginGroup);
+
+ match cli {
+ StkArgs::Client { server } => {
+ app.add_plugins(ClientPluginGroup);
+ app.add_plugins(ClientPlugin { server: Some(server) });
+ },
+ StkArgs::Server { bind_to, with_client } => {
+ app.add_plugins(ServerPluginGroup);
+ app.add_plugins(ServerPlugin { bind: bind_to });
+ if with_client {
+ app.add_plugins(ClientPluginGroup);
+ app.add_plugins(ClientPlugin { server: None });
+ app.add_systems(Startup, spawn_singleplayer_player);
+ }
+ }
+ }
+
+ app.run()
+}<
\ No newline at end of file
M crates/unified/src/wasm_entrypoint.rs => crates/unified/src/wasm_entrypoint.rs +4 -18
@@ 11,9 11,10 @@ use bevy::prelude::PluginGroup;
use tracing_web::MakeWebConsoleWriter;
use tracing_subscriber::prelude::*;
use tracing_subscriber::filter::LevelFilter;
+use crate::cli::StkArgs;
#[wasm_bindgen]
-pub fn play(_server: &str) -> Result<(), JsValue> {
+pub fn play(server: &str) -> Result<(), JsValue> {
console_error_panic_hook::set_once();
let fmt_layer = tracing_subscriber::fmt::layer()
.with_ansi(false)
@@ 25,23 26,8 @@ pub fn play(_server: &str) -> Result<(), JsValue> {
.with(fmt_layer)
.init();
- for instance in wgpu::Instance::enabled_backend_features().iter_names() {
- bevy::log::debug!(?instance, "available backend");
- }
-
- let mut app = App::new();
- app.add_plugins(
- DefaultPlugins.build()
- .disable::<LogPlugin>()
- .disable::<UiPlugin>()
- );
- app.add_plugins(SharedPluginGroup);
- app.add_plugins(ServerPluginGroup);
- app.add_plugins(ClientPluginGroup);
-
- app.run();
-
- bevy::prelude::info!("goodbye!");
+ let cli = StkArgs::Client { server };
+ run(cli);
Ok(())
}