Big update

This repository is no longer meant for just radarflow, thus it will be renamed.
I have split the SDK from radarflow, allowing for simpler use with new projects.
Other than that, radarflow is functionally the same.

- Fixed bug in radarflow where the entity loop didn't include the last entity.
This commit is contained in:
Janek 2023-12-30 18:07:55 +01:00
parent 462cfddfef
commit 45bba35a71
85 changed files with 6982 additions and 1036 deletions

5
.gitignore vendored

@ -1,4 +1 @@
/target
/src/sdk/cs2dumper/client.rs
/src/sdk/cs2dumper/engine2.rs
/src/sdk/cs2dumper/offsets.rs
/target

515
Cargo.lock generated

@ -33,8 +33,8 @@ dependencies = [
"abi_stable_shared",
"as_derive_utils",
"core_extensions",
"proc-macro2 1.0.71",
"quote 1.0.33",
"proc-macro2",
"quote",
"rustc_version 0.2.3",
"syn 1.0.109",
"typed-arena",
@ -66,9 +66,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.6"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
dependencies = [
"cfg-if",
"once_cell",
@ -76,36 +76,12 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.5"
@ -156,9 +132,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.76"
version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355"
checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9"
[[package]]
name = "as_derive_utils"
@ -167,8 +143,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a26fa495cefb8c86d9ce183b3f39ad11678e54fb3c20e6b7dbd87770811d9b"
dependencies = [
"core_extensions",
"proc-macro2 1.0.71",
"quote 1.0.33",
"proc-macro2",
"quote",
"syn 1.0.109",
]
@ -178,9 +154,9 @@ version = "0.1.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -345,8 +321,8 @@ dependencies = [
"itertools 0.10.5",
"lazy_static",
"proc-macro-crate",
"proc-macro2 1.0.71",
"quote 1.0.33",
"proc-macro2",
"quote",
"syn 1.0.109",
]
@ -357,30 +333,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf28b8c74a050973c9972edfad2f32f404bc1ff6725e37d003e7d55504dec1cf"
dependencies = [
"cglue-gen",
"proc-macro2 1.0.71",
"quote 1.0.33",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "chrono"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.48.5",
]
[[package]]
name = "clap"
version = "4.4.11"
version = "4.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2"
checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d"
dependencies = [
"clap_builder",
"clap_derive",
@ -388,9 +350,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.4.11"
version = "4.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb"
checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9"
dependencies = [
"anstream",
"anstyle",
@ -404,10 +366,10 @@ version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
dependencies = [
"heck 0.4.1",
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"heck",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -486,9 +448,9 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
version = "0.5.9"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5"
checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2"
dependencies = [
"cfg-if",
"crossbeam-utils",
@ -496,9 +458,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.17"
version = "0.8.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f"
checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
dependencies = [
"cfg-if",
]
@ -513,6 +475,21 @@ dependencies = [
"typenum",
]
[[package]]
name = "csflow"
version = "0.1.0"
dependencies = [
"clap",
"dataview 1.0.1",
"enum-primitive-derive",
"log",
"memflow",
"num-traits",
"reqwest",
"serde",
"thiserror",
]
[[package]]
name = "darling"
version = "0.20.3"
@ -531,10 +508,10 @@ checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
dependencies = [
"fnv",
"ident_case",
"proc-macro2 1.0.71",
"quote 1.0.33",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.42",
"syn 2.0.43",
]
[[package]]
@ -544,8 +521,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core",
"quote 1.0.33",
"syn 2.0.42",
"quote",
"syn 2.0.43",
]
[[package]]
@ -637,23 +614,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e"
dependencies = [
"num-traits",
"quote 1.0.33",
"quote",
"syn 1.0.109",
]
[[package]]
name = "env_logger"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
dependencies = [
"humantime",
"is-terminal",
"log",
"regex",
"termcolor",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@ -676,17 +640,6 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
name = "field_types"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "152ff4498a8c01b91737676420a1cd84e92724cb610320fdebee6838e4651c9a"
dependencies = [
"heck 0.3.3",
"quote 0.6.13",
"syn 0.15.44",
]
[[package]]
name = "fixed-slice-vec"
version = "0.10.0"
@ -725,57 +678,45 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.29"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.29"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-io"
version = "0.3.29"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
[[package]]
name = "futures-macro"
version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
]
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-sink"
version = "0.3.29"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "futures-task"
version = "0.3.29"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
[[package]]
name = "futures-util"
version = "0.3.29"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
@ -860,15 +801,6 @@ dependencies = [
"allocator-api2",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "heck"
version = "0.4.1"
@ -921,12 +853,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
version = "0.14.28"
@ -964,29 +890,6 @@ dependencies = [
"tokio-native-tls",
]
[[package]]
name = "iana-time-zone"
version = "0.1.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "ident_case"
version = "1.0.1"
@ -1039,17 +942,6 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "is-terminal"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi",
"rustix 0.38.28",
"windows-sys 0.48.0",
]
[[package]]
name = "itertools"
version = "0.10.5"
@ -1174,9 +1066,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "memchr"
version = "2.6.4"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "memflow"
@ -1205,7 +1097,7 @@ dependencies = [
"rangemap",
"serde",
"smallvec",
"toml 0.8.8",
"toml",
"x86_64",
]
@ -1217,9 +1109,9 @@ checksum = "d766f6681f968c92eb0359fc4bc99039ebe2568df4bb884c7cb7b16023e94d32"
dependencies = [
"darling",
"proc-macro-crate",
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -1305,8 +1197,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4"
dependencies = [
"either",
"proc-macro2 1.0.71",
"quote 1.0.33",
"proc-macro2",
"quote",
"serde",
"syn 1.0.109",
]
@ -1356,9 +1248,9 @@ dependencies = [
[[package]]
name = "object"
version = "0.32.1"
version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [
"memchr",
]
@ -1390,9 +1282,9 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -1511,9 +1403,9 @@ version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -1554,20 +1446,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro-crate"
version = "2.0.0"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a"
dependencies = [
"toml_edit 0.20.7",
]
[[package]]
name = "proc-macro2"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
dependencies = [
"unicode-xid",
"toml_datetime",
"toml_edit",
]
[[package]]
@ -1579,48 +1463,30 @@ 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.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2 1.0.71",
"proc-macro2",
]
[[package]]
name = "radarflow2"
version = "0.1.1"
name = "radarflow-leech"
version = "0.1.0"
dependencies = [
"anyhow",
"axum",
"chrono",
"clap",
"dataview 1.0.1",
"enum-primitive-derive",
"env_logger",
"field_types",
"futures-util",
"csflow",
"local-ip-address",
"log",
"memflow",
"num-traits",
"reqwest",
"serde",
"serde_json",
"simple_logger",
"tokio",
"tokio-timerfd",
"toml 0.7.8",
"tower",
"tower-http",
"vergen",
@ -1691,35 +1557,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "repr_offset"
version = "0.2.2"
@ -1832,11 +1669,11 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "schannel"
version = "0.1.22"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
@ -1860,9 +1697,9 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -1924,9 +1761,9 @@ version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -1993,9 +1830,9 @@ dependencies = [
[[package]]
name = "simple_logger"
version = "4.3.0"
version = "4.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0ca6504625ee1aa5fda33913d2005eab98c7a42dd85f116ecce3ff54c9d3ef"
checksum = "8e7e46c8c90251d47d08b28b8a419ffb4aede0f87c2eea95e17d1d5bacbf3ef1"
dependencies = [
"colored",
"log",
@ -2034,36 +1871,25 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "0.15.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
dependencies = [
"proc-macro2 0.4.30",
"quote 0.6.13",
"unicode-xid",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.42"
version = "2.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8"
checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"proc-macro2",
"quote",
"unicode-ident",
]
@ -2116,44 +1942,35 @@ checksum = "88da97cd34718f47df2adae0c2310ee305e061c794b9c07fd33d8387f4ee2e1c"
[[package]]
name = "tempfile"
version = "3.8.1"
version = "3.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
dependencies = [
"cfg-if",
"fastrand",
"redox_syscall 0.4.1",
"rustix 0.38.28",
"windows-sys 0.48.0",
]
[[package]]
name = "termcolor"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
dependencies = [
"winapi-util",
"windows-sys 0.52.0",
]
[[package]]
name = "thiserror"
version = "1.0.51"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7"
checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.51"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -2236,9 +2053,9 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
@ -2292,66 +2109,30 @@ dependencies = [
[[package]]
name = "toml"
version = "0.7.8"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.19.15",
]
[[package]]
name = "toml"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.21.0",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.19.15"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "toml_edit"
version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
]
[[package]]
name = "toml_edit"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
dependencies = [
"indexmap",
"serde",
@ -2515,18 +2296,6 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
[[package]]
name = "url"
version = "2.5.0"
@ -2615,9 +2384,9 @@ dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
"wasm-bindgen-shared",
]
@ -2639,7 +2408,7 @@ version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
dependencies = [
"quote 1.0.33",
"quote",
"wasm-bindgen-macro-support",
]
@ -2649,9 +2418,9 @@ version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -2688,30 +2457,12 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
@ -2846,9 +2597,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "winnow"
version = "0.5.30"
version = "0.5.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b5c3db89721d50d0e2a673f5043fc4722f76dcc352d7b1ab8b8288bed4ed2c5"
checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c"
dependencies = [
"memchr",
]
@ -2890,7 +2641,7 @@ version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2 1.0.71",
"quote 1.0.33",
"syn 2.0.42",
"proc-macro2",
"quote",
"syn 2.0.43",
]

@ -1,46 +1,3 @@
[package]
name = "radarflow2"
version = "0.1.1"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# dma and memory
memflow = "0.2.0"
dataview = "1.0.1"
# logging
log = "0.4.19"
env_logger = "0.10.0"
# error handling
anyhow = "1.0.72"
# tokio
tokio = { version = "1.29.1", features = ["full"] }
field_types = "1.1.0"
futures-util = "0.3.28"
# serde
serde = { version = "1.0.181", features = ["derive"] }
serde_json = "1.0.104"
toml = "0.7.6"
# networking
axum = { version = "0.6.20", features = ["ws"] }
tower-http = { version = "0.4.3", features = ["fs"] }
tower = "0.4.13"
tokio-timerfd = "0.2.0"
# other
local-ip-address = "0.5.4"
enum-primitive-derive = "0.2.2"
num-traits = "0.2.16"
clap = { version = "4.3.19", features = ["derive", "string"] }
simple_logger = "4.2.0"
chrono = "0.4.26"
[build-dependencies]
reqwest = { version = "0.11.18", features = ["blocking"] }
vergen = { version = "8.0.0", features = ["build", "cargo", "git", "gitcl", "rustc", "si"] }
[workspace]
members = ["csflow", "radarflow-leech"]
resolver = "2"

@ -1,23 +1,15 @@
# radarflow2
A Web radar for CS2 using [memflow](https://github.com/memflow/memflow)
# cs2-memflow-cheats
### What is this?
This is a repository for my CS2 cheats which utilize [memflow](https://github.com/memflow/memflow).
## How can I run this?
First, you need to set up a virtual machine on linux using qemu.
As of now, memflow's pcileech connector is not supported/tested.
### Contents
[csflow](csflow/README.md) - Rust library for creating CS2 cheats utilizing memflow
[radarflow](radarflow/README.md) - A Web radar for CS2 utilizing memflow
How to set up a VM on linux is way out of scope for this. You can find plenty of information online on how to do it.
Before you begin, install the necessary memflow plugins using memflowup from the *dev channel!*
Now you can clone this repository on your host:
`git clone https://github.com/superyu1337/radarflow2.git`
Now you can run radarflow:
`cargo run --release`
For an overview of CLI commands, run this:
`cargo run --release -- --help`
## Detection Status
VAC: ✅ (Undetected)
FaceIt: ❓ (Unknown, could work with proper spoofing)
ESEA: ❓ (Unknown, could work with proper spoofing)
### Todo
- csflow
- [] Documentation
- [ ] Test with pcileech hardware
- radarflow
- [ ] Test with pcileech hardware
- [ ] More useful logging, maybe a TUI to write statistics?

1912
csflow/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

28
csflow/Cargo.toml Normal file

@ -0,0 +1,28 @@
[package]
name = "csflow"
version = "0.1.1"
authors = ["Janek S <development@superyu.xyz>"]
edition = "2021"
description = "SDK for CS2 cheats utilizing memflow"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# memory
memflow = "0.2.0"
dataview = "1.0.1"
# logging
log = "0.4.19"
# error handling
thiserror = "1.0.52"
# derive stuff
enum-primitive-derive = "0.2.2"
num-traits = "0.2.16"
serde = { version = "1.0.181", features = ["derive"] }
clap = { version = "4.3.19", features = ["derive", "string"] }
[build-dependencies]
reqwest = { version = "0.11.18", features = ["blocking"] }

2
csflow/README.md Normal file

@ -0,0 +1,2 @@
# csflow
SDK for CS2 cheats utilizing [memflow](https://github.com/memflow/memflow)

@ -1,5 +1,4 @@
use std::error::Error;
use vergen::EmitBuilder;
fn download(url: &str, to: &str) -> Result<(), Box<dyn Error>> {
let content = reqwest::blocking::get(url)
@ -17,26 +16,18 @@ fn main() -> Result<(), Box<dyn Error>> {
download(
"https://raw.githubusercontent.com/a2x/cs2-dumper/main/generated/client.dll.rs",
"./src/sdk/cs2dumper/client.rs"
"./src/cs2dumper/client.rs"
).expect("Failed to download build file \"client.dll.rs\"");
download(
"https://raw.githubusercontent.com/a2x/cs2-dumper/main/generated/offsets.rs",
"./src/sdk/cs2dumper/offsets.rs"
"./src/cs2dumper/offsets.rs"
).expect("Failed to download build file \"offsets.rs\"");
download(
"https://raw.githubusercontent.com/a2x/cs2-dumper/main/generated/engine2.dll.rs",
"./src/sdk/cs2dumper/engine2.rs"
"./src/cs2dumper/engine2.rs"
).expect("Failed to download build file \"engine2.dll.rs\"");
EmitBuilder::builder()
.git_sha(true)
.git_commit_date()
.cargo_debug()
.cargo_target_triple()
.rustc_semver()
.rustc_llvm_version()
.emit()?;
Ok(())
}

130
csflow/src/context.rs Normal file

@ -0,0 +1,130 @@
use memflow::{plugins::{IntoProcessInstanceArcBox, Inventory, ConnectorArgs, args::Args}, os::{ModuleInfo, Os, Process}, mem::MemoryView, types::Address};
use crate::{error::Error, structs::{CPlayerController, CBaseEntity}, cs2dumper, traits::MemoryClass};
pub struct CheatCtx {
pub process: IntoProcessInstanceArcBox<'static>,
pub client_module: ModuleInfo,
pub engine_module: ModuleInfo,
}
impl CheatCtx {
fn check_version(&mut self) -> Result<(), Error> {
let game_build_number: u32 = self.process.read(self.engine_module.base + cs2dumper::offsets::engine2_dll::dwBuildNumber)?;
let offset_build_number = cs2dumper::offsets::game_info::buildNumber;
if game_build_number as usize != offset_build_number {
return Err(Error::GameVersionMismatch(game_build_number as usize, offset_build_number))
}
Ok(())
}
pub fn setup(connector: Connector, pcileech_device: String) -> Result<CheatCtx, Error> {
let inventory = Inventory::scan();
let os = {
if connector == Connector::Pcileech {
let args = Args::new()
.insert("device", &pcileech_device);
let connector_args = ConnectorArgs::new(None, args, None);
inventory.builder()
.connector(&connector.to_string())
.args(connector_args)
.os("win32")
.build()?
} else {
inventory.builder()
.connector(&connector.to_string())
.os("win32")
.build()?
}
};
let mut process = os.into_process_by_name("cs2.exe")?;
let client_module = process.module_by_name("client.dll")?;
let engine_module = process.module_by_name("engine2.dll")?;
let mut ctx = Self {
process,
client_module,
engine_module,
};
ctx.check_version()?;
Ok(ctx)
}
pub fn get_local(&mut self) -> Result<CPlayerController, Error> {
let ptr = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwLocalPlayerController)?;
Ok(CPlayerController::new(ptr))
}
pub fn get_plantedc4(&mut self) -> Result<CBaseEntity, Error> {
let ptr = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwPlantedC4)?;
let ptr2 = self.process.read_addr64(ptr)?;
Ok(CBaseEntity::new(ptr2))
}
pub fn is_bomb_planted(&mut self) -> Result<bool, Error> {
let game_rules = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGameRules)?;
let data: u8 = self.process.read(game_rules + cs2dumper::client::C_CSGameRules::m_bBombPlanted)?;
Ok(data != 0)
}
pub fn is_bomb_dropped(&mut self) -> Result<bool, Error> {
let game_rules = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGameRules)?;
let data: u8 = self.process.read(game_rules + cs2dumper::client::C_CSGameRules::m_bBombDropped)?;
Ok(data != 0)
}
pub fn get_entity_list(&mut self) -> Result<Address, Error> {
let ptr = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwEntityList)?;
Ok(ptr)
}
pub fn get_globals(&mut self) -> Result<Address, Error> {
let ptr = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGlobalVars)?;
Ok(ptr)
}
pub fn map_name(&mut self, global_vars: Address) -> Result<String, Error> {
let ptr = self.process.read_addr64(global_vars + 0x188)?;
Ok(self.process.read_char_string_n(ptr, 32)?)
}
pub fn highest_entity_index(&mut self) -> Result<i32, Error> {
let game_entity_system = self.process.read_addr64(self.client_module.base + cs2dumper::offsets::client_dll::dwGameEntitySystem)?;
let highest_index = self.process.read(game_entity_system + cs2dumper::offsets::client_dll::dwGameEntitySystem_getHighestEntityIndex)?;
Ok(highest_index)
}
pub fn network_is_ingame(&mut self) -> Result<bool, Error> {
let ptr = self.process.read_addr64(self.engine_module.base + cs2dumper::offsets::engine2_dll::dwNetworkGameClient)?;
let signonstate: i32 = self.process.read(ptr + cs2dumper::offsets::engine2_dll::dwNetworkGameClient_signOnState)?;
Ok(signonstate == 6)
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum, Default)]
pub enum Connector {
#[default]
Qemu,
Kvm,
Pcileech
}
impl ToString for Connector {
fn to_string(&self) -> String {
match self {
Connector::Qemu => String::from("qemu"),
Connector::Kvm => String::from("kvm"),
Connector::Pcileech => String::from("pcileech"),
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,244 @@
/*
* Created using https://github.com/a2x/cs2-dumper
* Sat, 30 Dec 2023 03:17:25 +0000
*/
#![allow(non_snake_case, non_upper_case_globals)]
pub mod CEmptyEntityInstance {
}
pub mod CEntityComponent {
}
pub mod CEntityComponentHelper {
pub const m_flags: usize = 0x8; // uint32_t
pub const m_pInfo: usize = 0x10; // EntComponentInfo_t*
pub const m_nPriority: usize = 0x18; // int32_t
pub const m_pNext: usize = 0x20; // CEntityComponentHelper*
}
pub mod CEntityIOOutput {
pub const m_Value: usize = 0x18; // CVariantBase<CVariantDefaultAllocator>
}
pub mod CEntityIdentity {
pub const m_nameStringableIndex: usize = 0x14; // int32_t
pub const m_name: usize = 0x18; // CUtlSymbolLarge
pub const m_designerName: usize = 0x20; // CUtlSymbolLarge
pub const m_flags: usize = 0x30; // uint32_t
pub const m_worldGroupId: usize = 0x38; // WorldGroupId_t
pub const m_fDataObjectTypes: usize = 0x3C; // uint32_t
pub const m_PathIndex: usize = 0x40; // ChangeAccessorFieldPathIndex_t
pub const m_pPrev: usize = 0x58; // CEntityIdentity*
pub const m_pNext: usize = 0x60; // CEntityIdentity*
pub const m_pPrevByClass: usize = 0x68; // CEntityIdentity*
pub const m_pNextByClass: usize = 0x70; // CEntityIdentity*
}
pub mod CEntityInstance {
pub const m_iszPrivateVScripts: usize = 0x8; // CUtlSymbolLarge
pub const m_pEntity: usize = 0x10; // CEntityIdentity*
pub const m_CScriptComponent: usize = 0x28; // CScriptComponent*
}
pub mod CNetworkVarChainer {
pub const m_PathIndex: usize = 0x20; // ChangeAccessorFieldPathIndex_t
}
pub mod CScriptComponent { // CEntityComponent
pub const m_scriptClassName: usize = 0x30; // CUtlSymbolLarge
}
pub mod CVariantDefaultAllocator {
}
pub mod EngineLoopState_t {
pub const m_nPlatWindowWidth: usize = 0x18; // int32_t
pub const m_nPlatWindowHeight: usize = 0x1C; // int32_t
pub const m_nRenderWidth: usize = 0x20; // int32_t
pub const m_nRenderHeight: usize = 0x24; // int32_t
}
pub mod EntComponentInfo_t {
pub const m_pName: usize = 0x0; // char*
pub const m_pCPPClassname: usize = 0x8; // char*
pub const m_pNetworkDataReferencedDescription: usize = 0x10; // char*
pub const m_pNetworkDataReferencedPtrPropDescription: usize = 0x18; // char*
pub const m_nRuntimeIndex: usize = 0x20; // int32_t
pub const m_nFlags: usize = 0x24; // uint32_t
pub const m_pBaseClassComponentHelper: usize = 0x60; // CEntityComponentHelper*
}
pub mod EntInput_t {
}
pub mod EntOutput_t {
}
pub mod EventAdvanceTick_t { // EventSimulate_t
pub const m_nCurrentTick: usize = 0x30; // int32_t
pub const m_nCurrentTickThisFrame: usize = 0x34; // int32_t
pub const m_nTotalTicksThisFrame: usize = 0x38; // int32_t
pub const m_nTotalTicks: usize = 0x3C; // int32_t
}
pub mod EventAppShutdown_t {
pub const m_nDummy0: usize = 0x0; // int32_t
}
pub mod EventClientAdvanceTick_t { // EventAdvanceTick_t
}
pub mod EventClientFrameSimulate_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_flRealTime: usize = 0x28; // float
pub const m_flFrameTime: usize = 0x2C; // float
}
pub mod EventClientOutput_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_flRenderTime: usize = 0x28; // float
pub const m_flRealTime: usize = 0x2C; // float
pub const m_flRenderFrameTimeUnbounded: usize = 0x30; // float
pub const m_bRenderOnly: usize = 0x34; // bool
}
pub mod EventClientPauseSimulate_t { // EventSimulate_t
}
pub mod EventClientPollInput_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_flRealTime: usize = 0x28; // float
}
pub mod EventClientPollNetworking_t {
pub const m_nTickCount: usize = 0x0; // int32_t
}
pub mod EventClientPostAdvanceTick_t { // EventPostAdvanceTick_t
}
pub mod EventClientPostOutput_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_flRenderTime: usize = 0x28; // double
pub const m_flRenderFrameTime: usize = 0x30; // float
pub const m_flRenderFrameTimeUnbounded: usize = 0x34; // float
pub const m_bRenderOnly: usize = 0x38; // bool
}
pub mod EventClientPostSimulate_t { // EventSimulate_t
}
pub mod EventClientPreOutput_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_flRenderTime: usize = 0x28; // double
pub const m_flRenderFrameTime: usize = 0x30; // double
pub const m_flRenderFrameTimeUnbounded: usize = 0x38; // double
pub const m_flRealTime: usize = 0x40; // float
pub const m_bRenderOnly: usize = 0x44; // bool
}
pub mod EventClientPreSimulate_t { // EventSimulate_t
}
pub mod EventClientPredictionPostNetupdate_t {
}
pub mod EventClientProcessGameInput_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_flRealTime: usize = 0x28; // float
pub const m_flFrameTime: usize = 0x2C; // float
}
pub mod EventClientProcessInput_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_flRealTime: usize = 0x28; // float
pub const m_flTickInterval: usize = 0x2C; // float
pub const m_flTickStartTime: usize = 0x30; // double
}
pub mod EventClientProcessNetworking_t {
}
pub mod EventClientSceneSystemThreadStateChange_t {
pub const m_bThreadsActive: usize = 0x0; // bool
}
pub mod EventClientSendInput_t {
pub const m_bFinalClientCommandTick: usize = 0x0; // bool
pub const m_nAdditionalClientCommandsToCreate: usize = 0x4; // int32_t
}
pub mod EventClientSimulate_t { // EventSimulate_t
}
pub mod EventFrameBoundary_t {
pub const m_flFrameTime: usize = 0x0; // float
}
pub mod EventModInitialized_t {
}
pub mod EventPostAdvanceTick_t { // EventSimulate_t
pub const m_nCurrentTick: usize = 0x30; // int32_t
pub const m_nCurrentTickThisFrame: usize = 0x34; // int32_t
pub const m_nTotalTicksThisFrame: usize = 0x38; // int32_t
pub const m_nTotalTicks: usize = 0x3C; // int32_t
}
pub mod EventPostDataUpdate_t {
pub const m_nCount: usize = 0x0; // int32_t
}
pub mod EventPreDataUpdate_t {
pub const m_nCount: usize = 0x0; // int32_t
}
pub mod EventProfileStorageAvailable_t {
pub const m_nSplitScreenSlot: usize = 0x0; // CSplitScreenSlot
}
pub mod EventServerAdvanceTick_t { // EventAdvanceTick_t
}
pub mod EventServerPollNetworking_t { // EventSimulate_t
}
pub mod EventServerPostAdvanceTick_t { // EventPostAdvanceTick_t
}
pub mod EventServerPostSimulate_t { // EventSimulate_t
}
pub mod EventServerProcessNetworking_t { // EventSimulate_t
}
pub mod EventServerSimulate_t { // EventSimulate_t
}
pub mod EventSetTime_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_nClientOutputFrames: usize = 0x28; // int32_t
pub const m_flRealTime: usize = 0x30; // double
pub const m_flRenderTime: usize = 0x38; // double
pub const m_flRenderFrameTime: usize = 0x40; // double
pub const m_flRenderFrameTimeUnbounded: usize = 0x48; // double
pub const m_flRenderFrameTimeUnscaled: usize = 0x50; // double
pub const m_flTickRemainder: usize = 0x58; // double
}
pub mod EventSimpleLoopFrameUpdate_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_flRealTime: usize = 0x28; // float
pub const m_flFrameTime: usize = 0x2C; // float
}
pub mod EventSimulate_t {
pub const m_LoopState: usize = 0x0; // EngineLoopState_t
pub const m_bFirstTick: usize = 0x28; // bool
pub const m_bLastTick: usize = 0x29; // bool
}
pub mod EventSplitScreenStateChanged_t {
}

