summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml4
-rw-r--r--src/main.rs149
2 files changed, 125 insertions, 28 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 0f375df..3790aa1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,9 @@ version = "0.1.0"
edition = "2021"
[dependencies]
+reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
hyper = { version = "0.14", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0" \ No newline at end of file
+serde_json = "1.0"
+webhook = "2.1.2" \ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index 1b2c8c7..76a929d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,12 @@
use hyper::{Body, Request, Response, Server, service::{make_service_fn, service_fn}};
use serde_json::Value;
-use std::convert::Infallible;
-use serde::Deserialize;
+use std::collections::HashMap;
+use std::sync::{Arc, Mutex};
+use serde::{Deserialize, Serialize};
+use webhook::client::WebhookClient;
+use std::error::Error;
+
+const IMAGE_URL: &str = "https://www.counter-strike.net/favicon.ico";
#[derive(Debug, Deserialize)]
struct MatchData {
@@ -17,19 +22,16 @@ struct MatchData {
#[derive(Debug, Deserialize)]
struct MapData {
name: Option<String>,
- // Add other map-specific fields as necessary
}
#[derive(Debug, Deserialize)]
struct RoundData {
phase: Option<String>,
- // Add other round-specific fields as necessary
}
#[derive(Debug, Deserialize)]
struct PlayerIdData {
id: Option<u32>,
- // Add other player_id-specific fields as necessary
}
#[derive(Debug, Deserialize)]
@@ -37,48 +39,133 @@ struct PlayerStateData {
health: Option<u32>,
armor: Option<u32>,
flashed: Option<u32>,
- // Add other player_state-specific fields as necessary
}
#[derive(Debug, Deserialize)]
struct PlayerWeaponsData {
primary: Option<String>,
secondary: Option<String>,
- // Add other player_weapons-specific fields as necessary
}
#[derive(Debug, Deserialize)]
struct PlayerMatchStatsData {
kills: Option<u32>,
deaths: Option<u32>,
- // Add other player_match_stats-specific fields as necessary
}
#[derive(Debug, Deserialize)]
struct AllPlayersIdData {
players: Vec<PlayerIdData>,
- // Add other allplayers_id-specific fields as necessary
}
-async fn handle_request(req: Request<Body>) -> Result<Response<Body>, Infallible> {
- if req.method() == hyper::Method::POST {
- let whole_body = hyper::body::to_bytes(req.into_body()).await.unwrap();
- let json: Value = serde_json::from_slice(&whole_body).unwrap();
+#[derive(Serialize)]
+struct Message {
+ content: String,
+}
- // Print the raw JSON for debugging
- println!("Received JSON: {}", json);
+// Define the state type
+type State = Arc<Mutex<HashMap<String, HashMap<String, i64>>>>;
- // Print out the parsed data for debugging
- if let Some(map) = json.as_object() {
- for (key, value) in map {
- println!("{}: {}", key, value);
+async fn handle_request(req: Request<Body>, state: State) -> Result<Response<Body>, Box<dyn Error + Send + Sync>> {
+ if req.method() == hyper::Method::POST {
+ let whole_body = hyper::body::to_bytes(req.into_body()).await?;
+
+ // Attempt to parse the JSON
+ match serde_json::from_slice::<Value>(&whole_body) {
+ Ok(json) => {
+ // Print the raw JSON for debugging
+ // println!("Received JSON: {}", json);
+
+ // Lock the state for reading and writing
+ let mut previous_state = state.lock().unwrap();
+
+ // Check if the JSON value is an object
+ if let Some(map) = json.as_object() {
+ if let Some(player) = map.get("player") {
+ if let Some(player_obj) = player.as_object() {
+ // Extract weapon information
+ if let Some(weapons) = player_obj.get("weapons") {
+ if let Some(weapons_obj) = weapons.as_object() {
+ for (weapon_key, weapon_value) in weapons_obj {
+ if let Some(weapon_obj) = weapon_value.as_object() {
+ if let Some(name) = weapon_obj.get("name") {
+ if let Some(name_str) = name.as_str() {
+ if let Some(ammo_clip) = weapon_obj.get("ammo_clip") {
+ if let Some(ammo_clip_value) = ammo_clip.as_i64() {
+ // Update previous state
+ let mut weapon_state = previous_state.entry(weapon_key.clone()).or_insert_with(HashMap::new);
+ let prev_ammo_clip = weapon_state.entry("ammo_clip".to_string()).or_insert(0);
+
+ // Print debug information
+ println!("Weapon: {}, Ammo Clip (prev): {}, Ammo Clip (current): {}", name_str, prev_ammo_clip, ammo_clip_value);
+
+ // Compare ammo_clip with previous state
+ if ammo_clip_value < *prev_ammo_clip {
+ println!("Weapon {}: {} fired! Ammo Clip: {} -> {}", weapon_key, name_str, prev_ammo_clip, ammo_clip_value);
+
+ let url = "https://discord.com/api/webhooks/1277517311347261470/4-UgsyHK3-AcWai9xWsOMHkpnpAHuFc0Izp3fRCb7M0NaHNng9h6tKmS3x_k4X-4tdMS";
+
+ // Send the webhook message in an async block
+ let client = WebhookClient::new(&url);
+ let webhook_info = client.get_information().await?;
+ println!("webhook: {:?}", webhook_info);
+
+ client.send(|message| message
+ .content("@everyone")
+ .username("Thoo")
+ .avatar_url(IMAGE_URL)
+ .embed(|embed| embed
+ .title("Webhook")
+ .description("Hello, World!")
+ .footer("Footer", Some(String::from(IMAGE_URL)))
+ .image(IMAGE_URL)
+ .thumbnail(IMAGE_URL)
+ .author("Lmao#0001", Some(String::from(IMAGE_URL)), Some(String::from(IMAGE_URL)))
+ .field("name", "value", false))).await?;
+
+ }
+
+ // Update previous ammo_clip
+ *prev_ammo_clip = ammo_clip_value;
+ } else {
+ println!("Ammo clip is not an integer for weapon {}", name_str);
+ }
+ } else {
+ println!("Ammo clip field is missing for weapon {}", name_str);
+ }
+ } else {
+ println!("Weapon name is not a string");
+ }
+ } else {
+ println!("Weapon object does not contain a name field");
+ }
+ } else {
+ println!("Weapon value is not an object");
+ }
+ }
+ } else {
+ println!("Weapons field is not an object");
+ }
+ } else {
+ println!("Player object does not contain weapons field");
+ }
+ } else {
+ println!("Player field is not an object");
+ }
+ } else {
+ println!("JSON does not contain player field");
+ }
+ } else {
+ println!("JSON is not an object");
+ }
+
+ Ok(Response::new(Body::from("Received")))
+ },
+ Err(e) => {
+ eprintln!("Failed to parse JSON: {}", e);
+ Ok(Response::new(Body::from("Invalid JSON")))
}
- } else {
- println!("Received data is not a JSON object");
}
-
- // Respond to the GSI service
- Ok(Response::new(Body::from("Received")))
} else {
Ok(Response::new(Body::from("Unsupported HTTP method")))
}
@@ -86,9 +173,17 @@ async fn handle_request(req: Request<Body>) -> Result<Response<Body>, Infallible
#[tokio::main]
async fn main() {
- let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle_request)) });
+ // Initialize the global state
+ let state = Arc::new(Mutex::new(HashMap::new()));
+
+ let make_svc = make_service_fn(move |_conn| {
+ let state = state.clone();
+ async move {
+ Ok::<_, Box<dyn Error + Send + Sync>>(service_fn(move |req| handle_request(req, state.clone())))
+ }
+ });
- let addr = ([0, 0, 0, 0], 5000).into(); // Listen on all interfaces on port 3000
+ let addr = ([0, 0, 0, 0], 5000).into(); // Listen on all interfaces on port 5000
let server = Server::bind(&addr).serve(make_svc);
println!("Listening on http://{}", addr);
@@ -96,4 +191,4 @@ async fn main() {
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
-} \ No newline at end of file
+}