|
1 | 1 | use bincode::{deserialize, serialize};
|
2 |
| -use crossbeam_channel::{Receiver, Sender}; |
3 |
| -use itertools::Itertools; |
4 |
| -use laminar::Packet; |
| 2 | +use message_io::network::{NetEvent, Transport}; |
| 3 | +use message_io::node; |
| 4 | +use message_io::node::NodeEvent; |
5 | 5 | use rustyhack_lib::background_map::AllMaps;
|
6 | 6 | use rustyhack_lib::network::packets::{PlayerRequest, ServerMessage};
|
7 | 7 | use std::collections::HashMap;
|
8 |
| -use std::thread; |
9 |
| -use std::time::Duration; |
| 8 | +use std::process; |
10 | 9 |
|
11 |
| -pub(crate) fn request_all_maps_data( |
12 |
| - sender: &Sender<Packet>, |
13 |
| - server_addr: &str, |
14 |
| - channel_receiver: &Receiver<ServerMessage>, |
15 |
| -) -> Option<AllMaps> { |
16 |
| - let get_all_maps_request_packet = Packet::reliable_ordered( |
17 |
| - server_addr |
18 |
| - .parse() |
19 |
| - .expect("Server address format is invalid."), |
20 |
| - serialize(&PlayerRequest::GetChunkedAllMaps) |
21 |
| - .expect("Error serializing GetAllMaps request."), |
22 |
| - Some(1), |
23 |
| - ); |
24 |
| - rustyhack_lib::network::send_packet(get_all_maps_request_packet, sender); |
25 |
| - info!("Requested all maps data from server."); |
26 |
| - wait_for_all_maps_response(channel_receiver) |
27 |
| -} |
| 10 | +pub(crate) fn request_all_maps_data(server_tcp_addr: &str) -> AllMaps { |
| 11 | + let mut all_maps = HashMap::new(); |
| 12 | + let (handler, listener) = node::split(); |
28 | 13 |
|
29 |
| -fn wait_for_all_maps_response(channel_receiver: &Receiver<ServerMessage>) -> Option<AllMaps> { |
30 |
| - let mut all_maps_downloaded = false; |
31 |
| - let mut all_maps = None; |
32 |
| - let mut all_maps_chunks = HashMap::new(); |
33 |
| - loop { |
34 |
| - let received = channel_receiver.recv(); |
35 |
| - if let Ok(received_message) = received { |
36 |
| - match received_message { |
37 |
| - ServerMessage::AllMapsChunk(message) => { |
38 |
| - info!("All maps chunk received from server: {}", message.0); |
39 |
| - all_maps_chunks.insert(message.0, message.1); |
40 |
| - } |
41 |
| - ServerMessage::AllMapsChunksComplete => { |
42 |
| - info!("All maps chunks downloaded from server."); |
43 |
| - all_maps = combine_all_maps_chunks(&all_maps_chunks); |
44 |
| - all_maps_downloaded = true; |
45 |
| - } |
46 |
| - _ => { |
47 |
| - info!( |
48 |
| - "Ignoring other message types until maps downloaded. {:?}", |
49 |
| - received_message |
50 |
| - ); |
| 14 | + //connect to server tcp port |
| 15 | + let (server, _) = handler |
| 16 | + .network() |
| 17 | + .connect(Transport::FramedTcp, server_tcp_addr) |
| 18 | + .unwrap_or_else(|err| { |
| 19 | + error!( |
| 20 | + "Unable to connect to server {}, error: {}", |
| 21 | + &server_tcp_addr, err |
| 22 | + ); |
| 23 | + process::exit(1); |
| 24 | + }); |
| 25 | + |
| 26 | + //send GetAllMaps request and wait for response |
| 27 | + listener.for_each(|event| match event { |
| 28 | + NodeEvent::Network(net_event) => match net_event { |
| 29 | + NetEvent::Connected(_endpoint, _ok) => { |
| 30 | + info!("Sending GetAllMaps request to server."); |
| 31 | + handler.signals().send(PlayerRequest::GetAllMaps); |
| 32 | + } |
| 33 | + NetEvent::Accepted(_, _) => unreachable!(), // Only generated by listening |
| 34 | + NetEvent::Message(_endpoint, data) => { |
| 35 | + info!("Received raw AllMaps data from server."); |
| 36 | + let all_maps_option = deserialize_all_maps_reply(data); |
| 37 | + match all_maps_option { |
| 38 | + None => { |
| 39 | + info!("Sending GetAllMaps request to server."); |
| 40 | + handler.signals().send(PlayerRequest::GetAllMaps); |
| 41 | + } |
| 42 | + Some(all_maps_data) => { |
| 43 | + all_maps = all_maps_data; |
| 44 | + handler.stop(); |
| 45 | + handler.network().remove(server.resource_id()); |
| 46 | + } |
51 | 47 | }
|
52 | 48 | }
|
53 |
| - } |
54 |
| - if all_maps_downloaded { |
55 |
| - info!("Got all maps data."); |
56 |
| - break; |
57 |
| - } |
58 |
| - thread::sleep(Duration::from_millis(1)); |
59 |
| - } |
60 |
| - debug!("All maps is: {:?}", all_maps); |
| 49 | + NetEvent::Disconnected(_endpoint) => { |
| 50 | + error!("Server is disconnected."); |
| 51 | + handler.stop(); |
| 52 | + handler.network().remove(server.resource_id()); |
| 53 | + process::exit(1); |
| 54 | + } |
| 55 | + }, |
| 56 | + NodeEvent::Signal(signal) => match signal { |
| 57 | + PlayerRequest::GetAllMaps => { |
| 58 | + handler |
| 59 | + .network() |
| 60 | + .send(server, &serialize(&PlayerRequest::GetAllMaps).unwrap()); |
| 61 | + } |
| 62 | + _ => { |
| 63 | + warn!("Ignoring invalid PlayerRequest on tcp channel."); |
| 64 | + } |
| 65 | + }, |
| 66 | + }); |
61 | 67 | all_maps
|
62 | 68 | }
|
63 | 69 |
|
64 |
| -fn combine_all_maps_chunks(all_maps_chunks: &HashMap<usize, Vec<u8>>) -> Option<AllMaps> { |
65 |
| - deserialize_all_maps_reply(&combine_chunks(all_maps_chunks)) |
66 |
| -} |
67 |
| - |
68 |
| -fn combine_chunks(all_maps_chunks: &HashMap<usize, Vec<u8>>) -> Vec<u8> { |
69 |
| - let mut combined_all_maps_chunks: Vec<u8> = Vec::new(); |
70 |
| - for chunk in all_maps_chunks.keys().sorted() { |
71 |
| - combined_all_maps_chunks.extend( |
72 |
| - all_maps_chunks |
73 |
| - .get(chunk) |
74 |
| - .expect("Error combining all maps chunks on chunk."), |
75 |
| - ); |
76 |
| - } |
77 |
| - combined_all_maps_chunks |
78 |
| -} |
79 |
| - |
80 |
| -fn deserialize_all_maps_reply(combined_chunks: &[u8]) -> Option<AllMaps> { |
81 |
| - let deserialized_chunks = deserialize::<ServerMessage>(combined_chunks); |
82 |
| - match deserialized_chunks { |
| 70 | +fn deserialize_all_maps_reply(data: &[u8]) -> Option<AllMaps> { |
| 71 | + let deserialized_data = deserialize::<ServerMessage>(data); |
| 72 | + match deserialized_data { |
83 | 73 | Ok(deserialized) => {
|
84 | 74 | if let ServerMessage::AllMaps(all_maps) = deserialized {
|
| 75 | + info!("AllMaps data downloaded successfully."); |
85 | 76 | Some(all_maps)
|
86 | 77 | } else {
|
87 |
| - warn!("Deserialized message from server was not all maps, will request again."); |
| 78 | + warn!("Deserialized message from server was not valid AllMaps data, will request again."); |
88 | 79 | None
|
89 | 80 | }
|
90 | 81 | }
|
91 | 82 | Err(error) => {
|
92 |
| - warn!( |
93 |
| - "Error deserializing all maps from server, will request again. {}", |
| 83 | + error!( |
| 84 | + "Error deserializing AllMaps from server, will request again. {}", |
94 | 85 | error.to_string()
|
95 | 86 | );
|
96 | 87 | None
|
|
0 commit comments