fn check_network_ready(&mut self) {
        let game_info;
        let routes;
        let snp_send_messages;
        match self.network {
            NetworkState::Incomplete(ref mut i) => {
                if i.game_info.is_some() && i.routes.is_some() && i.snp_send_messages.is_some() {
                    game_info = i.game_info.take().unwrap();
                    routes = i.routes.take().unwrap();
                    snp_send_messages = i.snp_send_messages.take().unwrap();
                } else {
                    return;
                }
            }
            NetworkState::Ready(_) => return,
            NetworkState::Error(ref e) => {
                for send in self.waiting_for_network.drain(..) {
                    let _ = send.send(Err(e.clone()));
                }
                return;
            }
        }
        // Build an object mapping Fake-IP => rally-point route, ordered consistently between all
        // players (host first, then all other players ordered by slot). Computers are not
        // included, as we [obviously] won't be sending network traffic to them. This mapping
        // will be used by our SNP to shuttle packets back and forth from Storm while:
        // - Keeping consistent IPs/ports between all players of the game
        //   (even though they might differ due to NAT, LAN, etc.)
        // - Allowing us to easily get references to active rally-point routes
        let host = game_info.slots.iter().find(|x| x.id == game_info.host.id);
        let rest = game_info
            .slots
            .iter()
            .filter(|x| x.is_human() || x.is_observer())
            .filter(|x| x.id != game_info.host.id);
        let ip_to_routes = host
            .into_iter()
            .chain(rest)
            .enumerate()
            .filter_map(|(i, player)| {
                match routes.iter().find(|x| x.lobby_player_id == player.id) {
                    Some(route) => Some((Ipv4Addr::new(10, 27, 27, i as u8), route.clone())),
                    None => {
                        // There won't be a route for current player
                        None
                    }
                }
            })
            .collect::<HashMap<_, _>>();
        // Create the task which receives packets and forwards them to Storm
        let streams_done = ip_to_routes
            .iter()
            .map(|(&ip, route)| {
                let snp_send = snp_send_messages.clone();
                let stream = self
                    .rally_point
                    .listen_route_data(&route.route_id, &route.address);
                async move {
                    pin_mut!(stream);
                    while let Some(message) = stream.next().await {
                        match message {
                            Ok(message) => {
                                let message = snp::ReceivedMessage {
                                    from: ip,
                                    data: message,
                                };
                                snp_send.send(message);
                            }
                            Err(e) => {
                                // I don't think there's much sense to kill network
                                // for this error, should never happen and if it does
                                // then try to keep going.
                                error!("Rally-point receive stream error for ip {:?}: {}", ip, e);
                            }
                        }
                    }
                }
            })
            .collect::<Vec<_>>();
        let recv_task = future::join_all(streams_done).map(|_| ());

        let (cancel_token, canceler) = CancelToken::new();
        self.cancel_child_tasks.push(canceler);
        tokio::spawn(cancel_token.bind(recv_task));

        let ready = ReadyNetwork { ip_to_routes };
        self.network = NetworkState::Ready(ready);
        for waiting in self.waiting_for_network.drain(..) {
            let _ = waiting.send(Ok(()));
        }
    }
// If we have all parts needed to init network, do all of the remaining work
If we have all parts needed to init network, do all of the remaining work
If we have all parts needed to init network do all of the remaining work
fn check_network_ready(&mut self) {
        let game_info;
        let routes;
        let snp_send_messages;
        match self.network {
            NetworkState::Incomplete(ref mut i) => {
                if i.game_info.is_some() && i.routes.is_some() && i.snp_send_messages.is_some() {
                    game_info = i.game_info.take().unwrap();
                    routes = i.routes.take().unwrap();
                    snp_send_messages = i.snp_send_messages.take().unwrap();
                } else {
                    return;
                }
            }
            NetworkState::Ready(_) => return,
            NetworkState::Error(ref e) => {
                for send in self.waiting_for_network.drain(..) {
                    let _ = send.send(Err(e.clone()));
                }
                return;
            }
        }
        // Build an object mapping Fake-IP => rally-point route, ordered consistently between all
        // players (host first, then all other players ordered by slot). Computers are not
        // included, as we [obviously] won't be sending network traffic to them. This mapping
        // will be used by our SNP to shuttle packets back and forth from Storm while:
        // - Keeping consistent IPs/ports between all players of the game
        //   (even though they might differ due to NAT, LAN, etc.)
        // - Allowing us to easily get references to active rally-point routes
        let host = game_info.slots.iter().find(|x| x.id == game_info.host.id);
        let rest = game_info
            .slots
            .iter()
            .filter(|x| x.is_human() || x.is_observer())
            .filter(|x| x.id != game_info.host.id);
        let ip_to_routes = host
            .into_iter()
            .chain(rest)
            .enumerate()
            .filter_map(|(i, player)| {
                match routes.iter().find(|x| x.lobby_player_id == player.id) {
                    Some(route) => Some((Ipv4Addr::new(10, 27, 27, i as u8), route.clone())),
                    None => {
                        // There won't be a route for current player
                        None
                    }
                }
            })
            .collect::<HashMap<_, _>>();
        // Create the task which receives packets and forwards them to Storm
        let streams_done = ip_to_routes
            .iter()
            .map(|(&ip, route)| {
                let snp_send = snp_send_messages.clone();
                let stream = self
                    .rally_point
                    .listen_route_data(&route.route_id, &route.address);
                async move {
                    pin_mut!(stream);
                    while let Some(message) = stream.next().await {
                        match message {
                            Ok(message) => {
                                let message = snp::ReceivedMessage {
                                    from: ip,
                                    data: message,
                                };
                                snp_send.send(message);
                            }
                            Err(e) => {
                                // I don't think there's much sense to kill network
                                // for this error, should never happen and if it does
                                // then try to keep going.
                                error!("Rally-point receive stream error for ip {:?}: {}", ip, e);
                            }
                        }
                    }
                }
            })
            .collect::<Vec<_>>();
        let recv_task = future::join_all(streams_done).map(|_| ());
        let (cancel_token, canceler) = CancelToken::new();
        self.cancel_child_tasks.push(canceler);
        tokio::spawn(cancel_token.bind(recv_task));
        let ready = ReadyNetwork { ip_to_routes };
        self.network = NetworkState::Ready(ready);
        for waiting in self.waiting_for_network.drain(..) {
            let _ = waiting.send(Ok(()));
        }
    }
