mirror of
https://codeberg.org/demostf/tf-demos-viewer.git
synced 2026-06-03 18:14:11 +02:00
more and better
This commit is contained in:
parent
2b45619edc
commit
0572f34c99
6 changed files with 745 additions and 177 deletions
460
Cargo.lock
generated
460
Cargo.lock
generated
|
|
@ -1,55 +1,52 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.13"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitbuffer"
|
||||
version = "0.8.0"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2b3cd4415fb790abfc898cd449f319029933a867462634dbd427c3f884ba6c5"
|
||||
checksum = "d75a9c93bd4423a7740feae26d6daf52b7d53451cba0b2d6bed59b836c32e15c"
|
||||
dependencies = [
|
||||
"bitbuffer_derive",
|
||||
"err-derive",
|
||||
"memchr",
|
||||
"num-traits",
|
||||
"num-traits 0.2.15",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitbuffer_derive"
|
||||
version = "0.8.0"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f51dcbe693d21078994abd2afac5adc9bcc80fbdf80206ebdb33fec4a145693"
|
||||
checksum = "4090254bfbc71442ff4a426ddba663346e26fd14b55b259281f763e350d7f621"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"syn_util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
version = "3.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
|
@ -58,55 +55,66 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.6"
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||
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",
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.1.1"
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
|
||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||
|
||||
[[package]]
|
||||
name = "enum_primitive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn",
|
||||
"num-traits 0.1.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2"
|
||||
version = "0.6.4"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0"
|
||||
checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb"
|
||||
dependencies = [
|
||||
"enumflags2_derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2_derive"
|
||||
version = "0.6.4"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce"
|
||||
checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "err-derive"
|
||||
version = "0.2.4"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4"
|
||||
checksum = "c34a887c8df3ed90498c1c437ce21f211c8e27672921a8ffa293cb8d6d4caa9e"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"rustversion",
|
||||
"syn",
|
||||
"synstructure",
|
||||
|
|
@ -120,21 +128,30 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.30"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c7e4c2612746b0df8fed4ce0c69156021b704c9aefa360311c04e6e9e002eed"
|
||||
checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.6"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.45"
|
||||
version = "0.3.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8"
|
||||
checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
|
@ -147,30 +164,30 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.79"
|
||||
version = "0.2.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743"
|
||||
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "main_error"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb63bb1e282e0b6aba0addb1f0e87cb5181ea68142b2dfd21ba108f8e8088a64"
|
||||
checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.3"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
|
|
@ -179,47 +196,122 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.12"
|
||||
name = "num"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
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.1"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "226b45a5c2ac4dd696ed30fa6b94b057ad909c7b7fc2e0d0808192bced894066"
|
||||
checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.1"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c0fd9eba1d5db0994a239e09c1be402d35622277e35468ba891aa5e3188ce7e"
|
||||
checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.5.2"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
||||
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
|
||||
|
||||
[[package]]
|
||||
name = "parse-display"
|
||||
version = "0.4.0"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12035532e456d9f4f59fcfa3834dc5f45b391d9029f5287292bf41960b05ce91"
|
||||
checksum = "813e91c6232dbeb2e9deba0eb0dc5c967bd6f380676fd34419f9ddd71411faa7"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"parse-display-derive",
|
||||
|
|
@ -228,24 +320,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parse-display-derive"
|
||||
version = "0.4.0"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "449f5881ab953fa168d60a57dd182a3e1fdeff16bb9bdd309145fbd8f32326ec"
|
||||
checksum = "007ed61a69cf7d9b95cc5dc18489dbb4f70d4adb0a0c100e2dd46f0be241711a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"regex",
|
||||
"regex-syntax",
|
||||
"structmeta",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "0.1.5"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
|
||||
checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"thiserror",
|
||||
"toml",
|
||||
]
|
||||
|
||||
|
|
@ -256,8 +351,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
|
@ -268,8 +363,8 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
|
@ -284,11 +379,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -302,47 +397,41 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"proc-macro2 1.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.9"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.18"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.3"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn",
|
||||
]
|
||||
checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
|
|
@ -352,29 +441,29 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.116"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
|
||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.116"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
|
||||
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.58"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4"
|
||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
|
@ -383,34 +472,68 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.6"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
|
||||
checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snap"
|
||||
version = "0.2.5"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95d697d63d44ad8b78b8d235bf85b34022a78af292c8918527c5f0cffdde7f43"
|
||||
checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451"
|
||||
|
||||
[[package]]
|
||||
name = "steamid-ng"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb049f8faa2cba570c5366dbaf88ee5849725b16edb771848639fac92e33673"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"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.42"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228"
|
||||
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"unicode-xid 0.2.1",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -419,41 +542,41 @@ version = "0.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6754c4559b79657554e9d8a0d56e65e490c76d382b9c23108364ec4125dea23c"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.4"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tf-demo-parser"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c55bccc934036ee9fb1c88106ef3b23a4375bc2fb7cddb735e15d1f265561713"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"bitbuffer",
|
||||
"enumflags2",
|
||||
"err-derive",
|
||||
"fnv",
|
||||
"itertools",
|
||||
"main_error",
|
||||
"num-traits",
|
||||
"num-traits 0.2.15",
|
||||
"num_enum",
|
||||
"parse-display",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"snap",
|
||||
"steamid-ng",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -471,23 +594,40 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
name = "thiserror"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.6"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
||||
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
|
|
@ -496,37 +636,37 @@ checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.68"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
|
||||
checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.68"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
|
||||
checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -537,7 +677,7 @@ version = "0.3.27"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 0.1.10",
|
||||
"futures",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
|
@ -546,22 +686,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.68"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
|
||||
checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
|
||||
dependencies = [
|
||||
"quote 1.0.7",
|
||||
"quote 1.0.21",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.68"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
|
||||
checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"proc-macro2 1.0.43",
|
||||
"quote 1.0.21",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
|
|
@ -569,9 +709,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.68"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
||||
checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
|
|
@ -600,9 +740,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.45"
|
||||
version = "0.3.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d"
|
||||
checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
|
@ -614,7 +754,7 @@ version = "0.4.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"memory_units",
|
||||
"winapi",
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ wasm-opt = false
|
|||
wasm-bindgen = "0.2.45"
|
||||
wee_alloc = { version = "0.4.2", optional = true }
|
||||
web-sys = { version = "0.3.22", features = ["console"] }
|
||||
tf-demo-parser = "0.2"
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
export {parseDemo, ParsedDemo, PlayerState, WorldBoundaries, Class, Team} from "./parser";
|
||||
export {parseDemo, ParsedDemo, PlayerState, WorldBoundaries, Class, Team, BuildingType} from "./parser";
|
||||
|
|
|
|||
123
js/parser.ts
123
js/parser.ts
|
|
@ -5,13 +5,41 @@ export async function parseDemo(bytes: Uint8Array): Promise<ParsedDemo> {
|
|||
const state = m.parse_demo(bytes);
|
||||
|
||||
let playerCount = state.player_count;
|
||||
let buildingCount = state.building_count;
|
||||
let boundaries = state.boundaries;
|
||||
let interval_per_tick = state.interval_per_tick;
|
||||
let kill_ticks = m.get_kill_ticks(state);
|
||||
let attackers = m.get_attacker_ids(state);
|
||||
let assisters = m.get_assister_ids(state);
|
||||
let victims = m.get_victim_ids(state);
|
||||
|
||||
let playerInfo = [];
|
||||
|
||||
for (let i = 0; i < playerCount; i++) {
|
||||
playerInfo.push({
|
||||
name: m.get_player_name(state, i),
|
||||
steamId: m.get_player_steam_id(state, i),
|
||||
entityId: m.get_player_entity_id(state, i),
|
||||
})
|
||||
}
|
||||
|
||||
let kills = [];
|
||||
for (let i = 0; i < kill_ticks.length; i++) {
|
||||
kills.push({
|
||||
tick: kill_ticks[i],
|
||||
attacker: attackers[i],
|
||||
assister: assisters[i],
|
||||
victim: victims[i],
|
||||
weapon: m.get_weapon(state, i),
|
||||
})
|
||||
}
|
||||
|
||||
let map = m.get_map(state);
|
||||
let data = m.get_data(state);
|
||||
|
||||
return new ParsedDemo(
|
||||
playerCount,
|
||||
buildingCount,
|
||||
{
|
||||
boundary_min: {
|
||||
x: boundaries.boundary_min.x,
|
||||
|
|
@ -26,10 +54,18 @@ export async function parseDemo(bytes: Uint8Array): Promise<ParsedDemo> {
|
|||
map,
|
||||
interval_per_tick
|
||||
},
|
||||
data
|
||||
data,
|
||||
kills,
|
||||
playerInfo
|
||||
);
|
||||
}
|
||||
|
||||
export interface PlayerInfo {
|
||||
entityId: number,
|
||||
name: string,
|
||||
steamId: string,
|
||||
}
|
||||
|
||||
export enum Team {
|
||||
Other = 0,
|
||||
Spectator = 1,
|
||||
|
|
@ -50,6 +86,17 @@ export enum Class {
|
|||
Engineer = 9,
|
||||
}
|
||||
|
||||
export enum BuildingType {
|
||||
TeleporterEntrance = 0,
|
||||
TeleporterExit = 1,
|
||||
Dispenser = 2,
|
||||
Level1Sentry = 3,
|
||||
Level2Sentry = 4,
|
||||
Level3Sentry = 5,
|
||||
MiniSentry = 6,
|
||||
Unknown = 7,
|
||||
}
|
||||
|
||||
export interface WorldBoundaries {
|
||||
boundary_min: {
|
||||
x: number,
|
||||
|
|
@ -70,6 +117,19 @@ export interface PlayerState {
|
|||
health: number,
|
||||
team: Team,
|
||||
playerClass: Class,
|
||||
info: PlayerInfo,
|
||||
charge: number,
|
||||
}
|
||||
|
||||
export interface BuildingState {
|
||||
position: {
|
||||
x: number,
|
||||
y: number
|
||||
},
|
||||
angle: number,
|
||||
health: number,
|
||||
team: Team,
|
||||
buildingType: BuildingType,
|
||||
}
|
||||
|
||||
export interface Header {
|
||||
|
|
@ -77,6 +137,14 @@ export interface Header {
|
|||
map: string
|
||||
}
|
||||
|
||||
export interface Kill {
|
||||
tick: number,
|
||||
attacker: number,
|
||||
assister: number,
|
||||
victim: number,
|
||||
weapon: string,
|
||||
}
|
||||
|
||||
function unpack_f32(val: number, min: number, max: number): number {
|
||||
const ratio = val / (Math.pow(2, 16) - 1);
|
||||
return ratio * (max - min) + min;
|
||||
|
|
@ -89,17 +157,23 @@ function unpack_angle(val: number): number {
|
|||
|
||||
export class ParsedDemo {
|
||||
public readonly playerCount: number;
|
||||
public readonly buildingCount: number;
|
||||
public readonly world: WorldBoundaries;
|
||||
public readonly data: Uint8Array;
|
||||
private readonly header: Header;
|
||||
public readonly tickCount: number;
|
||||
public readonly kills: Kill[];
|
||||
public readonly playerInfo: PlayerInfo[];
|
||||
|
||||
constructor(playerCount: number, world: WorldBoundaries, header: Header, data: Uint8Array) {
|
||||
constructor(playerCount: number, buildingCount: number, world: WorldBoundaries, header: Header, data: Uint8Array, kills: Kill[], playerInfo: PlayerInfo[]) {
|
||||
this.playerCount = playerCount;
|
||||
this.buildingCount = buildingCount;
|
||||
this.world = world;
|
||||
this.header = header;
|
||||
this.data = data;
|
||||
this.tickCount = data.length / playerCount / PACK_SIZE;
|
||||
this.kills = kills;
|
||||
this.playerInfo = playerInfo;
|
||||
this.tickCount = data.length / (playerCount * PLAYER_PACK_SIZE + buildingCount * BUILDING_PACK_SIZE);
|
||||
}
|
||||
|
||||
getPlayer(tick: number, playerIndex: number): PlayerState {
|
||||
|
|
@ -107,14 +181,24 @@ export class ParsedDemo {
|
|||
throw new Error("Player out of bounds");
|
||||
}
|
||||
|
||||
const base = ((playerIndex * this.tickCount) + tick) * PACK_SIZE;
|
||||
return unpackPlayer(this.data, base, this.world);
|
||||
const base = ((playerIndex * this.tickCount) + tick) * PLAYER_PACK_SIZE;
|
||||
return unpackPlayer(this.data, base, this.world, this.playerInfo[playerIndex]);
|
||||
}
|
||||
|
||||
getBuilding(tick: number, buildingIndex: number): BuildingState {
|
||||
if (buildingIndex >= this.buildingCount) {
|
||||
throw new Error("Player out of bounds");
|
||||
}
|
||||
|
||||
const base = ((buildingIndex * this.tickCount) + tick) * BUILDING_PACK_SIZE;
|
||||
return unpackBuilding(this.data, base, this.world);
|
||||
}
|
||||
}
|
||||
|
||||
const PACK_SIZE = 7;
|
||||
const PLAYER_PACK_SIZE = 8;
|
||||
const BUILDING_PACK_SIZE = 7;
|
||||
|
||||
function unpackPlayer(bytes: Uint8Array, base: number, world: WorldBoundaries): PlayerState {
|
||||
function unpackPlayer(bytes: Uint8Array, base: number, world: WorldBoundaries, info: PlayerInfo): PlayerState {
|
||||
const x = unpack_f32(bytes[base] + (bytes[base + 1] << 8), world.boundary_min.x, world.boundary_max.x);
|
||||
const y = unpack_f32(bytes[base + 2] + (bytes[base + 3] << 8), world.boundary_min.y, world.boundary_max.y);
|
||||
const team_class_health = bytes[base + 4] + (bytes[base + 5] << 8);
|
||||
|
|
@ -122,12 +206,33 @@ function unpackPlayer(bytes: Uint8Array, base: number, world: WorldBoundaries):
|
|||
const health = team_class_health & 1013;
|
||||
const team = (team_class_health >> 14) as Team;
|
||||
const playerClass = ((team_class_health >> 10) & 15) as Class;
|
||||
const charge = bytes[base + 7];
|
||||
|
||||
return {
|
||||
position: {x, y},
|
||||
angle,
|
||||
health,
|
||||
team,
|
||||
playerClass
|
||||
playerClass,
|
||||
info,
|
||||
charge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function unpackBuilding(bytes: Uint8Array, base: number, world: WorldBoundaries): BuildingState {
|
||||
const x = unpack_f32(bytes[base] + (bytes[base + 1] << 8), world.boundary_min.x, world.boundary_max.x);
|
||||
const y = unpack_f32(bytes[base + 2] + (bytes[base + 3] << 8), world.boundary_min.y, world.boundary_max.y);
|
||||
const team_type_health = bytes[base + 4] + (bytes[base + 5] << 8);
|
||||
const angle = unpack_angle(bytes[base + 6]);
|
||||
const health = team_type_health & 1013;
|
||||
const team = (team_type_health >> 13) as Team;
|
||||
const buildingType = ((team_type_health >> 10) & 7) as BuildingType;
|
||||
|
||||
return {
|
||||
position: {x, y},
|
||||
angle,
|
||||
health,
|
||||
team,
|
||||
buildingType
|
||||
}
|
||||
}
|
||||
|
|
|
|||
77
src/lib.rs
77
src/lib.rs
|
|
@ -1,9 +1,8 @@
|
|||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
#![macro_use]
|
||||
|
||||
use crate::state::ParsedDemo;
|
||||
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};
|
||||
|
|
@ -43,8 +42,15 @@ impl From<World> for WorldBoundaries {
|
|||
#[wasm_bindgen]
|
||||
pub struct FlatState {
|
||||
pub player_count: usize,
|
||||
pub building_count: usize,
|
||||
pub boundaries: WorldBoundaries,
|
||||
pub interval_per_tick: f32,
|
||||
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,
|
||||
}
|
||||
|
|
@ -52,21 +58,45 @@ pub struct FlatState {
|
|||
impl FlatState {
|
||||
pub fn new(parsed: ParsedDemo, world: World) -> Self {
|
||||
let ParsedDemo {
|
||||
players, header, ..
|
||||
players,
|
||||
header,
|
||||
buildings,
|
||||
..
|
||||
} = parsed;
|
||||
|
||||
let player_count = players.len();
|
||||
let building_count = buildings.len();
|
||||
|
||||
let flat: Vec<_> = players
|
||||
.into_iter()
|
||||
.chain(buildings.into_iter())
|
||||
.flat_map(|player| player.into_iter())
|
||||
.collect();
|
||||
|
||||
FlatState {
|
||||
player_count,
|
||||
building_count,
|
||||
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 as u32).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,
|
||||
}
|
||||
}
|
||||
|
|
@ -91,6 +121,46 @@ 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_steam_id(state: &FlatState, player_id: usize) -> String {
|
||||
state.player_info[player_id].steam_id.clone()
|
||||
}
|
||||
|
||||
pub fn parse_demo_inner(buffer: &[u8]) -> Result<(ParsedDemo, Option<World>), ParseError> {
|
||||
let demo = Demo::new(buffer);
|
||||
let parser = DemoParser::new_with_analyser(demo.get_stream(), GameStateAnalyser::default());
|
||||
|
|
@ -108,6 +178,7 @@ pub fn parse_demo_inner(buffer: &[u8]) -> Result<(ParsedDemo, Option<World>), Pa
|
|||
}
|
||||
|
||||
let world: Option<&World> = ticker.state().world.as_ref();
|
||||
parsed_demo.kills = ticker.state().kills.clone();
|
||||
Ok((parsed_demo, world.map(|w| w.clone())))
|
||||
}
|
||||
|
||||
|
|
|
|||
281
src/state.rs
281
src/state.rs
|
|
@ -1,5 +1,8 @@
|
|||
use tf_demo_parser::demo::header::Header;
|
||||
use tf_demo_parser::demo::parser::gamestateanalyser::{Class, GameState, Team, World};
|
||||
use tf_demo_parser::demo::parser::analyser::UserInfo;
|
||||
use tf_demo_parser::demo::parser::gamestateanalyser::{
|
||||
Building, Class, GameState, Kill, PlayerState as PlayerAliveState, Team, World,
|
||||
};
|
||||
use tf_demo_parser::demo::vector::VectorXY;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
|
|
@ -23,7 +26,10 @@ impl From<Angle> for f32 {
|
|||
pub struct ParsedDemo {
|
||||
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>,
|
||||
}
|
||||
|
||||
impl ParsedDemo {
|
||||
|
|
@ -31,6 +37,9 @@ impl ParsedDemo {
|
|||
ParsedDemo {
|
||||
tick: 0,
|
||||
players: Vec::new(),
|
||||
buildings: Vec::new(),
|
||||
kills: Vec::new(),
|
||||
player_info: Vec::new(),
|
||||
header,
|
||||
}
|
||||
}
|
||||
|
|
@ -41,18 +50,42 @@ impl ParsedDemo {
|
|||
let state = PlayerState {
|
||||
position: player.position.into(),
|
||||
angle: Angle::from(player.view_angle),
|
||||
health: player.health,
|
||||
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::default();
|
||||
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));
|
||||
}
|
||||
for (index, building) in game_state.buildings.iter().enumerate() {
|
||||
let state = BuildingState::new(building);
|
||||
|
||||
if let None = self.buildings.get(index) {
|
||||
let mut new_building =
|
||||
Vec::with_capacity(self.header.ticks as usize * BuildingState::PACKET_SIZE);
|
||||
new_building.resize(self.tick * BuildingState::PACKET_SIZE, 0);
|
||||
self.buildings.push(new_building);
|
||||
};
|
||||
|
||||
let parsed_player = &mut self.players[index];
|
||||
parsed_player.extend_from_slice(&state.pack(world));
|
||||
}
|
||||
|
|
@ -74,12 +107,13 @@ pub struct PlayerState {
|
|||
health: u16,
|
||||
team: Team,
|
||||
class: Class,
|
||||
charge: u8,
|
||||
}
|
||||
|
||||
impl PlayerState {
|
||||
const PACKET_SIZE: usize = 8;
|
||||
|
||||
pub fn pack(&self, world: &World) -> [u8; 7] {
|
||||
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
|
||||
|
|
@ -97,6 +131,223 @@ impl PlayerState {
|
|||
((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 { is_mini: true, .. } => BuildingType::MiniSentry,
|
||||
Building::Sentry {
|
||||
is_mini: false,
|
||||
level: 1,
|
||||
..
|
||||
} => BuildingType::Level1Sentry,
|
||||
Building::Sentry {
|
||||
is_mini: false,
|
||||
level: 2,
|
||||
..
|
||||
} => BuildingType::Level2Sentry,
|
||||
Building::Sentry {
|
||||
is_mini: false,
|
||||
level: 3,
|
||||
..
|
||||
} => BuildingType::Level3Sentry,
|
||||
Building::Dispenser { .. } => BuildingType::Dispenser,
|
||||
Building::Teleporter {
|
||||
is_entrance: true, ..
|
||||
} => BuildingType::TeleporterEntrance,
|
||||
Building::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,
|
||||
}
|
||||
|
||||
impl BuildingState {
|
||||
const PACKET_SIZE: usize = 7;
|
||||
|
||||
pub fn new(building: &Building) -> Self {
|
||||
match building {
|
||||
Building::Sentry {
|
||||
position,
|
||||
angle,
|
||||
health,
|
||||
team,
|
||||
..
|
||||
}
|
||||
| Building::Dispenser {
|
||||
position,
|
||||
angle,
|
||||
health,
|
||||
team,
|
||||
..
|
||||
}
|
||||
| Building::Teleporter {
|
||||
position,
|
||||
angle,
|
||||
health,
|
||||
team,
|
||||
..
|
||||
} => BuildingState {
|
||||
position: VectorXY {
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
},
|
||||
angle: Angle::from(*angle),
|
||||
health: *health,
|
||||
team: *team,
|
||||
ty: BuildingType::from_building(building),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
// 1 bits reserved
|
||||
// 2 bits reserved
|
||||
// 3 bits for type
|
||||
// 10 bits for health
|
||||
let team_type_health = ((self.team as u16) << 13) + ((self.ty as u16) << 10) + self.health;
|
||||
let combined_bytes = team_type_health.to_le_bytes();
|
||||
|
||||
[
|
||||
x[0],
|
||||
x[1],
|
||||
|
|
@ -125,24 +376,24 @@ impl PlayerState {
|
|||
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 team_type_health = u16::from_le_bytes([bytes[4], bytes[5]]);
|
||||
let health = team_type_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 team = Team::new(team_type_health >> 13);
|
||||
let ty = BuildingType::new((team_type_health >> 10) as u8 & 7);
|
||||
|
||||
PlayerState {
|
||||
BuildingState {
|
||||
position: VectorXY { x, y },
|
||||
angle,
|
||||
health,
|
||||
team,
|
||||
class,
|
||||
ty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_packing() {
|
||||
fn test_building_packing() {
|
||||
use tf_demo_parser::demo::vector::Vector;
|
||||
|
||||
let world = World {
|
||||
|
|
@ -158,7 +409,7 @@ fn test_packing() {
|
|||
},
|
||||
};
|
||||
|
||||
let input = PlayerState {
|
||||
let input = BuildingState {
|
||||
position: VectorXY {
|
||||
x: 100.0,
|
||||
y: -5000.0,
|
||||
|
|
@ -166,15 +417,15 @@ fn test_packing() {
|
|||
angle: Angle::from(213.0),
|
||||
health: 250,
|
||||
team: Team::Blue,
|
||||
class: Class::Demoman,
|
||||
ty: BuildingType::Level1Sentry,
|
||||
};
|
||||
|
||||
let bytes = input.pack(&world);
|
||||
|
||||
let unpacked = PlayerState::unpack(bytes, &world);
|
||||
let unpacked = BuildingState::unpack(bytes, &world);
|
||||
assert_eq!(input.angle, unpacked.angle);
|
||||
assert_eq!(input.health, unpacked.health);
|
||||
assert_eq!(input.class, unpacked.class);
|
||||
assert_eq!(input.ty, unpacked.ty);
|
||||
assert_eq!(input.team, unpacked.team);
|
||||
|
||||
assert!(f32::abs(input.position.x - unpacked.position.x) < 0.5);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue