Skip to content

Commit

Permalink
Updated JSON parse after merge
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanpoland committed Aug 8, 2024
1 parent 26ee666 commit 960a2bb
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 81 deletions.
186 changes: 132 additions & 54 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ use viz::{future::ok, handler::ServiceHandler, serve, Response, Result, Router,
use TerraForge;
use PebbleVault;

// WARNING
// Import all structs (when we have a ton of structs this will be very bad but should be fine for now)
//////////////////////////////////////////////////////////////
// !!!! WARNING !!!! //
// Import all structs (when we have a ton of structs this //
// will be very bad but should be fine for now) //
//////////////////////////////////////////////////////////////
use structs::*;

/////////////////////////////////////
Expand All @@ -48,19 +51,56 @@ mod structs;
mod subsystems;

///////////////////////////////////////////////////////////////
// WARNING //
// !!!! WARNING !!!! //
// on_connect runs every time a new player connects to the //
// server avoid putting memory hungry code here if possible! //
///////////////////////////////////////////////////////////////

fn on_connect(socket: SocketRef, Data(data): Data<Value>, players: Arc<Mutex<Vec<Player>>>) {
// Update the parsing functions to handle the data without Object wrappers

fn parse_rotation(parse: &Value) -> (f64, f64, f64, f64) {
(
parse_f64(&parse["w"]).unwrap_or(0.0),
parse_f64(&parse["x"]).unwrap_or(0.0),
parse_f64(&parse["y"]).unwrap_or(0.0),
parse_f64(&parse["z"]).unwrap_or(0.0),
)
}

fn parse_xyz(parse: &Value) -> (f64, f64, f64) {
(
parse_f64(&parse["x"]).unwrap_or(0.0),
parse_f64(&parse["y"]).unwrap_or(0.0),
parse_f64(&parse["z"]).unwrap_or(0.0),
)
}

fn parse_xy(parse: &Value) -> (f64, f64) {
(
parse_f64(&parse["x"]).unwrap_or(0.0),
parse_f64(&parse["y"]).unwrap_or(0.0),
)
}

fn parse_f64(n: &Value) -> Result<f64, std::io::Error> {
n.as_f64().ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid f64 value"))
}


let id = socket.id.as_str();
println!("Starting subsystems for player: {}", id);

///////////////////////////////////////////////////////////////////
//
//
///////////////////////////////////////////////////////////////////

// Authenticate the user
let player = Player {
let player = Player {
socket: socket.clone(),
location: None, // Initialize with no location
moveActionValue: None,
transform: None
};

players.lock().unwrap().push(player);
Expand All @@ -70,10 +110,10 @@ fn on_connect(socket: SocketRef, Data(data): Data<Value>, players: Arc<Mutex<Vec
socket.emit("connected", true).ok();
socket.emit("auth", true).ok();

/////////////////////////////////////////////////////////
// Setup external event listeners for the more complex //
// systems //
/////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Setup external event listeners for the more complex //
// systems //
///////////////////////////////////////////////////////////


// subsystems::actors::main::main();
Expand All @@ -85,63 +125,91 @@ fn on_connect(socket: SocketRef, Data(data): Data<Value>, players: Arc<Mutex<Vec
subsystems::core::logging::init();
subsystems::core::notifications::init();

////////////////////////////////////////////////////////
// Register some additional custom events with our //
// socket server. Your custom events will be //
// registered here as well as in the ./events/mod.rs //
// file //
////////////////////////////////////////////////////////

//define_event!(socket,
// "test", events::test::main(),
// );

let players_clone = Arc::clone(&players);
/////////////////////////////////////////////////////////
// Register some additional custom events with our //
// socket server. Your custom events will be //
// registered here as well as in the ./events/mod.rs //
// file //
/////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// !!!TEMPORARY!!! //
// see subsystems/player_data.rs this code will be moved there in the future //
////////////////////////////////////////////////////////////////////////////////
// define_event!(socket,
// "test", events::test::main(),
// );

let players_clone_updateloc: Arc<Mutex<Vec<Player>>> = Arc::clone(&players);
let players_clone: Arc<Mutex<Vec<Player>>> = Arc::clone(&players);
socket.on(
"UpdatePlayerLocation",
"updatePlayerLocation",
move |socket: SocketRef, Data::<Value>(data), Bin(bin)| {
info!(
println!(
"Received event: UpdatePlayerLocation with data: {:?} and bin: {:?}",
data, bin
);

// Extract location from data
match serde_json::from_value::<Location>(data.clone()) {
Ok(location) => {
let mut players: std::sync::MutexGuard<Vec<Player>> = players_clone.lock().unwrap();
if let Some(player) = players.iter_mut().find(|p: &&mut Player| p.socket.id == socket.id)
{
player.location = Some(location);
info!("Updated player location: {:?}", player);
if let Some(transform) = data.get("transform").and_then(|t| t.as_object()) {
let mut players: std::sync::MutexGuard<Vec<Player>> = players_clone_updateloc.lock().unwrap();
if let Some(player) = players.iter_mut().find(|p: &&mut Player| p.socket.id == socket.id)
{
// Do the actual parsing
if let (Some(rotation), Some(translation), Some(scale3d)) = (
transform.get("rotation"),
transform.get("translation"),
transform.get("scale3D")
) {
let (rot_w, rot_x, rot_y, rot_z) = parse_rotation(rotation);
let (trans_x, trans_y, trans_z) = parse_xyz(translation);
let (scale3d_x, scale3d_y, scale3d_z) = parse_xyz(scale3d);

// Create or update the transform
let mut transform = player.transform.take().unwrap_or_else(|| structs::Transform {
rotation: None,
translation: None,
scale3D: structs::Scale3D { x: 1.0, y: 1.0, z: 1.0 },
location: None,
});

// Update rotation
transform.rotation = Some(structs::Rotation { w: rot_w, x: rot_x, y: rot_y, z: rot_z });

// Update translation
let new_translation = structs::Translation { x: trans_x, y: trans_y, z: trans_z };
transform.translation = Some(new_translation.clone());
transform.location = Some(new_translation);

// Update scale3D
transform.scale3D = structs::Scale3D { x: scale3d_x, y: scale3d_y, z: scale3d_z };

// Update the player's transform
player.transform = Some(transform);

// Parse player movement axis values
if let Some(move_action) = data.get("move Action Value") {
let (mv_action_value_x, mv_action_value_y) = parse_xy(move_action);
player.moveActionValue = Some(structs::MoveActionValue { x: mv_action_value_x, y: mv_action_value_y });
}

// Print a debug statement
println!("Updated player location: {:?}", player);
} else {
info!("Player not found: {}", socket.id);
println!("Invalid transform data structure");
}
} else {
println!("Player not found: {}", socket.id);
}
Err(err) => {
info!("Failed to parse location: {:?}", err);
}
} else {
println!("Failed to parse location: transform field not found or is not an object");
}

// Send a reply containing the correct data
socket.bin(bin).emit("messageBack", data).ok();
},
);

socket.on(
"message-with-ack",
move |Data::<Value>(data), ack: AckSender, Bin(bin)| {
info!(
"Received event: message-with-ack with data: {:?} and bin: {:?}",
data, bin
);
ack.bin(bin).send(data).ok();
},
);
/////////////////////////////////////////////////////////////////////////
// Client sends this message when they need a list of online players //
/////////////////////////////////////////////////////////////////////////

let players_clone: Arc<Mutex<Vec<Player>>> = Arc::clone(&players);
socket.on(
"getOnlinePlayers",
move |socket: SocketRef, _: Data<Value>, _: Bin| {
Expand All @@ -163,17 +231,27 @@ fn on_connect(socket: SocketRef, Data(data): Data<Value>, players: Arc<Mutex<Vec

socket.on(
"getPlayersWithLocations",
move |socket: SocketRef, _: Data<Value>, _: Bin| {
println!("Responding with players and locations list");
move |socket: SocketRef, Data::<Value>(data), ack: AckSender, Bin(bin)| {
info!("Responding with players and locations list");
let players: std::sync::MutexGuard<Vec<Player>> = players_clone.lock().unwrap();

match data {
Value::Null => println!("Received event with null data"),
Value::String(s) => println!("Received event with string data: {}", s),
_ => println!("Received event with data: {:?}", data),
}
println!("Binary payload: {:?}", bin);
let players_with_locations_json = serde_json::to_value(
players
.iter()
.map(|player| json!({ "id": player.socket.id, "location": player.location }))
.map(|player| json!({
"id": player.socket.id,
"transform": player.transform.as_ref().unwrap().location
}))
.collect::<Vec<_>>(),
)
.unwrap();
println!(
info!(
"Players with Locations as JSON: {}",
players_with_locations_json
);
Expand Down Expand Up @@ -266,4 +344,4 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("{}", e);
}
Ok(())
}
}
85 changes: 59 additions & 26 deletions src/structs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
///////////////////////////////////////////////////////////////
// INFORMATION //
// This file contains Horizon's global struct definitions. //
// Because of this anything that is public in this file //
// can be imported by any part of Horizon using //
// crate::structs:: //
///////////////////////////////////////////////////////////////
// !!!! WARNING !!!! //
// Anything made public in this file *WILL* me imported by //
// main.rs //
///////////////////////////////////////////////////////////////

use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use socketioxide::extract::SocketRef;
Expand Down Expand Up @@ -104,6 +116,9 @@ impl ChildServer {
neighbors
}


// TODO: Finish this implementation and move to its own file

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment

//////////////////////////////////////////////////////////////////////////////////////////////////////
// * Event Transmission: //
// - After determining the target neighbors, the child server sends the event to the master server. //
Expand Down Expand Up @@ -141,12 +156,6 @@ impl ChildServer {
// }
}

// Define a struct for Player
#[derive(Debug, Clone)]
pub struct Player {
pub socket: SocketRef,
pub location: Option<Location>, // Optional to handle players who haven't sent location updates yet
}

/////////////////////////////////////////////////////////////////////////////
// World object structs: //
Expand All @@ -156,36 +165,60 @@ pub struct Player {

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Rotation {
w: f64,
x: f64,
y: f64,
z: f64,
pub x: f64,
pub y: f64,
pub z: f64,
pub w: f64,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Translation {
pub x: f64,
pub y: f64,
pub z: f64,
}

// Define a struct for Scale of objects
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Scale {
x: f64,
y: f64,
z: f64,
pub struct Location {
pub x: f64,
pub y: f64,
pub z: f64,
}

// Define a struct for Translation of objects
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Translation {
x: f64,
y: f64,
z: f64,
pub struct Scale3D {
pub x: f64,
pub y: f64,
pub z: f64,
}

// Define a struct for Location of objects
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Location {
rotation: Rotation,
scale3D: Scale, // Update field name to match the JSON data
translation: Translation,
pub struct Transform {
pub location: Option<Translation>,
pub rotation: Option<Rotation>,
pub translation: Option<Translation>,
pub scale3D: Scale3D,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MoveActionValue {
pub x: f64,
pub y: f64,
}


////////////////////////////////
// Define the player struct //
////////////////////////////////

#[derive(Debug, Clone)]
pub struct Player {
pub socket: SocketRef,
pub moveActionValue: Option<MoveActionValue>,
pub transform: Option<Transform>
}


pub struct PlayerManager {
players: Mutex<HashMap<String, Arc<Notify>>>,
}
Expand Down Expand Up @@ -293,4 +326,4 @@ pub struct Planet {
// ],
// };
// }
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
2 changes: 1 addition & 1 deletion src/subsystems/core
Submodule core updated from 63a2de to c47bba

0 comments on commit 960a2bb

Please sign in to comment.