Skip to content

Commit

Permalink
feat: large data transfers (#74)
Browse files Browse the repository at this point in the history
* feat: initial commit to enable large map data

* chore: update dependencies

* chore: refactoring and tidying of messaging code
  • Loading branch information
pbellchambers authored Jul 13, 2022
1 parent 533a57f commit 8d200b8
Show file tree
Hide file tree
Showing 21 changed files with 211 additions and 117 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions rustyhack_client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustyhack_client"
version = "0.2.1"
version = "0.2.2"
authors = ["pbellchambers <[email protected]>"]
edition = "2021"
repository = "https://github.com/pbellchambers/rustyhack-mmo"
Expand All @@ -16,7 +16,8 @@ console_engine = "2.4.0"
crossterm = { version = "0.23.2", features = ["serde"] }
laminar = "0.5.0"
crossbeam-channel = "0.5.5"
serde = { version = "1.0.138", features = ["derive"] }
serde = { version = "1.0.139", features = ["derive"] }
bincode = "1.3.3"
regex = "1.6.0"
chrono = "0.4.19"
itertools = "0.10.3"
5 changes: 2 additions & 3 deletions rustyhack_client/src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crossbeam_channel::{Receiver, Sender};
use laminar::{Packet, SocketEvent};
use std::collections::HashMap;

use rustyhack_lib::message_handler::player_message::EntityUpdates;
use rustyhack_lib::message_handler::messages::EntityUpdates;

use crate::consts::{CONSOLE_HEIGHT, CONSOLE_WIDTH, GAME_TITLE, TARGET_FPS};
use crate::networking::message_handler;
Expand Down Expand Up @@ -48,8 +48,7 @@ pub(crate) fn run(
);

//initialise console engine
let mut console =
console_engine::ConsoleEngine::init(CONSOLE_WIDTH, CONSOLE_HEIGHT, TARGET_FPS).unwrap();
let mut console = ConsoleEngine::init(CONSOLE_WIDTH, CONSOLE_HEIGHT, TARGET_FPS).unwrap();
console.set_title(GAME_TITLE);
info!("Initialised console engine.");

Expand Down
2 changes: 1 addition & 1 deletion rustyhack_client/src/game/commands/look_command.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use chrono::{DateTime, Local};
use rustyhack_lib::background_map::AllMaps;
use rustyhack_lib::ecs::player::Player;
use rustyhack_lib::message_handler::player_message::EntityUpdates;
use rustyhack_lib::message_handler::messages::EntityUpdates;

pub(crate) fn get_what_player_sees(
status_messages: &mut Vec<String>,
Expand Down
2 changes: 1 addition & 1 deletion rustyhack_client/src/game/input_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::game::commands;
use console_engine::{ConsoleEngine, KeyCode};
use rustyhack_lib::background_map::AllMaps;
use rustyhack_lib::ecs::player::Player;
use rustyhack_lib::message_handler::player_message::EntityUpdates;
use rustyhack_lib::message_handler::messages::EntityUpdates;

pub(crate) fn handle_other_input(
console: &mut ConsoleEngine,
Expand Down
53 changes: 44 additions & 9 deletions rustyhack_client/src/game/map_handler.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,48 @@
use crate::networking::message_handler;
use bincode::serialize;
use bincode::{deserialize, serialize};
use crossbeam_channel::{Receiver, Sender};
use itertools::Itertools;
use laminar::Packet;
use rustyhack_lib::background_map::AllMaps;
use rustyhack_lib::message_handler::player_message::{PlayerMessage, PlayerReply};
use rustyhack_lib::background_map::{AllMaps, BackgroundMap};
use rustyhack_lib::message_handler::messages::{PlayerRequest, ServerMessage};
use std::collections::HashMap;
use std::thread;
use std::time::Duration;

pub(crate) fn request_all_maps_data(
sender: &Sender<Packet>,
server_addr: &str,
channel_receiver: &Receiver<PlayerReply>,
channel_receiver: &Receiver<ServerMessage>,
) -> AllMaps {
let get_all_maps_request_packet = Packet::reliable_ordered(
server_addr
.parse()
.expect("Server address format is invalid."),
serialize(&PlayerMessage::GetAllMaps).expect("Error serialising GetAllMaps request."),
serialize(&PlayerRequest::GetChunkedAllMaps)
.expect("Error serializing GetAllMaps request."),
Some(1),
);
message_handler::send_packet(get_all_maps_request_packet, sender);
info!("Requested all maps data from server.");
wait_for_all_maps_response(channel_receiver)
}

fn wait_for_all_maps_response(channel_receiver: &Receiver<PlayerReply>) -> AllMaps {
fn wait_for_all_maps_response(channel_receiver: &Receiver<ServerMessage>) -> AllMaps {
let mut all_maps_downloaded = false;
let mut all_maps = HashMap::new();
let mut all_maps_chunks = HashMap::new();
loop {
let received = channel_receiver.recv();
if let Ok(received_message) = received {
match received_message {
PlayerReply::AllMaps(message) => {
info!("All maps downloaded from server.");
ServerMessage::AllMapsChunk(message) => {
info!("All maps chunk received from server: {}", message.0);
all_maps_chunks.insert(message.0, message.1);
}
ServerMessage::AllMapsChunksComplete => {
info!("All maps chunks downloaded from server.");
all_maps = combine_all_maps_chunks(&all_maps_chunks);
all_maps_downloaded = true;
all_maps = message;
}
_ => {
info!(
Expand All @@ -54,3 +61,31 @@ fn wait_for_all_maps_response(channel_receiver: &Receiver<PlayerReply>) -> AllMa
debug!("All maps is: {:?}", all_maps);
all_maps
}

fn combine_all_maps_chunks(
all_maps_chunks: &HashMap<usize, Vec<u8>>,
) -> HashMap<String, BackgroundMap> {
deserialize_all_maps_reply(combine_chunks(all_maps_chunks))
}

fn combine_chunks(all_maps_chunks: &HashMap<usize, Vec<u8>>) -> Vec<u8> {
let mut combined_all_maps_chunks: Vec<u8> = Vec::new();
for chunk in all_maps_chunks.keys().sorted() {
combined_all_maps_chunks.extend(
all_maps_chunks
.get(chunk)
.expect("Error combining all maps chunks on chunk."),
);
}
combined_all_maps_chunks
}

fn deserialize_all_maps_reply(combined_chunks: Vec<u8>) -> HashMap<String, BackgroundMap> {
let deserialized_chunks = deserialize::<ServerMessage>(&combined_chunks)
.expect("Error deserializing combined all maps chunks.");
return if let ServerMessage::AllMaps(message) = deserialized_chunks {
message
} else {
panic!("Combined all maps chunks did not make a valid PlayerReply::AllMaps message");
};
}
14 changes: 6 additions & 8 deletions rustyhack_client/src/game/new_player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use bincode::serialize;
use crossbeam_channel::{Receiver, Sender};
use laminar::Packet;
use rustyhack_lib::ecs::player::Player;
use rustyhack_lib::message_handler::player_message::{
CreatePlayerMessage, PlayerMessage, PlayerReply,
};
use rustyhack_lib::message_handler::messages::{CreatePlayerRequest, PlayerRequest, ServerMessage};
use std::time::Duration;
use std::{process, thread};

Expand All @@ -14,13 +12,13 @@ pub(crate) fn send_new_player_request(
player_name: &str,
server_addr: &str,
client_addr: &str,
channel_receiver: &Receiver<PlayerReply>,
channel_receiver: &Receiver<ServerMessage>,
) -> Player {
let create_player_request_packet = Packet::reliable_unordered(
server_addr
.parse()
.expect("Server address format is invalid."),
serialize(&PlayerMessage::PlayerJoin(CreatePlayerMessage {
serialize(&PlayerRequest::PlayerJoin(CreatePlayerRequest {
client_addr: client_addr.to_string(),
player_name: player_name.to_string(),
}))
Expand All @@ -31,19 +29,19 @@ pub(crate) fn send_new_player_request(
wait_for_new_player_response(channel_receiver)
}

fn wait_for_new_player_response(channel_receiver: &Receiver<PlayerReply>) -> Player {
fn wait_for_new_player_response(channel_receiver: &Receiver<ServerMessage>) -> Player {
let mut new_player_confirmed = false;
let mut player = Player::default();
loop {
let received = channel_receiver.recv();
if let Ok(received_message) = received {
match received_message {
PlayerReply::PlayerJoined(message) => {
ServerMessage::PlayerJoined(message) => {
info!("New player creation confirmed.");
new_player_confirmed = true;
player = message;
}
PlayerReply::PlayerAlreadyOnline => {
ServerMessage::PlayerAlreadyOnline => {
error!(
"This player name is already taken, and the player is currently online."
);
Expand Down
14 changes: 7 additions & 7 deletions rustyhack_client/src/game/updates_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crossbeam_channel::{Receiver, Sender};
use laminar::Packet;
use rustyhack_lib::ecs::components::Velocity;
use rustyhack_lib::ecs::player::Player;
use rustyhack_lib::message_handler::player_message::{
EntityUpdates, PlayerMessage, PlayerReply, VelocityMessage,
use rustyhack_lib::message_handler::messages::{
EntityUpdates, PlayerRequest, ServerMessage, VelocityMessage,
};

pub(crate) fn send_player_updates(
Expand Down Expand Up @@ -42,7 +42,7 @@ fn send_velocity_packet(
server_addr
.parse()
.expect("Server address format is invalid."),
serialize(&PlayerMessage::UpdateVelocity(VelocityMessage {
serialize(&PlayerRequest::UpdateVelocity(VelocityMessage {
player_name: player.player_details.player_name.clone(),
velocity,
}))
Expand All @@ -54,15 +54,15 @@ fn send_velocity_packet(
}

pub(crate) fn check_for_received_player_updates(
channel_receiver: &Receiver<PlayerReply>,
channel_receiver: &Receiver<ServerMessage>,
mut player: Player,
) -> Player {
debug!("Checking for received player position from server.");
while !channel_receiver.is_empty() {
let received = channel_receiver.recv();
if let Ok(received_message) = received {
match received_message {
PlayerReply::UpdatePosition(new_position) => {
ServerMessage::UpdatePosition(new_position) => {
debug!("Player position update received: {:?}", &new_position);
player.position = new_position
}
Expand All @@ -79,15 +79,15 @@ pub(crate) fn check_for_received_player_updates(
}

pub(crate) fn check_for_received_entity_updates(
channel_receiver: &Receiver<PlayerReply>,
channel_receiver: &Receiver<ServerMessage>,
mut entity_updates: EntityUpdates,
) -> EntityUpdates {
debug!("Checking for received entity updates from server.");
while !channel_receiver.is_empty() {
let received = channel_receiver.recv();
if let Ok(received_message) = received {
match received_message {
PlayerReply::UpdateOtherEntities(new_updates) => {
ServerMessage::UpdateOtherEntities(new_updates) => {
debug!("Entity updates received: {:?}", &new_updates);
entity_updates = new_updates;
}
Expand Down
45 changes: 24 additions & 21 deletions rustyhack_client/src/networking/message_handler.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
use crate::networking::message_handler;
use bincode::deserialize;
use crossbeam_channel::{Receiver, Sender};
use laminar::{Packet, SocketEvent};
use rustyhack_lib::message_handler::player_message::PlayerReply;
use rustyhack_lib::message_handler::messages::ServerMessage;
use std::{process, thread};

pub(crate) fn spawn_message_handler_thread(
sender: Sender<Packet>,
receiver: Receiver<SocketEvent>,
player_update_sender: Sender<PlayerReply>,
entity_update_sender: Sender<PlayerReply>,
player_update_sender: Sender<ServerMessage>,
entity_update_sender: Sender<ServerMessage>,
) {
thread::spawn(move || {
message_handler::run(sender, receiver, player_update_sender, entity_update_sender)
});
thread::spawn(move || run(sender, receiver, player_update_sender, entity_update_sender));
}

pub(crate) fn run(
_sender: Sender<Packet>,
receiver: Receiver<SocketEvent>,
player_update_sender: Sender<PlayerReply>,
entity_update_sender: Sender<PlayerReply>,
player_update_sender: Sender<ServerMessage>,
entity_update_sender: Sender<ServerMessage>,
) {
info!("Spawned message handler thread.");
loop {
Expand All @@ -32,12 +29,12 @@ pub(crate) fn run(
let msg = packet.payload();
let address = packet.addr();

let player_reply_result = deserialize::<PlayerReply>(msg);
let player_reply_result = deserialize::<ServerMessage>(msg);
let player_reply = match player_reply_result {
Ok(_) => player_reply_result.unwrap(),
Err(error) => {
warn!(
"Error when deserialising player reply packet from server: {}",
"Error when deserializing player reply packet from server: {}",
error
);
//try again with next packet
Expand All @@ -47,20 +44,26 @@ pub(crate) fn run(
debug!("Received {:?} from {:?}", player_reply, address);

let channel_send_status = match player_reply {
PlayerReply::PlayerJoined(message) => {
player_update_sender.send(PlayerReply::PlayerJoined(message))
ServerMessage::PlayerJoined(message) => {
player_update_sender.send(ServerMessage::PlayerJoined(message))
}
PlayerReply::AllMaps(message) => {
player_update_sender.send(PlayerReply::AllMaps(message))
ServerMessage::AllMaps(message) => {
player_update_sender.send(ServerMessage::AllMaps(message))
}
PlayerReply::UpdatePosition(message) => {
player_update_sender.send(PlayerReply::UpdatePosition(message))
ServerMessage::AllMapsChunk(message) => {
player_update_sender.send(ServerMessage::AllMapsChunk(message))
}
PlayerReply::UpdateOtherEntities(message) => {
entity_update_sender.send(PlayerReply::UpdateOtherEntities(message))
ServerMessage::AllMapsChunksComplete => {
player_update_sender.send(ServerMessage::AllMapsChunksComplete)
}
PlayerReply::PlayerAlreadyOnline => {
player_update_sender.send(PlayerReply::PlayerAlreadyOnline)
ServerMessage::UpdatePosition(message) => {
player_update_sender.send(ServerMessage::UpdatePosition(message))
}
ServerMessage::UpdateOtherEntities(message) => {
entity_update_sender.send(ServerMessage::UpdateOtherEntities(message))
}
ServerMessage::PlayerAlreadyOnline => {
player_update_sender.send(ServerMessage::PlayerAlreadyOnline)
}
};

Expand Down
2 changes: 1 addition & 1 deletion rustyhack_client/src/screens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::consts;
use console_engine::ConsoleEngine;
use rustyhack_lib::background_map::AllMaps;
use rustyhack_lib::ecs::player::Player;
use rustyhack_lib::message_handler::player_message::EntityUpdates;
use rustyhack_lib::message_handler::messages::EntityUpdates;
use std::process;

mod bottom_text_window;
Expand Down
2 changes: 1 addition & 1 deletion rustyhack_client/src/screens/viewport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustyhack_lib::background_map::tiles::{Tile, TilePosition};
use rustyhack_lib::background_map::BackgroundMap;
use rustyhack_lib::ecs::components::DisplayDetails;
use rustyhack_lib::ecs::player::Player;
use rustyhack_lib::message_handler::player_message::EntityUpdates;
use rustyhack_lib::message_handler::messages::EntityUpdates;

struct Viewport {
width: u32,
Expand Down
Loading

0 comments on commit 8d200b8

Please sign in to comment.