generated from esd2-groupwork/template-repository
Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
61a94a14cd |
9 changed files with 920 additions and 4 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
/target
|
||||
target/
|
||||
logs/
|
||||
test.png
|
||||
|
|
627
Cargo.lock
generated
627
Cargo.lock
generated
|
@ -2,6 +2,633 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "communication-layer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"fern",
|
||||
"image",
|
||||
"ipnet",
|
||||
"local-ip-address",
|
||||
"log",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fern"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9b4f005360d32e9325029b38ba47ebd7a56f3316df09249368939562d518645"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"gif",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "local-ip-address"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "136ef34e18462b17bf39a7826f8f3bbc223341f8e83822beb8b77db9a3d49696"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"neli",
|
||||
"thiserror",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neli"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"libc",
|
||||
"log",
|
||||
"neli-proc-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neli-proc-macros"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4"
|
||||
dependencies = [
|
||||
"either",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.4",
|
||||
"windows_aarch64_msvc 0.52.4",
|
||||
"windows_i686_gnu 0.52.4",
|
||||
"windows_i686_msvc 0.52.4",
|
||||
"windows_x86_64_gnu 0.52.4",
|
||||
"windows_x86_64_gnullvm 0.52.4",
|
||||
"windows_x86_64_msvc 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
|
|
|
@ -6,3 +6,10 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4.35"
|
||||
fern = "0.6.2"
|
||||
image = { version = "0.25.0", default-features = false, features = ["png","ff","gif"] }
|
||||
ipnet = "2.9.0"
|
||||
local-ip-address = "0.6.1"
|
||||
log = "0.4.21"
|
||||
rand = "0.8.5"
|
||||
|
|
12
README.md
12
README.md
|
@ -1,3 +1,13 @@
|
|||
# virtual-camera
|
||||
|
||||
Library and server for dissemination of images obtained from the world server.
|
||||
Library and server for dissemination of images obtained from the world server.
|
||||
|
||||
Currently uses TCP to stream images from the world server. Images are saved temporarily for testing purposes.
|
||||
|
||||
## Development
|
||||
|
||||
For development, you must first have Rust installed. This can be done by following the instructions found at [https://rustup.rs/](https://rustup.rs/). Once this is done, clone this repository, and in the root folder of the repository, run `cargo build --release`. This will both build the dependencies, install the correct toolchains, and create a final executable.
|
||||
|
||||
## Testing
|
||||
|
||||
To test this, first download the `comms-testing` branch of the World Server repository, open the `tennis` project, and run the project. Once this is done, build the latest version of this repository, as mentioned above. Finally, run this project, using `cargo run`.
|
||||
|
|
BIN
logScreeenshot.png
Normal file
BIN
logScreeenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 215 KiB |
7
logs/2024-03-21_14.47.log
Normal file
7
logs/2024-03-21_14.47.log
Normal file
|
@ -0,0 +1,7 @@
|
|||
2024-03-21T14:47:31.759962308-04:00 - [INFO, communication_layer] - aggregating all IPs... This may take several minutes...
|
||||
2024-03-21T14:47:36.825148581-04:00 - [INFO, communication_layer] - Stream connected to address: Ok(192.168.0.80:55001)
|
||||
2024-03-21T14:47:36.825292754-04:00 - [INFO, communication_layer] - Start reading...
|
||||
2024-03-21T14:47:38.021199638-04:00 - [INFO, communication_layer] - Image successfully recieved
|
||||
2024-03-21T14:47:38.021453459-04:00 - [INFO, communication_layer] - Building image...
|
||||
2024-03-21T14:47:39.127447553-04:00 - [INFO, communication_layer] - Image built, saving to file...
|
||||
2024-03-21T14:47:44.733286335-04:00 - [INFO, communication_layer] - image saved!
|
8
notes.md
8
notes.md
|
@ -1,5 +1,13 @@
|
|||
<<<<<<< HEAD
|
||||
Communication layer:
|
||||
Add image resolution to initial handshake
|
||||
unity: send x and y resolution
|
||||
SOC: send back colour bit depth
|
||||
unity: check bitdepth before beginning image transfer
|
||||
=======
|
||||
Rust Crate: `image-0.24.9`
|
||||
|
||||
Read image using `ImageBuffer::from_raw(w,h,bytes)`
|
||||
|
||||
image size: 4608 x 2592 x 3 [BGR]
|
||||
>>>>>>> main
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[toolchain]
|
||||
channel="1.76.0-2024-02-08"
|
||||
components = [ "rustc", "cargo", "rust-std", "rustfmt", "rust-docs", "rust-analyzer" ]
|
||||
targets = [ "armv7-unknown-linux-musleabi" ]
|
||||
targets = [ "armv7-unknown-linux-gnueabihf" ]
|
||||
profile = "default"
|
||||
|
|
257
src/main.rs
257
src/main.rs
|
@ -1,3 +1,258 @@
|
|||
use std::{ fs, io::{Bytes, stdin, BufReader, Error, ErrorKind, Read, Write}, net::{IpAddr, Ipv4Addr, SocketAddrV4, TcpStream}, path::Path, thread::{self, JoinHandle}, time::Duration};
|
||||
use chrono::{DateTime, Local};
|
||||
use image::{Rgb, RgbImage};
|
||||
use ipnet::{Ipv4Net,PrefixLenError};
|
||||
use local_ip_address::linux::local_ip;
|
||||
use log::{LevelFilter, trace,debug,warn,error,info};
|
||||
use fern::{log_file, Dispatch};
|
||||
|
||||
//RTSP port is 554; prepare for real world situations
|
||||
const PORT_NUMBER:u16 = 55001;
|
||||
const PORT_PROBE_TIMEOUT:Duration = Duration::new(5,0);
|
||||
const SUBNET_SIZE:u8 = 24;
|
||||
|
||||
//These subnets are well documented;
|
||||
///RIT owns the subnet 129.21.0.0/16; probing by attempting to open thousands of TCP streams
|
||||
///simultaneously is unwise.
|
||||
const UNSAFE_SUBNET:Result<Ipv4Net,PrefixLenError> = Ipv4Net::new(Ipv4Addr::new(129,21,0,0),16);
|
||||
|
||||
///This subnet is universally considered the "local" subnet. This results in 256 addresses, and can
|
||||
///be probed both safely and efficiently, and as long as the world server on the LAN is running it
|
||||
///is functionally guaranteeed to be found.
|
||||
const HOME_SUBNET:Result<Ipv4Net,PrefixLenError> = Ipv4Net::new(Ipv4Addr::new(192,168,0,0),24);
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
setup_logs(&true);
|
||||
//Get host IP
|
||||
let host_ip = local_ip().expect("No real IP address!");
|
||||
trace!("Host IP: {:?}",host_ip);
|
||||
|
||||
let mut thread_list:Vec<JoinHandle<Result<TcpStream,Error>>> = Vec::new();
|
||||
let mut port_list:Vec<TcpStream> = Vec::new();
|
||||
if let IpAddr::V4(host_v4_ip) = host_ip{
|
||||
//Check current subnet
|
||||
let net = Ipv4Net::new(host_v4_ip,SUBNET_SIZE);
|
||||
|
||||
if let Ok(net) = net{
|
||||
//RIT owns 129.21.0.0/16; DO NOT SPAM THIS NETWORK
|
||||
if UNSAFE_SUBNET.unwrap().contains(&net){
|
||||
//Request world server address from user
|
||||
let address = manual_address_prompt();
|
||||
if address.is_ok(){
|
||||
port_list.push(address.unwrap());
|
||||
//thread_list won't be added to, so the thread for loop won't execute
|
||||
}
|
||||
} else if net.contains(&HOME_SUBNET.unwrap()){
|
||||
//Collect all Hosts on the current subnet
|
||||
info!("aggregating all IPs... This may take several minutes...");
|
||||
for net_address in net.hosts(){
|
||||
thread_list.push(
|
||||
thread::spawn(move ||{
|
||||
let ip_port = std::net::SocketAddr::V4(SocketAddrV4::new(net_address, PORT_NUMBER));
|
||||
//Attempt to open a TCP stream with this IP address, exit the thread
|
||||
//returning the open TcpStream, or an error
|
||||
return TcpStream::connect_timeout(&ip_port, PORT_PROBE_TIMEOUT);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Multithread the port-sniffing block, only save sucessful connections
|
||||
for thread in thread_list{
|
||||
let output = thread.join().unwrap();
|
||||
if let Ok(real_output) = output{
|
||||
port_list.push(real_output);
|
||||
}
|
||||
}
|
||||
|
||||
//For all available ports, try the custom communication protocol
|
||||
for mut stream in port_list{
|
||||
info!("Stream connected to address: {:?}",stream.peer_addr());
|
||||
send_processing_time(&mut stream, 2.7f64);
|
||||
read_response(&mut stream);
|
||||
}
|
||||
//TODO: Document/implement RTSP client-side comms
|
||||
//Currently using custom port and custom protocol, but if real-world cameras will
|
||||
//be in use, we will likely need to be portable to the RTSP protocol, or similar
|
||||
}
|
||||
|
||||
//Used to send the calculated time value to the world server
|
||||
pub fn send_processing_time(stream:&mut TcpStream ,sent_value:f64){
|
||||
debug!("Begin handshake; sending timestamp float...");
|
||||
//Write the f64 value, in bytes, to the stream, and ensure it has been sent
|
||||
stream.write(&sent_value.to_le_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
debug!("Timestamp sent!");
|
||||
}
|
||||
|
||||
//Used to recieve images from the world server
|
||||
pub fn read_response(stream:&mut TcpStream){
|
||||
//Buffer the incoming stream
|
||||
let reader = BufReader::new(stream.try_clone().expect("Failed clone"));
|
||||
//Create a storage point for the bytes
|
||||
let mut recieved_bytes:Vec<u8> = Vec::new();
|
||||
//Create an iterator over the stream's bytes
|
||||
let mut iter = reader.bytes();
|
||||
|
||||
debug!("Continue handshake, read back image packet length...");
|
||||
//The first values sent will always be a u32 containing the length of the message (without the
|
||||
//length counted), followed by the image width and height
|
||||
let length = bytes_to_u32(&mut iter);
|
||||
debug!("Image packet length read as {:?}!",length);
|
||||
|
||||
debug!("Continue handshake, read back image width...");
|
||||
let image_width = bytes_to_u32(&mut iter);
|
||||
debug!("Image width read as {:?}!",image_width);
|
||||
|
||||
debug!("Continue handshake, read back image height...");
|
||||
let image_height = bytes_to_u32(&mut iter);
|
||||
debug!("Image height read as {:?}!",image_height);
|
||||
|
||||
//The length of the image is the total number of bytes
|
||||
let byte_depth = length / (image_width * image_height);
|
||||
debug!("Image bitdepth calculated as {:?}!", byte_depth);
|
||||
|
||||
//Confirm to world server the correct number of bytes
|
||||
stream.write(&byte_depth.to_le_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
|
||||
//TODO: Remove assumption
|
||||
//Always assumes world server will send image
|
||||
info!("Start reading...");
|
||||
//Recieve the rest of the message
|
||||
for _ in 0..length{
|
||||
recieved_bytes.push(iter.next().unwrap().unwrap_or(0));
|
||||
}
|
||||
|
||||
info!("Image successfully recieved");
|
||||
|
||||
//Create a blank pane on which to store the read in pixels
|
||||
let mut img = RgbImage::new(image_width,image_height);
|
||||
|
||||
//Create a temporary storage point for u8s when generating pixels
|
||||
let mut temp:Vec<u8> = Vec::new();
|
||||
|
||||
//Iterate over bytes
|
||||
info!("Building image...");
|
||||
for i in 0..recieved_bytes.len(){
|
||||
let byte = recieved_bytes.get(i).expect("Index does not exist!");
|
||||
|
||||
temp.push(byte.clone());
|
||||
//Each pixel is composed of [byte_depth] u8s
|
||||
if ((i as u32)+1) % byte_depth == 0{
|
||||
//Coordinate in the pane = i/3
|
||||
let pixel_number:u32 = (i as u32) /byte_depth;
|
||||
//Insert the pixel into the pane
|
||||
img.put_pixel(
|
||||
//Pixels coming directly from Unity are sent "upside down", that is,
|
||||
//starting at the bottom right, and iterating horizontally, then vertically.
|
||||
//This line compensates and creates a properly-oriented image
|
||||
(image_width-1)-(pixel_number%image_width), (image_height-1)-(pixel_number / image_width),
|
||||
//Extract image from temporary storage, ang generate pixel
|
||||
Rgb::<u8>{0:temp.clone().try_into().expect("bad vector length!")}
|
||||
);
|
||||
//Clear temporary storage
|
||||
temp.clear();
|
||||
}
|
||||
}
|
||||
//Dump image to file
|
||||
//ONLY FOR EXPERIMENTATION AND TESTING PURPOSES
|
||||
info!("Image built, saving to file...");
|
||||
_ = img.save("./test.png");
|
||||
info!("image saved!");
|
||||
}
|
||||
|
||||
///Borrows an iterator over the bytes in a buffered-reader of a TcpStream; reads the next 4 bytes,
|
||||
///outputs the generated u32
|
||||
fn bytes_to_u32(iter:&mut Bytes<BufReader<TcpStream>>) -> u32{
|
||||
let mut array:[u8;4] = [0;4];
|
||||
for i in 0..4{
|
||||
array[i] = iter.next().unwrap().unwrap();
|
||||
}
|
||||
return u32::from_le_bytes(array);
|
||||
}
|
||||
|
||||
///Request the user to input the world server's address into stdin
|
||||
fn manual_address_prompt() -> Result<TcpStream,Error>{
|
||||
let return_val:Result<TcpStream,Error> = Err(Error::new(ErrorKind::AddrNotAvailable,"Invalid Address"));
|
||||
while return_val.is_err(){
|
||||
let mut user_input:String = String::default();
|
||||
match stdin().read_line(&mut user_input){
|
||||
Ok(_) => {
|
||||
match user_input.trim().parse::<SocketAddrV4>(){
|
||||
Ok(address) => {
|
||||
//Test if the address is accurate
|
||||
let stream = TcpStream::connect_timeout(&std::net::SocketAddr::V4(address), PORT_PROBE_TIMEOUT);
|
||||
if stream.is_ok(){
|
||||
return stream;
|
||||
} else {
|
||||
warn!("Address unavailable!");
|
||||
debug!("{:?}",stream.unwrap_err());
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
error!("Unable to properly parse user input!");
|
||||
debug!("{:?}",error);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
error!("Unable to read user input!");
|
||||
debug!("{:?}",error);
|
||||
}
|
||||
}
|
||||
}
|
||||
return return_val;
|
||||
}
|
||||
|
||||
///Set up logging macros to be used throughout the program
|
||||
fn setup_logs(debug:&bool){
|
||||
//Get the current time
|
||||
let chrono_now: DateTime<Local> = Local::now();
|
||||
//Create a log directory, if it does not exist
|
||||
if ! Path::new("logs").is_dir(){
|
||||
_ = fs::create_dir("logs");
|
||||
};
|
||||
//Create a log macro listener
|
||||
_ = fern::Dispatch::new()
|
||||
//Format the output messages
|
||||
.format(|out,message,record|{
|
||||
out.finish(format_args!(
|
||||
"{} - [{}, {}] - {}",
|
||||
Local::now().to_rfc3339(),
|
||||
record.level(),
|
||||
record.target(),
|
||||
message
|
||||
))
|
||||
})
|
||||
//Output to the file
|
||||
.chain({
|
||||
let mut file_logger = Dispatch::new();
|
||||
let date_format = chrono_now.format("%Y-%m-%d_%H.%M").to_string();
|
||||
let local_log_file = log_file(format!("logs/{}.log",date_format)).unwrap();
|
||||
//Set filter based on whether the command is being run in "debug" mode
|
||||
if *debug{
|
||||
file_logger = file_logger.level(LevelFilter::Trace);
|
||||
}
|
||||
else {
|
||||
file_logger = file_logger.level(LevelFilter::Debug);
|
||||
}
|
||||
//Apply the filter and file formatting rules described above
|
||||
file_logger.chain(local_log_file)
|
||||
})
|
||||
.chain({
|
||||
//Also log to stdout
|
||||
let mut stdout_logger = fern::Dispatch::new();
|
||||
if *debug {
|
||||
stdout_logger = stdout_logger.level(LevelFilter::Debug);
|
||||
}
|
||||
else {
|
||||
stdout_logger = stdout_logger.level(LevelFilter::Info);
|
||||
}
|
||||
stdout_logger.chain(std::io::stdout())
|
||||
})
|
||||
//Start listening to macros
|
||||
.apply();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue