mirror of
https://codeberg.org/demostf/tf-demos-viewer.git
synced 2026-06-03 18:14:11 +02:00
forgot to commit this for 7 months...
This commit is contained in:
parent
ff75c2ca48
commit
6d568799a7
11 changed files with 77 additions and 31 deletions
784
wasm/Cargo.lock
generated
Normal file
784
wasm/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,784 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitbuffer"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d75a9c93bd4423a7740feae26d6daf52b7d53451cba0b2d6bed59b836c32e15c"
|
||||
dependencies = [
|
||||
"bitbuffer_derive",
|
||||
"err-derive",
|
||||
"memchr",
|
||||
"num-traits 0.2.15",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitbuffer_derive"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4090254bfbc71442ff4a426ddba663346e26fd14b55b259281f763e350d7f621"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"syn_util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||
|
||||
[[package]]
|
||||
name = "enum_primitive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
|
||||
dependencies = [
|
||||
"num-traits 0.1.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb"
|
||||
dependencies = [
|
||||
"enumflags2_derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2_derive"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "err-derive"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c34a887c8df3ed90498c1c437ce21f211c8e27672921a8ffa293cb8d6d4caa9e"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"rustversion",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8bf247779e67a9082a4790b45e71ac7cfd1321331a5c856a74a9faebdab78d0"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "main_error"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
|
||||
dependencies = [
|
||||
"num-traits 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
dependencies = [
|
||||
"num-traits 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
||||
|
||||
[[package]]
|
||||
name = "parse-display"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "813e91c6232dbeb2e9deba0eb0dc5c967bd6f380676fd34419f9ddd71411faa7"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"parse-display-derive",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parse-display-derive"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "007ed61a69cf7d9b95cc5dc18489dbb4f70d4adb0a0c100e2dd46f0be241711a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"regex",
|
||||
"regex-syntax",
|
||||
"structmeta",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"thiserror",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snap"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451"
|
||||
|
||||
[[package]]
|
||||
name = "steamid-ng"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb049f8faa2cba570c5366dbaf88ee5849725b16edb771848639fac92e33673"
|
||||
dependencies = [
|
||||
"enum_primitive",
|
||||
"lazy_static",
|
||||
"num",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structmeta"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bd9c2155aa89fb2c2cb87d99a610c689e7c47099b3e9f1c8a8f53faf4e3d2e3"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"structmeta-derive",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structmeta-derive"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bafede0d0a2f21910f36d47b1558caae3076ed80f6f3ad0fc85a91e6ba7e5938"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn_util"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6754c4559b79657554e9d8a0d56e65e490c76d382b9c23108364ec4125dea23c"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"unicode-xid 0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tf-demo-parser"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/demostf/parser#9e3f008e510a0b69cefd48e606adccb7669e700c"
|
||||
dependencies = [
|
||||
"bitbuffer",
|
||||
"enumflags2",
|
||||
"err-derive",
|
||||
"fnv",
|
||||
"itertools",
|
||||
"main_error",
|
||||
"num-traits 0.2.15",
|
||||
"num_enum",
|
||||
"parse-display",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"snap",
|
||||
"steamid-ng",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tf-demos-viewer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"js-sys",
|
||||
"tf-demo-parser",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test",
|
||||
"web-sys",
|
||||
"wee_alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c53f98874615aea268107765aa1ed8f6116782501d18e53d08b471733bea6c85"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8b463991b4eab2d801e724172285ec4195c650e8ec79b149e6c2a8e6dd3f783"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
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 = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"futures",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
dependencies = [
|
||||
"quote 1.0.21",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2d9693b63a742d481c7f80587e057920e568317b2806988c59cd71618bc26c1"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"futures",
|
||||
"js-sys",
|
||||
"scoped-tls",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0789dac148a8840bbcf9efe13905463b733fa96543bfbf263790535c11af7ba5"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"memory_units",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
37
wasm/Cargo.toml
Normal file
37
wasm/Cargo.toml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
[package]
|
||||
name = "tf-demos-viewer"
|
||||
description = "JS bindings for demo parser"
|
||||
version = "0.1.1"
|
||||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||
categories = ["wasm"]
|
||||
readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 3 # demo parsing is slow
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = true
|
||||
#wasm-opt = ["-Oz", "--enable-mutable-globals"]
|
||||
|
||||
[features]
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2.45"
|
||||
wee_alloc = { version = "0.4.2", optional = true }
|
||||
web-sys = { version = "0.3.22", features = ["console"] }
|
||||
js-sys = "0.3.22"
|
||||
tf-demo-parser = { version = "0.4", git = "https://github.com/demostf/parser" }
|
||||
#tf-demo-parser = { version = "0.4", path = "../tf-demo-parser" }
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.2.45"
|
||||
futures = "0.1.27"
|
||||
js-sys = "0.3.22"
|
||||
wasm-bindgen-futures = "0.3.22"
|
||||
210
wasm/src/lib.rs
Normal file
210
wasm/src/lib.rs
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
#![macro_use]
|
||||
|
||||
use crate::state::ParsedDemo;
|
||||
use js_sys::Function;
|
||||
use tf_demo_parser::demo::header::Header;
|
||||
use tf_demo_parser::demo::parser::analyser::UserInfo;
|
||||
use tf_demo_parser::demo::parser::gamestateanalyser::{GameStateAnalyser, World};
|
||||
use tf_demo_parser::demo::vector::Vector;
|
||||
use tf_demo_parser::{Demo, DemoParser, ParseError};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
mod state;
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct XY {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
}
|
||||
|
||||
impl From<Vector> for XY {
|
||||
fn from(vec: Vector) -> Self {
|
||||
XY { x: vec.x, y: vec.y }
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct WorldBoundaries {
|
||||
pub boundary_min: XY,
|
||||
pub boundary_max: XY,
|
||||
}
|
||||
|
||||
impl From<World> for WorldBoundaries {
|
||||
fn from(world: World) -> Self {
|
||||
WorldBoundaries {
|
||||
boundary_min: world.boundary_min.into(),
|
||||
boundary_max: world.boundary_max.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct FlatState {
|
||||
pub player_count: usize,
|
||||
pub building_count: usize,
|
||||
pub boundaries: WorldBoundaries,
|
||||
pub interval_per_tick: f32,
|
||||
pub tick_count: u32,
|
||||
kill_ticks: Box<[u32]>,
|
||||
attackers: Box<[u8]>,
|
||||
assisters: Box<[u8]>,
|
||||
victims: Box<[u8]>,
|
||||
weapons: Vec<String>,
|
||||
player_info: Vec<UserInfo>,
|
||||
data: Box<[u8]>,
|
||||
header: Header,
|
||||
}
|
||||
|
||||
impl FlatState {
|
||||
pub fn new(parsed: ParsedDemo, world: World) -> Self {
|
||||
let ParsedDemo {
|
||||
players,
|
||||
header,
|
||||
buildings,
|
||||
max_building_count,
|
||||
tick,
|
||||
..
|
||||
} = parsed;
|
||||
|
||||
let player_count = players.len();
|
||||
let building_count = max_building_count;
|
||||
|
||||
let flat: Vec<_> = players
|
||||
.into_iter()
|
||||
.chain(buildings.into_iter())
|
||||
.flat_map(|data| data.into_iter())
|
||||
.collect();
|
||||
|
||||
FlatState {
|
||||
player_count,
|
||||
building_count,
|
||||
tick_count: tick as u32,
|
||||
boundaries: world.into(),
|
||||
interval_per_tick: header.duration / (header.ticks as f32),
|
||||
data: flat.into_boxed_slice(),
|
||||
kill_ticks: parsed.kills.iter().map(|kill| kill.tick.into()).collect(),
|
||||
attackers: parsed
|
||||
.kills
|
||||
.iter()
|
||||
.map(|kill| kill.attacker_id as u8)
|
||||
.collect(),
|
||||
assisters: parsed
|
||||
.kills
|
||||
.iter()
|
||||
.map(|kill| kill.assister_id as u8)
|
||||
.collect(),
|
||||
victims: parsed
|
||||
.kills
|
||||
.iter()
|
||||
.map(|kill| kill.victim_id as u8)
|
||||
.collect(),
|
||||
weapons: parsed.kills.into_iter().map(|kill| kill.weapon).collect(),
|
||||
player_info: parsed.player_info,
|
||||
header,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn parse_demo(buffer: Box<[u8]>, progress: &Function) -> Result<FlatState, JsValue> {
|
||||
let (parsed, world) =
|
||||
parse_demo_inner(&buffer, progress).map_err(|e| JsValue::from(e.to_string()))?;
|
||||
|
||||
let world = world.ok_or_else(|| JsValue::from_str("No world defined in demo"))?;
|
||||
|
||||
Ok(FlatState::new(parsed, world))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_data(state: FlatState) -> Box<[u8]> {
|
||||
state.data
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_map(state: &FlatState) -> String {
|
||||
state.header.map.clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_kill_ticks(state: &FlatState) -> Box<[u32]> {
|
||||
state.kill_ticks.clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_attacker_ids(state: &FlatState) -> Box<[u8]> {
|
||||
state.attackers.clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_assister_ids(state: &FlatState) -> Box<[u8]> {
|
||||
state.assisters.clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_victim_ids(state: &FlatState) -> Box<[u8]> {
|
||||
state.victims.clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_weapon(state: &FlatState, kill_id: usize) -> String {
|
||||
state.weapons[kill_id].clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_player_name(state: &FlatState, player_id: usize) -> String {
|
||||
state.player_info[player_id].name.clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_player_entity_id(state: &FlatState, player_id: usize) -> u32 {
|
||||
state.player_info[player_id].entity_id.into()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_player_user_id(state: &FlatState, player_id: usize) -> u8 {
|
||||
state.player_info[player_id].user_id.into()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_player_steam_id(state: &FlatState, player_id: usize) -> String {
|
||||
state.player_info[player_id].steam_id.clone()
|
||||
}
|
||||
|
||||
pub fn parse_demo_inner(
|
||||
buffer: &[u8],
|
||||
progress: &Function,
|
||||
) -> Result<(ParsedDemo, Option<World>), ParseError> {
|
||||
let demo = Demo::new(buffer);
|
||||
|
||||
let parser = DemoParser::new_with_analyser(demo.get_stream(), GameStateAnalyser::default());
|
||||
let (header, mut ticker) = parser.ticker()?;
|
||||
let total_ticks = header.ticks;
|
||||
let mut last_progress = 0.0;
|
||||
|
||||
let mut parsed_demo = ParsedDemo::new(header);
|
||||
|
||||
while ticker.tick()? {
|
||||
parsed_demo.push_state(ticker.state());
|
||||
let new_progress =
|
||||
((u32::from(ticker.state().tick) as f32 / total_ticks as f32) * 100.0).floor();
|
||||
if new_progress > last_progress {
|
||||
last_progress = new_progress;
|
||||
let _ = progress.call1(&JsValue::null(), &last_progress.into());
|
||||
}
|
||||
}
|
||||
|
||||
parsed_demo.finish();
|
||||
|
||||
let state = ticker.into_state();
|
||||
|
||||
parsed_demo.kills = state.kills;
|
||||
Ok((parsed_demo, state.world))
|
||||
}
|
||||
|
||||
// This is like the `main` function, except for JavaScript.
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn main_js() -> Result<(), JsValue> {
|
||||
Ok(())
|
||||
}
|
||||
447
wasm/src/state.rs
Normal file
447
wasm/src/state.rs
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
use tf_demo_parser::demo::data::DemoTick;
|
||||
use tf_demo_parser::demo::header::Header;
|
||||
use tf_demo_parser::demo::parser::analyser::UserInfo;
|
||||
use tf_demo_parser::demo::parser::gamestateanalyser::{
|
||||
Building, Class, Dispenser, GameState, Kill, PlayerState as PlayerAliveState, Sentry, Team,
|
||||
Teleporter, World,
|
||||
};
|
||||
use tf_demo_parser::demo::vector::VectorXY;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
pub struct Angle(u8);
|
||||
|
||||
impl From<f32> for Angle {
|
||||
fn from(val: f32) -> Self {
|
||||
let ratio = val.rem_euclid(360.0) / 360.0;
|
||||
Angle((ratio * u8::max_value() as f32) as u8)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Angle> for f32 {
|
||||
fn from(val: Angle) -> Self {
|
||||
let ratio = val.0 as f32 / u8::max_value() as f32;
|
||||
ratio * 360.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ParsedDemo {
|
||||
last_tick: DemoTick,
|
||||
pub tick: usize,
|
||||
pub players: Vec<Vec<u8>>,
|
||||
pub buildings: Vec<Vec<u8>>,
|
||||
pub kills: Vec<Kill>,
|
||||
pub header: Header,
|
||||
pub player_info: Vec<UserInfo>,
|
||||
pub max_building_count: usize,
|
||||
}
|
||||
|
||||
impl ParsedDemo {
|
||||
pub fn new(header: Header) -> Self {
|
||||
ParsedDemo {
|
||||
last_tick: DemoTick::default(),
|
||||
tick: 0,
|
||||
players: Vec::new(),
|
||||
buildings: Vec::new(),
|
||||
kills: Vec::new(),
|
||||
player_info: Vec::new(),
|
||||
max_building_count: 0,
|
||||
header,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_state(&mut self, game_state: &GameState) {
|
||||
if let Some(world) = game_state.world.as_ref() {
|
||||
for _tick in u32::from(self.last_tick)..u32::from(game_state.tick) {
|
||||
for (index, player) in game_state.players.iter().enumerate() {
|
||||
let state = PlayerState {
|
||||
position: player.position.into(),
|
||||
angle: Angle::from(player.view_angle),
|
||||
health: if player.state == PlayerAliveState::Alive {
|
||||
player.health
|
||||
} else {
|
||||
0
|
||||
},
|
||||
team: player.team,
|
||||
class: player.class,
|
||||
charge: player.charge,
|
||||
};
|
||||
|
||||
if let None = self.players.get(index) {
|
||||
let mut new_player = Vec::with_capacity(
|
||||
self.header.ticks as usize * PlayerState::PACKET_SIZE,
|
||||
);
|
||||
// backfill with defaults
|
||||
new_player.resize(self.tick * PlayerState::PACKET_SIZE, 0);
|
||||
self.players.push(new_player);
|
||||
};
|
||||
|
||||
match (self.player_info.get(index), player.info.as_ref()) {
|
||||
(None, Some(info)) => self.player_info.push(info.clone()),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let parsed_player = &mut self.players[index];
|
||||
parsed_player.extend_from_slice(&state.pack(world));
|
||||
}
|
||||
|
||||
self.max_building_count = self.max_building_count.max(game_state.buildings.len());
|
||||
for (index, building) in game_state.buildings.values().enumerate() {
|
||||
let state = BuildingState::new(building);
|
||||
|
||||
if let None = self.buildings.get(index) {
|
||||
let new_building = Vec::with_capacity(
|
||||
self.header.ticks as usize * BuildingState::PACKET_SIZE,
|
||||
);
|
||||
self.buildings.push(new_building);
|
||||
};
|
||||
|
||||
let parsed_building = &mut self.buildings[index];
|
||||
parsed_building.resize(self.tick * BuildingState::PACKET_SIZE, 0);
|
||||
|
||||
parsed_building.extend_from_slice(&state.pack(world));
|
||||
}
|
||||
self.tick += 1;
|
||||
}
|
||||
self.last_tick = game_state.tick;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(&mut self) {
|
||||
for parsed_building in self.buildings.iter_mut() {
|
||||
parsed_building.resize(self.tick * BuildingState::PACKET_SIZE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
self.players
|
||||
.iter()
|
||||
.fold(0, |size, player| size + player.len())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct PlayerState {
|
||||
position: VectorXY,
|
||||
angle: Angle,
|
||||
health: u16,
|
||||
team: Team,
|
||||
class: Class,
|
||||
charge: u8,
|
||||
}
|
||||
|
||||
impl PlayerState {
|
||||
const PACKET_SIZE: usize = 8;
|
||||
|
||||
pub fn pack(&self, world: &World) -> [u8; Self::PACKET_SIZE] {
|
||||
// for the purpose of viewing the demo in the browser we dont really need high accuracy for
|
||||
// position or angle, so we save a bunch of space by truncating those down to half the number
|
||||
// of bits
|
||||
fn pack_f32(val: f32, min: f32, max: f32) -> u16 {
|
||||
let ratio = (val - min) / (max - min);
|
||||
(ratio * u16::max_value() as f32) as u16
|
||||
}
|
||||
|
||||
let x = pack_f32(self.position.x, world.boundary_min.x, world.boundary_max.x).to_le_bytes();
|
||||
let y = pack_f32(self.position.y, world.boundary_min.y, world.boundary_max.y).to_le_bytes();
|
||||
// 2 bits for team
|
||||
// 4 bits for class
|
||||
// 10 bits for health
|
||||
let team_class_health =
|
||||
((self.team as u16) << 14) + ((self.class as u16) << 10) + self.health;
|
||||
let combined_bytes = team_class_health.to_le_bytes();
|
||||
|
||||
[
|
||||
x[0],
|
||||
x[1],
|
||||
y[0],
|
||||
y[1],
|
||||
combined_bytes[0],
|
||||
combined_bytes[1],
|
||||
self.angle.0,
|
||||
self.charge,
|
||||
]
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn unpack(bytes: [u8; 8], world: &World) -> Self {
|
||||
fn unpack_f32(val: u16, min: f32, max: f32) -> f32 {
|
||||
let ratio = val as f32 / (u16::max_value() as f32);
|
||||
ratio * (max - min) + min
|
||||
}
|
||||
|
||||
let x = unpack_f32(
|
||||
u16::from_le_bytes([bytes[0], bytes[1]]),
|
||||
world.boundary_min.x,
|
||||
world.boundary_max.x,
|
||||
);
|
||||
let y = unpack_f32(
|
||||
u16::from_le_bytes([bytes[2], bytes[3]]),
|
||||
world.boundary_min.y,
|
||||
world.boundary_max.y,
|
||||
);
|
||||
let team_class_health = u16::from_le_bytes([bytes[4], bytes[5]]);
|
||||
let health = team_class_health & 1023;
|
||||
let angle = Angle(bytes[6]);
|
||||
let team = Team::new(team_class_health >> 14);
|
||||
let class = Class::new((team_class_health >> 10) & 15);
|
||||
let charge = bytes[7];
|
||||
|
||||
PlayerState {
|
||||
position: VectorXY { x, y },
|
||||
angle,
|
||||
health,
|
||||
team,
|
||||
class,
|
||||
charge,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_player_packing() {
|
||||
use tf_demo_parser::demo::vector::Vector;
|
||||
|
||||
let world = World {
|
||||
boundary_max: Vector {
|
||||
x: 10000.0,
|
||||
y: 10000.0,
|
||||
z: 100.0,
|
||||
},
|
||||
boundary_min: Vector {
|
||||
x: -10000.0,
|
||||
y: -10000.0,
|
||||
z: -100.0,
|
||||
},
|
||||
};
|
||||
|
||||
let input = PlayerState {
|
||||
position: VectorXY {
|
||||
x: 100.0,
|
||||
y: -5000.0,
|
||||
},
|
||||
angle: Angle::from(213.0),
|
||||
health: 250,
|
||||
team: Team::Blue,
|
||||
class: Class::Demoman,
|
||||
charge: 7,
|
||||
};
|
||||
|
||||
let bytes = input.pack(&world);
|
||||
|
||||
let unpacked = PlayerState::unpack(bytes, &world);
|
||||
assert_eq!(input.angle, unpacked.angle);
|
||||
assert_eq!(input.health, unpacked.health);
|
||||
assert_eq!(input.class, unpacked.class);
|
||||
assert_eq!(input.team, unpacked.team);
|
||||
assert_eq!(input.charge, unpacked.charge);
|
||||
|
||||
assert!(f32::abs(input.position.x - unpacked.position.x) < 0.5);
|
||||
assert!(f32::abs(input.position.y - unpacked.position.y) < 0.5);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum BuildingType {
|
||||
TeleporterEntrance = 0,
|
||||
TeleporterExit = 1,
|
||||
Dispenser = 2,
|
||||
Level1Sentry = 3,
|
||||
Level2Sentry = 4,
|
||||
Level3Sentry = 5,
|
||||
MiniSentry = 6,
|
||||
Unknown = 7,
|
||||
}
|
||||
|
||||
impl Default for BuildingType {
|
||||
fn default() -> Self {
|
||||
BuildingType::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
impl BuildingType {
|
||||
pub fn new(raw: u8) -> BuildingType {
|
||||
match raw {
|
||||
0 => Self::TeleporterEntrance,
|
||||
1 => Self::TeleporterExit,
|
||||
2 => Self::Dispenser,
|
||||
3 => Self::Level1Sentry,
|
||||
4 => Self::Level2Sentry,
|
||||
5 => Self::Level3Sentry,
|
||||
6 => Self::MiniSentry,
|
||||
_ => Self::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_building(building: &Building) -> Self {
|
||||
match building {
|
||||
Building::Sentry(Sentry { is_mini: true, .. }) => BuildingType::MiniSentry,
|
||||
Building::Sentry(Sentry {
|
||||
is_mini: false,
|
||||
level: 1,
|
||||
..
|
||||
}) => BuildingType::Level1Sentry,
|
||||
Building::Sentry(Sentry {
|
||||
is_mini: false,
|
||||
level: 2,
|
||||
..
|
||||
}) => BuildingType::Level2Sentry,
|
||||
Building::Sentry(Sentry {
|
||||
is_mini: false,
|
||||
level: 3,
|
||||
..
|
||||
}) => BuildingType::Level3Sentry,
|
||||
Building::Dispenser(Dispenser { .. }) => BuildingType::Dispenser,
|
||||
Building::Teleporter(Teleporter {
|
||||
is_entrance: true, ..
|
||||
}) => BuildingType::TeleporterEntrance,
|
||||
Building::Teleporter(Teleporter {
|
||||
is_entrance: false, ..
|
||||
}) => BuildingType::TeleporterExit,
|
||||
_ => BuildingType::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct BuildingState {
|
||||
position: VectorXY,
|
||||
angle: Angle,
|
||||
health: u16,
|
||||
team: Team,
|
||||
ty: BuildingType,
|
||||
level: u8,
|
||||
}
|
||||
|
||||
impl BuildingState {
|
||||
const PACKET_SIZE: usize = 7;
|
||||
|
||||
pub fn new(building: &Building) -> Self {
|
||||
let position = building.position();
|
||||
BuildingState {
|
||||
position: VectorXY {
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
},
|
||||
angle: Angle::from(building.angle()),
|
||||
health: building.health(),
|
||||
team: building.team(),
|
||||
ty: BuildingType::from_building(building),
|
||||
level: building.level(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pack(&self, world: &World) -> [u8; 7] {
|
||||
// for the purpose of viewing the demo in the browser we dont really need high accuracy for
|
||||
// position or angle, so we save a bunch of space by truncating those down to half the number
|
||||
// of bits
|
||||
fn pack_f32(val: f32, min: f32, max: f32) -> u16 {
|
||||
let ratio = (val - min) / (max - min);
|
||||
(ratio * u16::max_value() as f32) as u16
|
||||
}
|
||||
|
||||
let x = pack_f32(self.position.x, world.boundary_min.x, world.boundary_max.x).to_le_bytes();
|
||||
let y = pack_f32(self.position.y, world.boundary_min.y, world.boundary_max.y).to_le_bytes();
|
||||
// 2 bits level
|
||||
// 1 bit team
|
||||
// 3 bits for type
|
||||
// 10 bits for health
|
||||
let team = if self.team == Team::Blue { 0 } else { 1 };
|
||||
let team_type_health = ((self.level as u16) << 14)
|
||||
+ ((team as u16) << 13)
|
||||
+ ((self.ty as u16) << 10)
|
||||
+ self.health;
|
||||
let combined_bytes = team_type_health.to_le_bytes();
|
||||
|
||||
[
|
||||
x[0],
|
||||
x[1],
|
||||
y[0],
|
||||
y[1],
|
||||
combined_bytes[0],
|
||||
combined_bytes[1],
|
||||
self.angle.0,
|
||||
]
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn unpack(bytes: [u8; 7], world: &World) -> Self {
|
||||
fn unpack_f32(val: u16, min: f32, max: f32) -> f32 {
|
||||
let ratio = val as f32 / (u16::max_value() as f32);
|
||||
ratio * (max - min) + min
|
||||
}
|
||||
|
||||
let x = unpack_f32(
|
||||
u16::from_le_bytes([bytes[0], bytes[1]]),
|
||||
world.boundary_min.x,
|
||||
world.boundary_max.x,
|
||||
);
|
||||
let y = unpack_f32(
|
||||
u16::from_le_bytes([bytes[2], bytes[3]]),
|
||||
world.boundary_min.y,
|
||||
world.boundary_max.y,
|
||||
);
|
||||
let team_type_health = u16::from_le_bytes([bytes[4], bytes[5]]);
|
||||
let health = team_type_health & 1023;
|
||||
let angle = Angle(bytes[6]);
|
||||
let packed_team = (team_type_health >> 13) & 1;
|
||||
let team = if packed_team == 0 {
|
||||
Team::Blue
|
||||
} else {
|
||||
Team::Red
|
||||
};
|
||||
let ty = BuildingType::new((team_type_health >> 10) as u8 & 7);
|
||||
let level = (team_type_health >> 14) as u8;
|
||||
|
||||
BuildingState {
|
||||
position: VectorXY { x, y },
|
||||
angle,
|
||||
health,
|
||||
team,
|
||||
ty,
|
||||
level,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_building_packing() {
|
||||
use tf_demo_parser::demo::vector::Vector;
|
||||
|
||||
let world = World {
|
||||
boundary_max: Vector {
|
||||
x: 10000.0,
|
||||
y: 10000.0,
|
||||
z: 100.0,
|
||||
},
|
||||
boundary_min: Vector {
|
||||
x: -10000.0,
|
||||
y: -10000.0,
|
||||
z: -100.0,
|
||||
},
|
||||
};
|
||||
|
||||
let input = BuildingState {
|
||||
position: VectorXY {
|
||||
x: 100.0,
|
||||
y: -5000.0,
|
||||
},
|
||||
angle: Angle::from(213.0),
|
||||
health: 250,
|
||||
team: Team::Blue,
|
||||
level: 3,
|
||||
ty: BuildingType::Level1Sentry,
|
||||
};
|
||||
|
||||
let bytes = input.pack(&world);
|
||||
|
||||
let unpacked = BuildingState::unpack(bytes, &world);
|
||||
assert_eq!(input.angle, unpacked.angle);
|
||||
assert_eq!(input.health, unpacked.health);
|
||||
assert_eq!(input.ty, unpacked.ty);
|
||||
assert_eq!(input.team, unpacked.team);
|
||||
assert_eq!(input.level, unpacked.level);
|
||||
|
||||
assert!(f32::abs(input.position.x - unpacked.position.x) < 0.5);
|
||||
assert!(f32::abs(input.position.y - unpacked.position.y) < 0.5);
|
||||
}
|
||||
35
wasm/tests/app.rs
Normal file
35
wasm/tests/app.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use wasm_bindgen_test::{wasm_bindgen_test_configure, wasm_bindgen_test};
|
||||
use futures::prelude::*;
|
||||
use wasm_bindgen::JsValue;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
|
||||
// This runs a unit test in native Rust, so it can only use Rust APIs.
|
||||
#[test]
|
||||
fn rust_test() {
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
|
||||
|
||||
// This runs a unit test in the browser, so it can use browser APIs.
|
||||
#[wasm_bindgen_test]
|
||||
fn web_test() {
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
|
||||
|
||||
// This runs a unit test in the browser, and in addition it supports asynchronous Future APIs.
|
||||
#[wasm_bindgen_test(async)]
|
||||
fn async_test() -> impl Future<Item = (), Error = JsValue> {
|
||||
// Creates a JavaScript Promise which will asynchronously resolve with the value 42.
|
||||
let promise = js_sys::Promise::resolve(&JsValue::from(42));
|
||||
|
||||
// Converts that Promise into a Future.
|
||||
// The unit test will wait for the Future to resolve.
|
||||
JsFuture::from(promise)
|
||||
.map(|x| {
|
||||
assert_eq!(x, 42);
|
||||
})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue