Skip to content

Commit

Permalink
Inital commit of project and start of client
Browse files Browse the repository at this point in the history
  • Loading branch information
vvanders committed Mar 2, 2017
0 parents commit e6a8678
Show file tree
Hide file tree
Showing 8 changed files with 318 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
target
Cargo.lock
3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "netcode"]
path = netcode
url = https://github.com/networkprotocol/netcode.io.git
11 changes: 11 additions & 0 deletions Cargo.toml
@@ -0,0 +1,11 @@
[package]
name = "netcode"
version = "0.1.0"
authors = ["Val Vanderschaegen <valere.vanderschaegen@gmail.com>"]
build = "build.rs"
links = "libnetcode"

[dependencies]

[build-dependencies]
gcc = "0.3.43"
14 changes: 14 additions & 0 deletions build.rs
@@ -0,0 +1,14 @@
extern crate gcc;

pub fn main() {
gcc::Config::new()
.file("netcode/netcode.c")
.include("netcode")
.include("netcode/windows")
.define("NETCODE_ENABLE_TESTS", Some("0"))
.define("NDEBUG", Some("0"))
.compile("libnetcode.a");

println!("cargo:rustc-link-search=native=netcode/windows");
println!("cargo:rustc-link-lib=static=sodium-release");
}
1 change: 1 addition & 0 deletions netcode
Submodule netcode added at 8a716d
151 changes: 151 additions & 0 deletions src/lib.rs
@@ -0,0 +1,151 @@
mod netcode;
mod util;

use std::ffi::CString;

pub enum ClientError {
Create,
Token
}

pub enum ClientState {
ConnectTokenExpired,
InvalidConnectToken,
ConnectionTimedOut,
ConnectionResponseTimeout,
ConnectionRequestTimeout,
ConnectionDenied,
Disconnected,
SendingConnectionRequest,
SendingConnectionResponse,
Connected,
Unknown
}

impl ClientState {
fn from_code(code: i32) -> ClientState {
match code {
netcode::NETCODE_CLIENT_STATE_CONNECT_TOKEN_EXPIRED => ClientState::ConnectTokenExpired,
netcode::NETCODE_CLIENT_STATE_INVALID_CONNECT_TOKEN => ClientState::InvalidConnectToken,
netcode::NETCODE_CLIENT_STATE_CONNECTION_TIMED_OUT => ClientState::ConnectionTimedOut,
netcode::NETCODE_CLIENT_STATE_CONNECTION_RESPONSE_TIMEOUT => ClientState::ConnectionResponseTimeout,
netcode::NETCODE_CLIENT_STATE_CONNECTION_REQUEST_TIMEOUT => ClientState::ConnectionRequestTimeout,
netcode::NETCODE_CLIENT_STATE_CONNECTION_DENIED => ClientState::ConnectionDenied,
netcode::NETCODE_CLIENT_STATE_DISCONNECTED => ClientState::Disconnected,
netcode::NETCODE_CLIENT_STATE_SENDING_CONNECTION_REQUEST => ClientState::SendingConnectionRequest,
netcode::NETCODE_CLIENT_STATE_SENDING_CONNECTION_RESPONSE => ClientState::SendingConnectionResponse,
netcode::NETCODE_CLIENT_STATE_CONNECTED => ClientState::Connected,
_ => ClientState::Unknown
}
}
}

pub struct Client {
handle: *mut netcode::netcode_client_t
}

impl Client {
pub fn new_with_host<S>(client_address: S, token: &ConnectToken) -> Result<Client, ClientError> where S: Into<String> {
util::global_init();

unsafe {
let cstr_client_address = CString::new(client_address.into()).unwrap();
let client_ptr = netcode::netcode_client_create(cstr_client_address.as_ptr(), 0.0);

if client_ptr == std::ptr::null_mut() {
return Err(ClientError::Create)
}

//Construct client so we destroy it if an further step fails
let client = Client {
handle: client_ptr
};

netcode::netcode_client_connect(client_ptr, token.token.as_ptr());

Ok(client)
}
}

pub fn new(token: &ConnectToken) -> Result<Client, ClientError> {
Self::new_with_host("::", token)
}

pub fn state(&self) -> ClientState {
unsafe {
ClientState::from_code(netcode::netcode_client_state(self.handle))
}
}
}

impl Drop for Client {
fn drop(&mut self) {
unsafe {
netcode::netcode_client_destroy(self.handle);
util::global_term();
}
}
}

pub struct ConnectToken {
token: [u8; netcode::NETCODE_CONNECT_TOKEN_BYTES as usize]
}

impl ConnectToken {
pub fn from_bytes<I>(bytes: I) -> ConnectToken where I: Iterator<Item=u8> {
let mut token = [0; netcode::NETCODE_CONNECT_TOKEN_BYTES];

for (i,b) in bytes.enumerate() {
token[i] = b;
}

ConnectToken { token: token }
}

pub fn from_hosts<I>(hosts: I, private_key: &mut [u8; netcode::NETCODE_KEY_BYTES], expire: i32, client_id: u64, protocol: u64, sequence: u64)
-> Result<ConnectToken, ClientError>
where I: Iterator<Item=String> {
let mut host_list_ptr = [std::ptr::null_mut(); netcode::NETCODE_MAX_SERVERS_PER_CONNECT];
let mut host_count = 0;

for (i,host) in hosts.enumerate().take(netcode::NETCODE_MAX_SERVERS_PER_CONNECT) {
let cstr = CString::new(host).unwrap();
host_list_ptr[i] = cstr.into_raw();
host_count += 1;
}

let mut token = [0; netcode::NETCODE_CONNECT_TOKEN_BYTES];

unsafe {
match netcode::netcode_generate_connect_token(host_count,
host_list_ptr.as_mut_ptr(),
expire,
client_id,
protocol,
sequence,
private_key.as_mut_ptr(),
token.as_mut_ptr()
) {
0 => Ok(ConnectToken { token: token }),
_ => Err(ClientError::Token)
}
}

}
}

pub struct Server {
handle: *mut netcode::netcode_server_t
}

impl Server {
}

impl Drop for Server {
fn drop(&mut self) {
unsafe {
netcode::netcode_server_destroy(self.handle);
util::global_term();
}
}
}
115 changes: 115 additions & 0 deletions src/netcode.rs
@@ -0,0 +1,115 @@
pub const NETCODE_CONNECT_TOKEN_BYTES: usize = 4096;
pub const NETCODE_KEY_BYTES: usize = 32;
pub const NETCODE_MAC_BYTES: usize = 16;
pub const NETCODE_NONCE_BYTES: usize = 8;
pub const NETCODE_MAX_SERVERS_PER_CONNECT: usize = 16;

pub const NETCODE_CLIENT_STATE_CONNECT_TOKEN_EXPIRED: ::std::os::raw::c_int =
-6;
pub const NETCODE_CLIENT_STATE_INVALID_CONNECT_TOKEN: ::std::os::raw::c_int =
-5;
pub const NETCODE_CLIENT_STATE_CONNECTION_TIMED_OUT: ::std::os::raw::c_int =
-4;
pub const NETCODE_CLIENT_STATE_CONNECTION_RESPONSE_TIMEOUT:
::std::os::raw::c_int =
-3;
pub const NETCODE_CLIENT_STATE_CONNECTION_REQUEST_TIMEOUT:
::std::os::raw::c_int =
-2;
pub const NETCODE_CLIENT_STATE_CONNECTION_DENIED: ::std::os::raw::c_int = -1;
pub const NETCODE_CLIENT_STATE_DISCONNECTED: ::std::os::raw::c_int = 0;
pub const NETCODE_CLIENT_STATE_SENDING_CONNECTION_REQUEST:
::std::os::raw::c_int =
1;
pub const NETCODE_CLIENT_STATE_SENDING_CONNECTION_RESPONSE:
::std::os::raw::c_int =
2;
pub const NETCODE_CLIENT_STATE_CONNECTED: ::std::os::raw::c_int = 3;

pub const NETCODE_SOCKET_IPV6: ::std::os::raw::c_uint = 1;
pub const NETCODE_SOCKET_IPV4: ::std::os::raw::c_uint = 2;

pub const NETCODE_MAX_CLIENTS: usize = 256;
pub const NETCODE_MAX_PACKET_SIZE: usize = 1200;

pub const NETCODE_LOG_LEVEL_NONE: ::std::os::raw::c_uint = 0;
pub const NETCODE_LOG_LEVEL_INFO: ::std::os::raw::c_uint = 1;
pub const NETCODE_LOG_LEVEL_ERROR: ::std::os::raw::c_uint = 2;
pub const NETCODE_LOG_LEVEL_DEBUG: ::std::os::raw::c_uint = 3;

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct netcode_client_t;

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct netcode_server_t;

extern "C" {
pub fn netcode_init() -> ::std::os::raw::c_int;
pub fn netcode_term();
pub fn netcode_log_level(level: ::std::os::raw::c_int);
pub fn netcode_random_bytes(data: *mut u8, bytes: ::std::os::raw::c_int);

pub fn netcode_client_create(address: *const ::std::os::raw::c_char,
time: f64) -> *mut netcode_client_t;
pub fn netcode_client_destroy(client: *mut netcode_client_t);
pub fn netcode_client_connect(client: *mut netcode_client_t,
connect_token: *const u8);
pub fn netcode_client_update(client: *mut netcode_client_t, time: f64);
pub fn netcode_client_send_packet(client: *mut netcode_client_t,
packet_data: *mut u8,
packet_bytes: ::std::os::raw::c_int);
pub fn netcode_client_receive_packet(client: *mut netcode_client_t,
packet_bytes:
*mut ::std::os::raw::c_int)
-> *mut ::std::os::raw::c_void;
pub fn netcode_client_free_packet(client: *mut netcode_client_t,
packet: *mut ::std::os::raw::c_void);
pub fn netcode_client_disconnect(client: *mut netcode_client_t);
pub fn netcode_client_state(client: *const netcode_client_t)
-> ::std::os::raw::c_int;
pub fn netcode_client_index(client: *mut netcode_client_t)
-> ::std::os::raw::c_int;
pub fn netcode_generate_connect_token(num_server_addresses:
::std::os::raw::c_int,
server_addresses:
*mut *mut ::std::os::raw::c_char,
expire_seconds:
::std::os::raw::c_int,
client_id: u64, protocol_id: u64,
sequence: u64, private_key: *mut u8,
connect_token: *mut u8)
-> ::std::os::raw::c_int;

pub fn netcode_server_create(bind_address: *mut ::std::os::raw::c_char,
public_address: *mut ::std::os::raw::c_char,
protocol_id: u64, private_key: *mut u8,
time: f64) -> *mut netcode_server_t;
pub fn netcode_server_start(server: *mut netcode_server_t,
max_clients: ::std::os::raw::c_int);
pub fn netcode_server_update(client: *mut netcode_server_t, time: f64);
pub fn netcode_server_client_connected(server: *mut netcode_server_t,
client_index:
::std::os::raw::c_int)
-> ::std::os::raw::c_int;
pub fn netcode_server_disconnect_client(server: *mut netcode_server_t,
client_index:
::std::os::raw::c_int);
pub fn netcode_server_disconnect_all_clients(server:
*mut netcode_server_t);
pub fn netcode_server_send_packet(server: *mut netcode_server_t,
client_index: ::std::os::raw::c_int,
packet_data: *mut u8,
packet_bytes: ::std::os::raw::c_int);
pub fn netcode_server_receive_packet(server: *mut netcode_server_t,
client_index: ::std::os::raw::c_int,
packet_bytes:
*mut ::std::os::raw::c_int)
-> *mut ::std::os::raw::c_void;
pub fn netcode_server_free_packet(server: *mut netcode_server_t,
packet: *mut ::std::os::raw::c_void);
pub fn netcode_server_num_clients_connected(server: *mut netcode_server_t)
-> ::std::os::raw::c_int;
pub fn netcode_server_destroy(server: *mut netcode_server_t);
}
21 changes: 21 additions & 0 deletions src/util.rs
@@ -0,0 +1,21 @@
use std::sync::atomic;

use netcode;

static mut netcode_init_count: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;

pub fn global_init() {
unsafe {
netcode_init_count.fetch_add(1, atomic::Ordering::SeqCst);
netcode::netcode_init();
}
}

pub fn global_term() {
unsafe {
let active = netcode_init_count.fetch_sub(1, atomic::Ordering::SeqCst);
if active == 0 {
netcode::netcode_term();
}
}
}

0 comments on commit e6a8678

Please sign in to comment.