fn check_network_ready ( & mut self ) { let game_info ; let routes ; let snp_send_messages ; match self . network { NetworkState :: Incomplete ( ref mut i ) => { if i . game_info . is_some ( ) && i . routes . is_some ( ) && i . snp_send_messages . is_some ( ) { game_info = i . game_info . take ( ) . unwrap ( ) ; routes = i . routes . take ( ) . unwrap ( ) ; snp_send_messages = i . snp_send_messages . take ( ) . unwrap ( ) ; } else { return ; } } NetworkState :: Ready ( _ ) => return , NetworkState :: Error ( ref e ) => { for send in self . waiting_for_network . drain ( .. ) { let _ = send . send ( Err ( e . clone ( ) ) ) ; } return ; } } // Build an object mapping Fake-IP => rally-point route, ordered consistently between all // players (host first, then all other players ordered by slot). Computers are not // included, as we [obviously] won't be sending network traffic to them. This mapping // will be used by our SNP to shuttle packets back and forth from Storm while: // - Keeping consistent IPs/ports between all players of the game //   (even though they might differ due to NAT, LAN, etc.) // - Allowing us to easily get references to active rally-point routes let host = game_info . slots . iter ( ) . find ( | x | x . id == game_info . host . id ) ; let rest = game_info . slots . iter ( ) . filter ( | x | x . is_human ( ) || x . is_observer ( ) ) . filter ( | x | x . id != game_info . host . id ) ; let ip_to_routes = host . into_iter ( ) . chain ( rest ) . enumerate ( ) . filter_map ( | ( i , player ) | { match routes . iter ( ) . find ( | x | x . lobby_player_id == player . id ) { Some ( route ) => Some ( ( Ipv4Addr :: new ( 10 , 27 , 27 , i as u8 ) , route . clone ( ) ) ) , None => { // There won't be a route for current player None } } } ) . collect :: < HashMap < _ , _ > > ( ) ; // Create the task which receives packets and forwards them to Storm let streams_done = ip_to_routes . iter ( ) . map ( | ( & ip , route ) | { let snp_send = snp_send_messages . clone ( ) ; let stream = self . rally_point . listen_route_data ( & route . route_id , & route . address ) ; async move { pin_mut ! ( stream ) ; while let Some ( message ) = stream . next ( ) . await { match message { Ok ( message ) => { let message = snp :: ReceivedMessage { from : ip , data : message , } ; snp_send . send ( message ) ; } Err ( e ) => { // I don't think there's much sense to kill network // for this error, should never happen and if it does // then try to keep going. error ! ( " " ip e ) ; } } } } } ) . collect :: < Vec < _ > > ( ) ; let recv_task = future :: join_all ( streams_done ) . map ( | _ | ( ) ) ; let ( cancel_token , canceler ) = CancelToken :: new ( ) ; self . cancel_child_tasks . push ( canceler ) ; tokio :: spawn ( cancel_token . bind ( recv_task ) ) ; let ready = ReadyNetwork { ip_to_routes } ; self . network = NetworkState :: Ready ( ready ) ; for waiting in self . waiting_for_network . drain ( .. ) { let _ = waiting . send ( Ok ( ( ) ) ) ; } }
If we have all parts needed to init network, do all of the remaining work
If we have all parts needed to init network do all of the remaining work
&mut self
&mut self