rust/hedgewars-server/src/protocol.rs
author alfadur
Tue, 01 Feb 2022 02:23:35 +0300
changeset 15831 7d0f747afcb8
parent 15804 747278149393
child 15832 a4d505a32879
permissions -rw-r--r--
move server network to tokio
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15831
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
     1
use bytes::{Buf, BufMut, BytesMut};
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
     2
use log::*;
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
     3
use std::{io, io::ErrorKind, marker::Unpin};
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
     4
use tokio::io::AsyncReadExt;
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
     5
15804
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
     6
use hedgewars_network_protocol::{
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
     7
    messages::HwProtocolMessage,
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
     8
    parser::{malformed_message, message},
747278149393 Extract network protocol into a separate crate
unc0rr
parents: 15795
diff changeset
     9
};
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    10
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    11
pub struct ProtocolDecoder {
15831
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    12
    buffer: BytesMut,
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    13
    is_recovering: bool,
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    14
}
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    15
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    16
impl ProtocolDecoder {
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    17
    pub fn new() -> ProtocolDecoder {
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    18
        ProtocolDecoder {
15831
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    19
            buffer: BytesMut::with_capacity(1024),
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    20
            is_recovering: false,
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    21
        }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    22
    }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    23
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    24
    fn recover(&mut self) -> bool {
15831
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    25
        self.is_recovering = match malformed_message(&self.buffer[..]) {
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    26
            Ok((tail, ())) => {
15831
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    27
                let remaining = tail.len();
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    28
                self.buffer.advance(self.buffer.len() - remaining);
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    29
                false
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    30
            }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    31
            _ => {
15831
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    32
                self.buffer.clear();
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    33
                true
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    34
            }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    35
        };
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    36
        !self.is_recovering
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    37
    }
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    38
15831
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    39
    fn extract_message(&mut self) -> Option<HwProtocolMessage> {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    40
        if !self.is_recovering || self.recover() {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    41
            match message(&self.buffer[..]) {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    42
                Ok((tail, message)) => {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    43
                    let remaining = tail.len();
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    44
                    self.buffer.advance(self.buffer.len() - remaining);
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    45
                    return Some(message);
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    46
                }
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    47
                Err(nom::Err::Incomplete(_)) => {}
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    48
                Err(nom::Err::Failure(e) | nom::Err::Error(e)) => {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    49
                    debug!("Invalid message: {:?}", e);
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    50
                    self.recover();
14795
add191d825f4 add parser error handling
alfadur
parents: 14775
diff changeset
    51
                }
14457
98ef2913ec73 Apply rustfmt to all files
unc0rr
parents: 14415
diff changeset
    52
            }
12136
e25a82ce2374 - Render messages to string
unc0rr
parents: 12133
diff changeset
    53
        }
15831
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    54
        None
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    55
    }
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    56
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    57
    pub async fn read_from<R: AsyncReadExt + Unpin>(
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    58
        &mut self,
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    59
        stream: &mut R,
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    60
    ) -> Option<HwProtocolMessage> {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    61
        loop {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    62
            if !self.buffer.has_remaining() {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    63
                let count = stream.read_buf(&mut self.buffer).await.ok()?;
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    64
                if count == 0 {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    65
                    return None;
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    66
                }
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    67
            }
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    68
            while !self.buffer.is_empty() {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    69
                if let Some(result) = self.extract_message() {
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    70
                    return Some(result);
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    71
                }
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    72
            }
7d0f747afcb8 move server network to tokio
alfadur
parents: 15804
diff changeset
    73
        }
12129
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    74
    }
07972a8c2433 - Start protocol parser implementation
unc0rr
parents:
diff changeset
    75
}