Add network link to ue-server implementation #13

Open
dkanus wants to merge 23 commits from feature_link into master
3 changed files with 54 additions and 27 deletions
Showing only changes of commit 4f67a7b72c - Show all commits

View File

@ -1,3 +1,5 @@
//! Implements reader and writer to use when talking to UE2 game server.
use std::error::Error;
use std::io::{Read, Write};
use std::net::{SocketAddr, TcpListener};

View File

@ -1,3 +1,5 @@
//! Implements reader that receives data from UE2 game server.
use std::collections::VecDeque;
use std::str;
@ -32,16 +34,25 @@ enum ReadingState {
Payload,
}
/// For converting byte stream that is expected from the ue-server into actual messages.
/// For converting byte stream that is expected from the ue-server into actual messages.
///
/// Expected format is a sequence of either:
/// 1. [HEAD_UE_RECEIVED: marker byte | 1 byte]
/// [AMOUNT: amount of bytes received by ue-server since last update | 2 bytes: u16 BE]
/// 2. [HEAD_UE_MESSAGE: marker byte | 1 byte]
/// [LENGTH: length of the JSON message in utf8 encoding | 4 bytes: u32 BE]
/// [PAYLOAD: utf8-encoded string | `LENGTH` bytes]
/// On any invalid input enters into a failure state (can be checked by `is_broken()`) and
/// never recovers from it.
/// Use either `push_byte()` or `push()` to input byte stream from ue-server and `pop()` to
///
/// | Data | Length |
/// |---------|---------|
/// | [`HEAD_UE_RECEIVED`] (marker byte) | 1 byte |
/// | Amount of bytes received by ue-server since last update | 2 bytes: u16 BE|
///
/// or
///
/// | Data | Length |
/// |---------|---------|
/// | [`HEAD_UE_MESSAGE`] (marker byte) | 1 byte|
/// | `LENGTH` of the JSON message in utf8 encoding | 4 bytes: u32 BE|
/// | UTF8-encoded string | `LENGTH` bytes|
///
/// On any invalid input enters into a failure state (can be checked by `is_broken()`) and never recovers from it.
/// Use either `push_byte()` or `push()` to input byte stream from ue-server and `pop()` to
/// retrieve resulting messages.
pub struct MessageReader {
is_broken: bool,

View File

@ -1,3 +1,5 @@
//! Implements writer that sends data to UE2 game server.
use std::cmp::{max, min};
use std::collections::VecDeque;
use std::convert::TryFrom;
@ -10,30 +12,42 @@ const UE_INPUT_BUFFER: usize = 4095;
// Minimal payload size (in bytes) to send, unless there is not enough data left
const MIN_PAYLOAD_SIZE: usize = 50;
/// For converting byte stream that is expected from the ue-server into actual messages.
/// Conversion process has two steps:
/// 1. Every string message is converted into it's utf8 representation and is pre-pended with
/// it's own length in format:
///
/// | Data | Length |
dkanus marked this conversation as resolved Outdated

Elaborate => "Conversion happens in two steps"?

Elaborate => "Conversion happens in two steps"?

Changed in upcoming patch.

Changed in upcoming patch.
/// |---------|---------|
dkanus marked this conversation as resolved Outdated

it's => its
pre-pended => prepended
"utf8 representation"?

Can be simplified => Every message is a length-prefixed array of utf8 bytes.

it's => its pre-pended => prepended "utf8 representation"? Can be simplified => Every message is a length-prefixed array of utf8 bytes.

Fixed in upcoming patch.

Fixed in upcoming patch.
/// | Message `LENGTH` | 4 bytes: u32 BE |
/// | UTF8-encoded string | `LENGTH` bytes|
dkanus marked this conversation as resolved Outdated

Remove "in utf8 encoding", because it's wrong and misleading - length is sent as u32, not as string.

Remove "in utf8 encoding", because it's wrong and misleading - length is sent as u32, not as string.
///
/// Resulting byte sequences from all the messages then concatenated, in order, into
dkanus marked this conversation as resolved Outdated

the messages => messages
then => is then
"in order" - in what order?

the messages => messages then => is then "in order" - in what order?

Changed in upcoming patch.

Changed in upcoming patch.
/// a single data stream.
///
/// 2. Resulting data stream is then separated into "chunks" that can be accepted by
dkanus marked this conversation as resolved Outdated

But Writer doesn't send anything?

But Writer doesn't send anything?

Fixed in upcoming patch.

Fixed in upcoming patch.
/// the ue-server (each no longer than `UE_INPUT_BUFFER` in total) and are sent in a format:
///
/// | Data | Length |
/// |---------|---------|
/// | Chunk `LENGTH` | 2 bytes: u16 BE |
/// | UTF8-encoded string | `LENGTH` bytes|
///
/// Use `push()` to input string messages and `try_pop()` to retrieve next chunk, if ue-server
dkanus marked this conversation as resolved Outdated

"has depleted all it's data." => "has successfully sent all data."?

"has depleted all it's data." => "has successfully sent all data."?

Changed in upcoming patch.

Changed in upcoming patch.
/// can accept it.
/// NOTE: `try_pop()` can return `None` even if not all message data has been transferred,
/// in case ue-server's buffer does not have enough space.
///
/// Call `update_ue_received_bytes()` to update `MessageWriter`'s information about
/// how many bytes ue-server has received so far.
///
/// Use `is_empty()` call to check for whether `MessageWriter` has depleted all it's data.
pub struct MessageWriter {
sent_bytes: u64,
ue_received_bytes: u64,
pending_data: VecDeque<u8>,
}
/// For converting byte stream that is expected from the ue-server into actual messages.
/// Conversion process has two steps:
/// 1. Every string message is converted into it's utf8 representation and is pre-pended with
/// it's own length in format:
/// [MESSAGE_LENGTH: length of the message in utf8 encoding | 4 bytes: u32 BE]
/// [MESSAGE: utf8-encoded string | `MESSAGE_LENGTH` bytes]
/// Resulting byte sequences from all the messages then concatenated, in order, into
/// a single data stream.
/// 2. Resulting data stream is then separated into "chunks" that can be accepted by
/// the ue-server (each no longer than `UE_INPUT_BUFFER` in total) and are sent in a format:
/// [LENGTH: length of the chunk | 2 bytes: u16 BE]
/// [PAYLOAD: utf8-encoded string | `LENGTH` bytes]
/// Use `push()` to input string messages and `try_pop()` to retrieve next chunk, if ue-server
/// can accept it. Call `update_ue_received_bytes()` to update `MessageWriter`'s information about
/// how many bytes ue-server has received so far.
/// NOTE: `try_pop()` can return `None` even if not all message data has been transferred,
/// in case ue-server's buffer does not have enough space. Use `is_empty()` call to check for
/// whether `MessageWriter` has depleted all it's data.
impl MessageWriter {
pub fn new() -> MessageWriter {
MessageWriter {