@ -0,0 +1,51 @@
/*
* Created using https://github.com/a2x/cs2-dumper
* Sat, 30 Dec 2023 03:17:26 +0000
*/
#![allow(non_snake_case, non_upper_case_globals)]
pub mod client_dll { // client.dll
pub const dwEntityList: usize = 0x17C1950;
pub const dwForceAttack: usize = 0x16C1E70;
pub const dwForceAttack2: usize = 0x16C1F00;
pub const dwForceBackward: usize = 0x16C2140;
pub const dwForceCrouch: usize = 0x16C2410;
pub const dwForceForward: usize = 0x16C20B0;
pub const dwForceJump: usize = 0x16C2380;
pub const dwForceLeft: usize = 0x16C21D0;
pub const dwForceRight: usize = 0x16C2260;
pub const dwGameEntitySystem: usize = 0x18ED250;
pub const dwGameEntitySystem_getHighestEntityIndex: usize = 0x1510;
pub const dwGameRules: usize = 0x181E048;
pub const dwGlobalVars: usize = 0x16BDC98;
pub const dwGlowManager: usize = 0x181D7B0;
pub const dwInterfaceLinkList: usize = 0x191AEE8;
pub const dwLocalPlayerController: usize = 0x1810F48;
pub const dwLocalPlayerPawn: usize = 0x16C8F38;
pub const dwPlantedC4: usize = 0x1824A88;
pub const dwPrediction: usize = 0x16C8E00;
pub const dwSensitivity: usize = 0x181ED48;
pub const dwSensitivity_sensitivity: usize = 0x40;
pub const dwViewAngles: usize = 0x1880DC0;
pub const dwViewMatrix: usize = 0x1820150;
pub const dwViewRender: usize = 0x1820998;
}
pub mod engine2_dll { // engine2.dll
pub const dwBuildNumber: usize = 0x4E03D4;
pub const dwNetworkGameClient: usize = 0x4DF988;
pub const dwNetworkGameClient_getLocalPlayer: usize = 0xF0;
pub const dwNetworkGameClient_maxClients: usize = 0x250;
pub const dwNetworkGameClient_signOnState: usize = 0x240;
pub const dwWindowHeight: usize = 0x596E1C;
pub const dwWindowWidth: usize = 0x596E18;
}
pub mod game_info { // Some additional information about the game at dump time
pub const buildNumber: usize = 0x369F; // Game build number
}
pub mod inputsystem_dll { // inputsystem.dll
pub const dwInputSystem: usize = 0x35760;
}

5
csflow/src/enums/mod.rs Normal file

@ -0,0 +1,5 @@
mod player_type;
mod teamid;
pub use player_type::PlayerType;
pub use teamid::TeamID;

@ -0,0 +1,9 @@
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, Default, PartialEq)]
pub enum PlayerType {
#[default]
Unknown,
Spectator,
Local,
Enemy,
Team
}

@ -0,0 +1,7 @@
#[repr(i32)]
#[derive(Debug, Eq, PartialEq, enum_primitive_derive::Primitive)]
pub enum TeamID {
Spectator = 1,
T = 2,
CT = 3
}

33
csflow/src/error.rs Normal file

@ -0,0 +1,33 @@
use memflow::types::Address;
use thiserror::Error;
use crate::structs::Vec3;
#[derive(Error, Debug)]
pub enum Error {
/// Game version mismatch.
/// First arg is the game version, second is the offset version.
#[error("version mismatch, game has version {0}, but offsets have version {1}")]
GameVersionMismatch(usize, usize),
#[error("memflow error: {0}")]
Memflow(#[from] memflow::error::Error),
#[error("memflow partial error when reading address: {0}")]
MemflowPartialAddress(#[from] memflow::error::PartialError<Address>),
#[error("memflow partial error when reading Vec3: {0}")]
MemflowPartialVec3(#[from] memflow::error::PartialError<Vec3>),
#[error("memflow partial error when reading String: {0}")]
MemflowPartialString(#[from] memflow::error::PartialError<String>),
#[error("memflow partial error when reading i32: {0}")]
MemflowPartiali32(#[from] memflow::error::PartialError<i32>),
#[error("memflow partial error when reading u32: {0}")]
MemflowPartialu32(#[from] memflow::error::PartialError<u32>),
#[error("memflow partial error when reading u8: {0}")]
MemflowPartialu8(#[from] memflow::error::PartialError<u8>)
}

14
csflow/src/lib.rs Normal file

@ -0,0 +1,14 @@
#![allow(dead_code)]
mod cs2dumper;
mod context;
mod error;
pub mod structs;
pub mod traits;
pub mod enums;
pub use context::*;
pub use error::Error;
pub use memflow::prelude as memflow;

@ -1,8 +1,5 @@
use memflow::{types::Address, mem::MemoryView};
use anyhow::Result;
use crate::{dma::CheatCtx, structs::Vec3, sdk::{cs2dumper, structs::{BaseEntity, MemoryClass}}};
use super::CPlayerController;
use crate::{CheatCtx, Error, cs2dumper, traits::{BaseEntity, MemoryClass}, structs::Vec3};
pub struct CBaseEntity(Address);
@ -17,7 +14,7 @@ impl MemoryClass for CBaseEntity {
}
impl BaseEntity for CBaseEntity {
fn from_index(ctx: &mut CheatCtx, entity_list: Address, index: i32) -> Result<Option<CBaseEntity>> {
fn from_index(ctx: &mut CheatCtx, entity_list: Address, index: i32) -> Result<Option<CBaseEntity>, Error> {
let list_entry = ctx.process.read_addr64(entity_list + 8 * (index >> 9) + 16)?;
if list_entry.is_null() && !list_entry.is_valid() {
return Ok(None);
@ -31,12 +28,12 @@ impl BaseEntity for CBaseEntity {
Ok(Some(Self::new(player_ptr)))
}
fn pos(&self, ctx: &mut CheatCtx) -> anyhow::Result<Vec3> {
fn pos(&self, ctx: &mut CheatCtx) -> Result<Vec3, Error> {
let node = ctx.process.read_addr64(self.0 + cs2dumper::client::C_BaseEntity::m_pGameSceneNode)?;
Ok(ctx.process.read(node + cs2dumper::client::CGameSceneNode::m_vecAbsOrigin)?)
}
fn class_name(&self, ctx: &mut CheatCtx) -> anyhow::Result<String> {
fn class_name(&self, ctx: &mut CheatCtx) -> Result<String, Error> {
let entity_identity_ptr = ctx.process.read_addr64(self.0 + cs2dumper::client::CEntityInstance::m_pEntity)?;
let class_name_ptr = ctx.process.read_addr64(entity_identity_ptr + cs2dumper::client::CEntityIdentity::m_designerName)?;
Ok(ctx.process.read_char_string_n(class_name_ptr, 32)?)
@ -44,7 +41,7 @@ impl BaseEntity for CBaseEntity {
}
impl CBaseEntity {
pub fn to_player_controller(&self) -> CPlayerController {
CPlayerController::new(self.0)
pub fn to_player_controller(&self) -> super::CPlayerController {
super::CPlayerController::new(self.0)
}
}

@ -0,0 +1,7 @@
mod base_entity;
mod player_controller;
mod player_pawn;
pub use base_entity::CBaseEntity;
pub use player_controller::CPlayerController;
pub use player_pawn::CPlayerPawn;

@ -1,10 +1,7 @@
use memflow::{types::Address, mem::MemoryView};
use anyhow::Result;
use num_traits::FromPrimitive;
use crate::{dma::CheatCtx, structs::{Vec3, communication::PlayerType}, sdk::{cs2dumper, structs::{BaseEntity, MemoryClass, TeamID}}};
use super::CPlayerPawn;
use crate::{CheatCtx, Error, cs2dumper, structs::Vec3, traits::{MemoryClass, BaseEntity}, enums::{TeamID, PlayerType}};
pub struct CPlayerController(Address);
@ -19,7 +16,7 @@ impl MemoryClass for CPlayerController {
}
impl BaseEntity for CPlayerController {
fn from_index(ctx: &mut CheatCtx, entity_list: Address, index: i32) -> Result<Option<CPlayerController>> {
fn from_index(ctx: &mut CheatCtx, entity_list: Address, index: i32) -> Result<Option<CPlayerController>, Error> {
let list_entry = ctx.process.read_addr64(entity_list + 8 * (index >> 9) + 16)?;
if list_entry.is_null() && !list_entry.is_valid() {
return Ok(None);
@ -33,12 +30,12 @@ impl BaseEntity for CPlayerController {
Ok(Some(Self::new(player_ptr)))
}
fn pos(&self, ctx: &mut CheatCtx) -> anyhow::Result<Vec3> {
fn pos(&self, ctx: &mut CheatCtx) -> Result<Vec3, Error> {
let node = ctx.process.read_addr64(self.0 + cs2dumper::client::C_BaseEntity::m_pGameSceneNode)?;
Ok(ctx.process.read(node + cs2dumper::client::CGameSceneNode::m_vecAbsOrigin)?)
}
fn class_name(&self, ctx: &mut CheatCtx) -> anyhow::Result<String> {
fn class_name(&self, ctx: &mut CheatCtx) -> Result<String, Error> {
let entity_identity_ptr = ctx.process.read_addr64(self.0 + cs2dumper::client::CEntityInstance::m_pEntity)?;
let class_name_ptr = ctx.process.read_addr64(entity_identity_ptr + cs2dumper::client::CEntityIdentity::m_designerName)?;
Ok(ctx.process.read_char_string_n(class_name_ptr, 32)?)
@ -46,18 +43,18 @@ impl BaseEntity for CPlayerController {
}
impl CPlayerController {
pub fn get_pawn(&self, ctx: &mut CheatCtx, entity_list: Address) -> Result<Option<CPlayerPawn>> {
pub fn get_pawn(&self, ctx: &mut CheatCtx, entity_list: Address) -> Result<Option<super::CPlayerPawn>, Error> {
let uhandle = ctx.process.read(self.0 + cs2dumper::client::CCSPlayerController::m_hPlayerPawn)?;
CPlayerPawn::from_uhandle(ctx, entity_list, uhandle)
super::CPlayerPawn::from_uhandle(ctx, entity_list, uhandle)
}
// Technically something that should be in the BaseEntity trait, but we are only gonna use it on CPlayerController
pub fn get_team(&self, ctx: &mut CheatCtx) -> Result<Option<TeamID>> {
pub fn get_team(&self, ctx: &mut CheatCtx) -> Result<Option<TeamID>, Error> {
let team_num: i32 = ctx.process.read(self.0 + cs2dumper::client::C_BaseEntity::m_iTeamNum)?;
Ok(TeamID::from_i32(team_num))
}
pub fn get_player_type(&self, ctx: &mut CheatCtx, local: &CPlayerController) -> Result<Option<PlayerType>> {
pub fn get_player_type(&self, ctx: &mut CheatCtx, local: &CPlayerController) -> Result<Option<PlayerType>, Error> {
if self.0 == local.0 {
return Ok(Some(PlayerType::Local))
}

@ -1,12 +1,21 @@
use memflow::{types::Address, mem::MemoryView};
use anyhow::Result;
use crate::{dma::CheatCtx, structs::Vec3, sdk::{cs2dumper, structs::MemoryClass}};
use crate::{Error, CheatCtx, cs2dumper, structs::Vec3, traits::MemoryClass};
pub struct CPlayerPawn(Address);
impl MemoryClass for CPlayerPawn {
fn ptr(&self) -> Address {
self.0
}
fn new(ptr: Address) -> Self {
Self(ptr)
}
}
impl CPlayerPawn {
pub fn from_uhandle(ctx: &mut CheatCtx, entity_list: Address, uhandle: u32) -> Result<Option<Self>> {
pub fn from_uhandle(ctx: &mut CheatCtx, entity_list: Address, uhandle: u32) -> Result<Option<Self>, Error> {
let list_entry = ctx.process.read_addr64(entity_list + 0x8 * ((uhandle & 0x7FFF) >> 9) + 16)?;
if list_entry.is_null() || !list_entry.is_valid() {
@ -18,7 +27,7 @@ impl CPlayerPawn {
}
// Todo: Optimize this function: find another way to do this
pub fn has_c4(&self, ctx: &mut CheatCtx, entity_list: Address) -> Result<bool> {
pub fn has_c4(&self, ctx: &mut CheatCtx, entity_list: Address) -> Result<bool, Error> {
let mut has_c4 = false;
let wep_services = ctx.process.read_addr64(self.0 + cs2dumper::client::C_BasePlayerPawn::m_pWeaponServices)?;
let wep_count: i32 = ctx.process.read(wep_services + cs2dumper::client::CPlayer_WeaponServices::m_hMyWeapons)?;
@ -52,30 +61,20 @@ impl CPlayerPawn {
Ok(has_c4)
}
pub fn pos(&self, ctx: &mut CheatCtx) -> Result<Vec3> {
pub fn pos(&self, ctx: &mut CheatCtx) -> Result<Vec3, Error> {
Ok(ctx.process.read(self.0 + cs2dumper::client::C_BasePlayerPawn::m_vOldOrigin)?)
}
pub fn angles(&self, ctx: &mut CheatCtx) -> Result<Vec3> {
pub fn angles(&self, ctx: &mut CheatCtx) -> Result<Vec3, Error> {
Ok(ctx.process.read(self.0 + cs2dumper::client::C_CSPlayerPawnBase::m_angEyeAngles)?)
}
pub fn health(&self, ctx: &mut CheatCtx) -> Result<u32> {
pub fn health(&self, ctx: &mut CheatCtx) -> Result<u32, Error> {
Ok(ctx.process.read(self.0 + cs2dumper::client::C_BaseEntity::m_iHealth)?)
}
/// Same as ::get_health > 0
pub fn is_alive(&self, ctx: &mut CheatCtx) -> Result<bool> {
pub fn is_alive(&self, ctx: &mut CheatCtx) -> Result<bool, Error> {
Ok(self.health(ctx)? > 0)
}
}
impl MemoryClass for CPlayerPawn {
fn ptr(&self) -> Address {
self.0
}
fn new(ptr: Address) -> Self {
Self(ptr)
}
}

@ -0,0 +1,5 @@
mod vec3;
mod entity;
pub use vec3::Vec3;
pub use entity::{CBaseEntity, CPlayerController, CPlayerPawn};

@ -0,0 +1,11 @@
use memflow::types::Address;
use crate::{CheatCtx, structs::Vec3, Error};
/// A trait for basic functions from C_BaseEntity
/// CCSPlayerController inherits C_BaseEntity, which is why this trait exists.
pub trait BaseEntity {
fn from_index(ctx: &mut CheatCtx, entity_list: Address, index: i32) -> Result<Option<Self>, Error> where Self: std::marker::Sized;
fn pos(&self, ctx: &mut CheatCtx) -> Result<Vec3, Error>;
fn class_name(&self, ctx: &mut CheatCtx) -> Result<String, Error>;
}

@ -0,0 +1,7 @@
use memflow::types::Address;
/// A trait that implements basic functions for a class represented by a single pointer
pub trait MemoryClass {
fn ptr(&self) -> Address;
fn new(ptr: Address) -> Self;
}

5
csflow/src/traits/mod.rs Normal file

@ -0,0 +1,5 @@
mod base_entity;
mod memory_class;
pub use base_entity::BaseEntity;
pub use memory_class::MemoryClass;

40
radarflow/Cargo.toml Normal file

@ -0,0 +1,40 @@
[package]
name = "radarflow"
version = "0.2.0"
authors = ["Janek S <development@superyu.xyz>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
csflow = { path = "../csflow" }
# cli
clap = { version = "4.3.19", features = ["derive", "string"] }
# tokio
tokio = { version = "1.29.1", features = ["full"] }
tokio-timerfd = "0.2.0"
# serde
serde = { version = "1.0.181", features = ["derive"] }
serde_json = "1.0.104"
# networking
axum = { version = "0.6.20", features = ["ws"] }
tower-http = { version = "0.4.3", features = ["fs"] }
tower = "0.4.13"
local-ip-address = "0.5.4"
# other
# error handling
anyhow = "1.0.77"
# logging
log = "0.4.19"
simple_logger = "4.2.0"
[build-dependencies]
vergen = { version = "8.0.0", features = ["build", "cargo", "git", "gitcl", "rustc", "si"] }

44
radarflow/README.md Normal file

@ -0,0 +1,44 @@
# radarflow
A Web radar for CS2 using [memflow](https://github.com/memflow/memflow)
## How can I run this?
There is two ways to run this, first way is using a KVM/QEMU setup to target a running VM to read memory out of it. The second way is using pcileech hardware, like a PCIe Screamer.
> [!NOTE]
> The pcileech method is untested. However, I have ordered hardware, and will test soon.
### The KVM/QEMU method
First, you need to set up a virtual machine on linux using qemu.
How to set up a VM on linux is way out of scope for this. You can find plenty of information online on how to do it.
Before you begin, install the necessary memflow plugins using memflowup from the *stable 0.2.0 channel!*
Clone the repo on your vm host:
`git clone https://github.com/superyu1337/radarflow2.git`
Run radarflow:
`cargo run --release`
For an overview of CLI commands, run this:
`cargo run --release -- --help`
### The pcileech method
> [!WARNING]
> The pcileech method is untested.
Install your pcileech hardware in your target pc. On your attacking pc, install the necessary memflow plugins using memflowup from the *stable 0.2.0 channel!*
Clone the repo on your attacking pc:
`git clone https://github.com/superyu1337/radarflow2.git`
Run radarflow:
`cargo run --release`
For an overview of CLI commands, run this:
`cargo run --release -- --help`
## Detection Status
VAC: ✅ (Undetected)
FaceIt: ❓ (Unknown, could work with proper spoofing on pcileech method)
ESEA: ❓ (Unknown, could work with proper spoofing on pcileech method)

14
radarflow/build.rs Normal file

@ -0,0 +1,14 @@
use std::error::Error;
use vergen::EmitBuilder;
fn main() -> Result<(), Box<dyn Error>> {
EmitBuilder::builder()
.git_sha(true)
.git_commit_date()
.cargo_debug()
.cargo_target_triple()
.rustc_semver()
.rustc_llvm_version()
.emit()?;
Ok(())
}

@ -1,9 +1,7 @@
use std::path::PathBuf;
use clap::Parser;
use memflow::prelude::Inventory;
use crate::structs::{Connector, Loglevel};
use clap::{Parser, ValueEnum};
use csflow::{Connector, memflow::Inventory};
const PORT_RANGE: std::ops::RangeInclusive<usize> = 8000..=65535;
const POLL_RANGE: std::ops::RangeInclusive<usize> = 1..=1000;
@ -24,7 +22,7 @@ pub struct Cli {
pub port: u16,
/// Path to the directory served by the Webserver
#[arg(short, long, default_value = "./web", value_parser = valid_path)]
#[arg(short, long, default_value = "./webradar", value_parser = valid_path)]
pub web_path: PathBuf,
/// Polling frequency in times per second for the DMA thread
@ -90,4 +88,27 @@ fn poll_in_range(s: &str) -> Result<u16, String> {
POLL_RANGE.end()
))
}
}
/// Wrapper because log::LevelFilter doesn't implement ValueEnum
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Default)]
pub enum Loglevel {
Error,
#[default]
Warn,
Info,
Debug,
Trace,
}
impl From<Loglevel> for log::LevelFilter {
fn from(val: Loglevel) -> Self {
match val {
Loglevel::Error => log::LevelFilter::Error,
Loglevel::Warn => log::LevelFilter::Warn,
Loglevel::Info => log::LevelFilter::Info,
Loglevel::Debug => log::LevelFilter::Debug,
Loglevel::Trace => log::LevelFilter::Trace,
}
}
}

@ -1,7 +1,6 @@
use csflow::{enums::PlayerType, structs::Vec3};
use serde::{Serialize, Deserialize};
use super::Vec3;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlayerData {
pos: Vec3,
@ -39,16 +38,6 @@ pub enum EntityData {
Bomb(BombData)
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default, PartialEq)]
pub enum PlayerType {
#[default]
Unknown,
Spectator,
Local,
Enemy,
Team
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RadarData {
ingame: bool,

@ -1,6 +1,4 @@
use memflow::types::Address;
use crate::structs::communication::PlayerType;
use csflow::{memflow::Address, enums::PlayerType};
#[derive(Clone, Copy)]
pub enum CachedEntity {

@ -1,60 +1,13 @@
mod cache;
use std::sync::Arc;
use ::std::sync::Arc;
use memflow::prelude::v1::*;
use csflow::{CheatCtx, Connector, memflow::Process, traits::{MemoryClass, BaseEntity}, enums::PlayerType, structs::{CBaseEntity, CPlayerController}};
use tokio::{sync::RwLock, time::{Duration, Instant}};
use crate::{structs::{Connector, communication::{RadarData, PlayerType, EntityData, PlayerData, BombData}}, sdk::{self, structs::{MemoryClass, BaseEntity, CBaseEntity, CPlayerController}}, dma::cache::CacheBuilder};
use crate::{comms::{RadarData, EntityData, BombData, PlayerData}, dma::cache::CacheBuilder};
use self::cache::Cache;
pub struct CheatCtx {
pub process: IntoProcessInstanceArcBox<'static>,
pub client_module: ModuleInfo,
pub engine_module: ModuleInfo,
}
impl CheatCtx {
pub fn setup(connector: Connector, pcileech_device: String) -> anyhow::Result<CheatCtx> {
let inventory = Inventory::scan();
let os = {
if connector == Connector::Pcileech {
let args = Args::new()
.insert("device", &pcileech_device);
let connector_args = ConnectorArgs::new(None, args, None);
inventory.builder()
.connector(&connector.to_string())
.args(connector_args)
.os("win32")
.build()?
} else {
inventory.builder()
.connector(&connector.to_string())
.os("win32")
.build()?
}
};
let mut process = os.into_process_by_name("cs2.exe")?;
let client_module = process.module_by_name("client.dll")?;
let engine_module = process.module_by_name("engine2.dll")?;
let ctx = Self {
process,
client_module,
engine_module,
};
Ok(ctx)
}
}
mod cache;
const SECOND_AS_NANO: u64 = 1000*1000*1000;
static ONCE: std::sync::Once = std::sync::Once::new();
@ -62,6 +15,12 @@ static ONCE: std::sync::Once = std::sync::Once::new();
pub async fn run(connector: Connector, pcileech_device: String, poll_rate: u16, data_lock: Arc<RwLock<RadarData>>) -> anyhow::Result<()> {
let mut ctx = CheatCtx::setup(connector, pcileech_device)?;
println!("---------------------------------------------------");
println!("Found cs2.exe at {:X}", ctx.process.info().address);
println!("Found engine module at cs2.exe+{:X}", ctx.engine_module.base);
println!("Found client module at cs2.exe+{:X}", ctx.client_module.base);
println!("---------------------------------------------------");
// Avoid printing warnings and other stuff before the initial prints are complete
tokio::time::sleep(Duration::from_millis(500)).await;
@ -82,12 +41,12 @@ pub async fn run(connector: Connector, pcileech_device: String, poll_rate: u16,
if !cache.is_valid() {
let mut cached_entities = Vec::new();
let globals = sdk::get_globals(&mut ctx)?;
let highest_index = sdk::highest_entity_index(&mut ctx)?;
let map_name = sdk::map_name(globals, &mut ctx)?;
let entity_list = sdk::get_entity_list(&mut ctx)?;
let globals = ctx.get_globals()?;
let highest_index = ctx.highest_entity_index()?;
let map_name = ctx.map_name(globals)?;
let entity_list = ctx.get_entity_list()?;
let local = sdk::get_local(&mut ctx)?;
let local = ctx.get_local()?;
if local.get_pawn(&mut ctx, entity_list)?.is_some() {
cached_entities.push(cache::CachedEntity::Player {
@ -95,7 +54,7 @@ pub async fn run(connector: Connector, pcileech_device: String, poll_rate: u16,
player_type: PlayerType::Local
});
for idx in 1..highest_index {
for idx in 1..=highest_index {
if let Some(entity) = CBaseEntity::from_index(&mut ctx, entity_list, idx)? {
let class_name = entity.class_name(&mut ctx)?;
@ -138,11 +97,11 @@ pub async fn run(connector: Connector, pcileech_device: String, poll_rate: u16,
log::debug!("Rebuilt cache.");
}
if sdk::network_is_ingame(&mut ctx)? {
if ctx.network_is_ingame()? {
let mut radar_data = Vec::with_capacity(64);
if sdk::is_bomb_planted(&mut ctx)? {
let bomb = sdk::get_plantedc4(&mut ctx)?;
if ctx.is_bomb_planted()? {
let bomb = ctx.get_plantedc4()?;
let bomb_pos = bomb.pos(&mut ctx)?;
radar_data.push(
EntityData::Bomb(BombData::new(
@ -155,7 +114,7 @@ pub async fn run(connector: Connector, pcileech_device: String, poll_rate: u16,
for cached_data in cache.entity_cache() {
match cached_data {
cache::CachedEntity::Bomb { ptr } => {
if sdk::is_bomb_dropped(&mut ctx)? {
if ctx.is_bomb_dropped()? {
let bomb_entity = CBaseEntity::new(ptr);
let pos = bomb_entity.pos(&mut ctx)?;
@ -234,7 +193,7 @@ pub async fn run(connector: Connector, pcileech_device: String, poll_rate: u16,
log::trace!("elapsed: {}ns", elapsed.as_nanos());
log::trace!("target: {}ns", target_interval.as_nanos());
log::trace!("missmatch count: {}", missmatch_count);
last_iteration_time = Instant::now();
}
}

@ -1,15 +1,15 @@
use ::std::sync::Arc;
use clap::Parser;
use std::sync::Arc;
use clap::Parser;
use cli::Cli;
use structs::communication::RadarData;
use comms::RadarData;
use tokio::sync::RwLock;
mod dma;
mod sdk;
mod structs;
mod comms;
mod cli;
mod webserver;
mod dma;
mod websocket;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
@ -29,12 +29,12 @@ async fn main() -> anyhow::Result<()> {
let rwlock_clone = rwlock.clone();
let dma_handle = tokio::spawn(async move {
if let Err(err) = dma::run(cli.connector, cli.pcileech_device, cli.poll_rate, rwlock_clone).await {
log::error!("Error in dma thread: {}", err.to_string());
log::error!("Error in dma thread: [{}]", err.to_string());
}
});
tokio::spawn(async move {
let future = webserver::run(cli.web_path, cli.port, rwlock);
let future = websocket::run(cli.web_path, cli.port, rwlock);
if let Ok(my_local_ip) = local_ip_address::local_ip() {
let address = format!("http://{}:{}", my_local_ip, cli.port);
@ -45,7 +45,7 @@ async fn main() -> anyhow::Result<()> {
}
if let Err(err) = future.await {
log::error!("Error in websocket server: {}", err.to_string());
log::error!("Error in websocket server: [{}]", err.to_string());
}
});

@ -10,7 +10,7 @@ use axum::{
use tokio::sync::RwLock;
use tower_http::services::ServeDir;
use crate::structs::communication::RadarData;
use crate::comms::RadarData;
#[derive(Clone)]
struct AppState {

@ -1,74 +0,0 @@
pub mod structs;
pub mod cs2dumper;
use crate::dma::CheatCtx;
use memflow::prelude::v1::*;
use anyhow::Result;
use self::structs::{CPlayerController, CBaseEntity, MemoryClass, CPlayerPawn};
pub fn get_local(ctx: &mut CheatCtx) -> Result<CPlayerController> {
let ptr = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwLocalPlayerController)?;
Ok(CPlayerController::new(ptr))
}
pub fn get_plantedc4(ctx: &mut CheatCtx) -> Result<CBaseEntity> {
let ptr = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwPlantedC4)?;
let ptr2 = ctx.process.read_addr64(ptr)?;
Ok(CBaseEntity::new(ptr2))
}
pub fn is_bomb_planted(ctx: &mut CheatCtx) -> Result<bool> {
let game_rules = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwGameRules)?;
let data: u8 = ctx.process.read(game_rules + cs2dumper::client::C_CSGameRules::m_bBombPlanted)?;
Ok(data != 0)
}
pub fn is_bomb_dropped(ctx: &mut CheatCtx) -> Result<bool> {
let game_rules = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwGameRules)?;
let data: u8 = ctx.process.read(game_rules + cs2dumper::client::C_CSGameRules::m_bBombDropped)?;
Ok(data != 0)
}
/*
pub fn is_ingame(ctx: &mut CheatCtx) -> Result<bool> {
let game_rules = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwGameRules)?;
let data: i32 = ctx.process.read(game_rules + cs2dumper::client::C_CSGameRules::m_gamePhase)?;
println!("m_gamePhase: {}", data);
Ok(data != 1)
}
*/
#[allow(dead_code)]
pub fn get_local_pawn(ctx: &mut CheatCtx) -> Result<CPlayerPawn> {
let ptr = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwLocalPlayerPawn)?;
Ok(CPlayerPawn::new(ptr))
}
pub fn get_entity_list(ctx: &mut CheatCtx) -> Result<Address> {
let ptr = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwEntityList)?;
Ok(ptr)
}
pub fn get_globals(ctx: &mut CheatCtx) -> Result<Address> {
let ptr = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwGlobalVars)?;
Ok(ptr)
}
pub fn map_name(global_vars: Address, ctx: &mut CheatCtx) -> Result<String> {
let ptr = ctx.process.read_addr64(global_vars + 0x188)?;
Ok(ctx.process.read_char_string_n(ptr, 32)?)
}
pub fn highest_entity_index(ctx: &mut CheatCtx) -> Result<i32> {
let game_entity_system = ctx.process.read_addr64(ctx.client_module.base + cs2dumper::offsets::client_dll::dwGameEntitySystem)?;
let highest_index = ctx.process.read(game_entity_system + cs2dumper::offsets::client_dll::dwGameEntitySystem_getHighestEntityIndex)?;
Ok(highest_index)
}
pub fn network_is_ingame(ctx: &mut CheatCtx) -> Result<bool> {
let ptr = ctx.process.read_addr64(ctx.engine_module.base + cs2dumper::offsets::engine2_dll::dwNetworkGameClient)?;
let signonstate: u64 = ctx.process.read(ptr + cs2dumper::offsets::engine2_dll::dwNetworkGameClient_signOnState)?;
Ok(signonstate == 6)
}

@ -1,26 +0,0 @@
mod base_entity;
mod player_controller;
mod player_pawn;
pub use base_entity::CBaseEntity;
pub use player_controller::CPlayerController;
pub use player_pawn::CPlayerPawn;
use crate::{dma::CheatCtx, structs::Vec3};
use memflow::types::Address;
use anyhow::Result;
/// A trait that implements basic functions from C_BaseEntity
/// CCSPlayerController inherits C_BaseEntity, which is why this trait exists.
pub trait BaseEntity {
fn from_index(ctx: &mut CheatCtx, entity_list: Address, index: i32) -> Result<Option<Self>> where Self: std::marker::Sized;
fn pos(&self, ctx: &mut CheatCtx) -> Result<Vec3>;
fn class_name(&self, ctx: &mut CheatCtx) -> Result<String>;
}
/// A trait that implements basic functions for an class represented by a single pointer
pub trait MemoryClass {
fn ptr(&self) -> Address;
fn new(ptr: Address) -> Self;
}

@ -1,13 +0,0 @@
mod entity_classes;
pub use entity_classes::*;
use enum_primitive_derive::Primitive;
#[repr(i32)]
#[derive(Debug, Eq, PartialEq, Primitive)]
pub enum TeamID {
Spectator = 1,
T = 2,
CT = 3
}

@ -1,50 +0,0 @@
pub mod comms;
use clap::ValueEnum;
pub use comms as communication;
mod vec3;
pub use vec3::Vec3;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Default)]
pub enum Connector {
#[default]
Qemu,
Kvm,
Pcileech
}
impl ToString for Connector {
fn to_string(&self) -> String {
match self {
Connector::Qemu => String::from("qemu"),
Connector::Kvm => String::from("kvm"),
Connector::Pcileech => String::from("pcileech"),
}
}
}
/// Wrapper because log::LevelFilter doesn't implement ValueEnum
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Default)]
pub enum Loglevel {
Error,
#[default]
Warn,
Info,
Debug,
Trace,
}
impl From<Loglevel> for log::LevelFilter {
fn from(val: Loglevel) -> Self {
match val {
Loglevel::Error => log::LevelFilter::Error,
Loglevel::Warn => log::LevelFilter::Warn,
Loglevel::Info => log::LevelFilter::Info,
Loglevel::Debug => log::LevelFilter::Debug,
Loglevel::Trace => log::LevelFilter::Trace,
}
}
}

Binary file not shown.

Before

(image error) Size: 101 KiB

Binary file not shown.

Before

(image error) Size: 186 KiB

Binary file not shown.

Before

(image error) Size: 152 KiB

Binary file not shown.

Before

(image error) Size: 212 KiB

Binary file not shown.

Before

(image error) Size: 156 KiB

Binary file not shown.

Before

(image error) Size: 126 KiB

Binary file not shown.

Before

(image error) Size: 137 KiB

Binary file not shown.

Before

(image error) Size: 76 KiB

Binary file not shown.

Before

(image error) Size: 196 KiB

Binary file not shown.

Before

(image error) Size: 97 KiB

Binary file not shown.

Before

(image error) Size: 474 KiB

@ -1,31 +0,0 @@
// HLTV overview description file for cs_italy.bsp
"cs_italy"
{
"material" "overviews/cs_italy" // texture file
"pos_x" "-2647" // upper left world coordinate
"pos_y" "2592"
"scale" "4.6"
"rotate" "1"
"zoom" "1.5"
// loading screen icons and positions
"CTSpawn_x" "0.41"
"CTSpawn_y" "0.91"
"TSpawn_x" "0.6"
"TSpawn_y" "0.1"
"Hostage1_x" "0.43"
"Hostage1_y" "0.29"
"Hostage2_x" "0.48"
"Hostage2_y" "0.24"
"Hostage3_x" "0.64"
"Hostage3_y" "0.03"
"Hostage4_x" "0.72"
"Hostage4_y" "0.05"
// "Hostage5_x" "0.8"
// "Hostage5_y" "0.3"
// "Hostage6_x" "0.6"
// "Hostage6_y" "0.9"
}

@ -1,29 +0,0 @@
// HLTV overview description file for cs_office.bsp
"cs_office"
{
"material" "overviews/cs_office" // texture file
"pos_x" "-1838" // upper left world coordinate
"pos_y" "1858"
"scale" "4.1"
// loading screen icons and positions
"CTSpawn_x" "0.16"
"CTSpawn_y" "0.89"
"TSpawn_x" "0.78"
"TSpawn_y" "0.30"
"Hostage1_x" "0.84"
"Hostage1_y" "0.27"
"Hostage2_x" "0.84"
"Hostage2_y" "0.48"
"Hostage3_x" "0.91"
"Hostage3_y" "0.48"
"Hostage4_x" "0.77"
"Hostage4_y" "0.48"
"Hostage5_x" "0.77"
"Hostage5_y" "0.55"
// "Hostage6_x" "0.6"
// "Hostage6_y" "0.9"
}

@ -1,23 +0,0 @@
// HLTV overview description file for de_ancient.bsp
"de_ancient"
{
"material" "overviews/de_ancient" // texture file
"pos_x" "-2953" // upper left world coordinate
"pos_y" "2164"
"scale" "5"
"rotate" "0"
"zoom" "0"
// loading screen icons and positions
"CTSpawn_x" "0.51"
"CTSpawn_y" "0.17"
"TSpawn_x" "0.485"
"TSpawn_y" "0.87"
"bombA_x" "0.31"
"bombA_y" "0.25"
"bombB_x" "0.80"
"bombB_y" "0.40"
}

@ -1,12 +0,0 @@
// TAVR - AUTO RADAR. v 2.5.0a
"de_anubis"
{
"CTSpawn_x" "0.610000"
"CTSpawn_y" "0.220000"
"TSpawn_x" "0.580000"
"TSpawn_y" "0.930000"
"material" "overviews/de_anubis"
"pos_x" "-2796.000000"
"pos_y" "3328.000000"
"scale" "5.220000"
}

@ -1,27 +0,0 @@
// HLTV overview description file for de_dust2_v2.bsp
"de_dust2"
{
"material" "overviews/de_dust2_v2" // texture file
"pos_x" "-2476" // upper left world coordinate
"pos_y" "3239"
"scale" "4.4"
"rotate" "1"
"zoom" "1.1"
"inset_left" "0.0"
"inset_top" "0.0"
"inset_right" "0.0"
"inset_bottom" "0.0"
// loading screen icons and positions
"CTSpawn_x" "0.62"
"CTSpawn_y" "0.21"
"TSpawn_x" "0.39"
"TSpawn_y" "0.91"
"bombA_x" "0.80"
"bombA_y" "0.16"
"bombB_x" "0.21"
"bombB_y" "0.12"
}

@ -1,20 +0,0 @@
// HLTV overview description file for de_inferno.bsp
"de_inferno"
{
"material" "overviews/de_inferno" // texture file
"pos_x" "-2087" // upper left world coordinate
"pos_y" "3870"
"scale" "4.9"
// loading screen icons and positions
"CTSpawn_x" "0.9"
"CTSpawn_y" "0.35"
"TSpawn_x" "0.1"
"TSpawn_y" "0.67"
"bombA_x" "0.81"
"bombA_y" "0.69"
"bombB_x" "0.49"
"bombB_y" "0.22"
}

@ -1,25 +0,0 @@
"de_mirage"
{
"material" "overviews/de_mirage" // texture file
"pos_x" "-3230" // X coordinate,
"pos_y" "1713" // Y coordinate,
"scale" "5.00" // and used scale used when taking the screenshot
"rotate" "0" // map was rotated by 90 degress in image editor
"zoom" "0" // optimal zoom factor if map is shown in full size
// loading screen icons and positions
"CTSpawn_x" "0.28"
"CTSpawn_y" "0.70"
"TSpawn_x" "0.87"
"TSpawn_y" "0.36"
"bombA_x" "0.54"
"bombA_y" "0.76"
"bombB_x" "0.23"
"bombB_y" "0.28"
"inset_left" "0.135"
"inset_top" "0.08"
"inset_right" "0.105"
"inset_bottom" "0.08"
}

@ -1,41 +0,0 @@
// HLTV overview description file for de_nuke.bsp
"de_nuke"
{
"material" "overviews/de_nuke" // texture file
"pos_x" "-3453" // upper left world coordinate
"pos_y" "2887"
"scale" "7"
"verticalsections"
{
"default" // use the primary radar image
{
"AltitudeMax" "10000"
"AltitudeMin" "-495"
}
"lower" // i.e. de_nuke_lower_radar.dds
{
"AltitudeMax" "-495"
"AltitudeMin" "-10000"
}
}
// loading screen icons and positions
"CTSpawn_x" "0.82"
"CTSpawn_y" "0.45"
"TSpawn_x" "0.19"
"TSpawn_y" "0.54"
"bombA_x" "0.58"
"bombA_y" "0.48"
"bombB_x" "0.58"
"bombB_y" "0.58"
"inset_left" "0.33"
"inset_top" "0.2"
"inset_right" "0.2"
"inset_bottom" "0.2"
}

@ -1,22 +0,0 @@
// HLTV overview description file for de_overpass.bsp
"de_overpass"
{
"material" "overviews/de_overpass" // texture file
"pos_x" "-4831" // upper left world coordinate
"pos_y" "1781"
"scale" "5.2"
"rotate" "0"
"zoom" "0"
// loading screen icons and positions
"CTSpawn_x" "0.49"
"CTSpawn_y" "0.2"
"TSpawn_x" "0.66"
"TSpawn_y" "0.93"
"bombA_x" "0.55"
"bombA_y" "0.23"
"bombB_x" "0.7"
"bombB_y" "0.31"
}

@ -1,40 +0,0 @@
// HLTV overview description file for de_vertigo.bsp
"de_vertigo"
{
"material" "overviews/de_vertigo_radar" // texture file
"pos_x" "-3168" // upper left world coordinate
"pos_y" "1762"
"scale" "4.0"
"verticalsections"
{
"default" // use the primary radar image
{
"AltitudeMax" "20000"
"AltitudeMin" "11700"
}
"lower" // i.e. de_nuke_lower_radar.dds
{
"AltitudeMax" "11700"
"AltitudeMin" "-10000"
}
}
// loading screen icons and positions
"CTSpawn_x" "0.54"
"CTSpawn_y" "0.25"
"TSpawn_x" "0.20"
"TSpawn_y" "0.75"
"bombA_x" "0.705"
"bombA_y" "0.585"
"bombB_x" "0.222"
"bombB_y" "0.223"
"inset_left" "0.1"
"inset_top" "0.1"
"inset_right" "0.2"
"inset_bottom" "0.15"
}

@ -1,7 +0,0 @@
"workshop_preview"
{
"autogenerated_tga" "1"
"pos_x" "-2071"
"pos_y" "711"
"scale" "1.699219"
}

Before

(image error) Size: 101 KiB

After

(image error) Size: 101 KiB

Before

(image error) Size: 186 KiB

After

(image error) Size: 186 KiB

Before

(image error) Size: 212 KiB

After

(image error) Size: 212 KiB

Before

(image error) Size: 156 KiB

After

(image error) Size: 156 KiB

Before

(image error) Size: 137 KiB

After

(image error) Size: 137 KiB

Before

(image error) Size: 76 KiB

After

(image error) Size: 76 KiB

Before

(image error) Size: 97 KiB

After

(image error) Size: 97 KiB