#ifndef NETCODE_H
#define NETCODE_H
#include <stdint.h>
#if defined(__386__) || defined(i386) || defined(__i386__) \
|| defined(__X86) || defined(_M_IX86) \
|| defined(_M_X64) || defined(__x86_64__) \
|| defined(alpha) || defined(__alpha) || defined(__alpha__) \
|| defined(_M_ALPHA) \
|| defined(ARM) || defined(_ARM) || defined(__arm__) \
|| defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
|| defined(_WIN32_WCE) || defined(__NT__) \
|| defined(__MIPSEL__)
#define NETCODE_LITTLE_ENDIAN 1
#else
#define NETCODE_BIG_ENDIAN 1
#endif
#define NETCODE_PLATFORM_WINDOWS 1
#define NETCODE_PLATFORM_MAC 2
#define NETCODE_PLATFORM_UNIX 3
#if defined(_WIN32)
#define NETCODE_PLATFORM NETCODE_PLATFORM_WINDOWS
#elif defined(__APPLE__)
#define NETCODE_PLATFORM NETCODE_PLATFORM_MAC
#else
#define NETCODE_PLATFORM NETCODE_PLATFORM_UNIX
#endif
#define NETCODE_CONNECT_TOKEN_BYTES 2048
#define NETCODE_KEY_BYTES 32
#define NETCODE_MAC_BYTES 16
#define NETCODE_NONCE_BYTES 8
#define NETCODE_MAX_SERVERS_PER_CONNECT 32
#define NETCODE_CLIENT_STATE_CONNECT_TOKEN_EXPIRED -6
#define NETCODE_CLIENT_STATE_INVALID_CONNECT_TOKEN -5
#define NETCODE_CLIENT_STATE_CONNECTION_TIMED_OUT -4
#define NETCODE_CLIENT_STATE_CONNECTION_RESPONSE_TIMED_OUT -3
#define NETCODE_CLIENT_STATE_CONNECTION_REQUEST_TIMED_OUT -2
#define NETCODE_CLIENT_STATE_CONNECTION_DENIED -1
#define NETCODE_CLIENT_STATE_DISCONNECTED 0
#define NETCODE_CLIENT_STATE_SENDING_CONNECTION_REQUEST 1
#define NETCODE_CLIENT_STATE_SENDING_CONNECTION_RESPONSE 2
#define NETCODE_CLIENT_STATE_CONNECTED 3
#define NETCODE_SOCKET_IPV6 1
#define NETCODE_SOCKET_IPV4 2
#define NETCODE_MAX_CLIENTS 256
#define NETCODE_MAX_PACKET_SIZE 1200
#define NETCODE_LOG_LEVEL_NONE 0
#define NETCODE_LOG_LEVEL_INFO 1
#define NETCODE_LOG_LEVEL_ERROR 2
#define NETCODE_LOG_LEVEL_DEBUG 3
int netcode_init();
void netcode_term();
void netcode_log_level( int level );
void netcode_random_bytes( uint8_t * data, int bytes );
struct netcode_client_t * netcode_client_create( char * address, double time );
void netcode_client_destroy( struct netcode_client_t * client );
void netcode_client_connect( struct netcode_client_t * client, uint8_t * connect_token );
void netcode_client_update( struct netcode_client_t * client, double time );
uint64_t netcode_client_next_packet_sequence( struct netcode_client_t * client );
void netcode_client_send_packet( struct netcode_client_t * client, uint8_t * packet_data, int packet_bytes );
void * netcode_client_receive_packet( struct netcode_client_t * client, int * packet_bytes, uint64_t * packet_sequence );
void netcode_client_free_packet( struct netcode_client_t * client, void * packet );
void netcode_client_disconnect( struct netcode_client_t * client );
int netcode_client_state( struct netcode_client_t * client );
int netcode_client_index( struct netcode_client_t * client );
int netcode_client_max_clients( struct netcode_client_t * client );
int netcode_generate_connect_token( int num_server_addresses, char ** server_addresses, int expire_seconds, uint64_t client_id, uint64_t protocol_id, uint64_t sequence, uint8_t * private_key, uint8_t * connect_token );
struct netcode_server_t * netcode_server_create( char * bind_address, char * public_address, uint64_t protocol_id, uint8_t * private_key, double time );
void netcode_server_start( struct netcode_server_t * server, int max_clients );
void netcode_server_update( struct netcode_server_t * client, double time );
int netcode_server_client_connected( struct netcode_server_t * server, int client_index );
uint64_t netcode_server_client_id( struct netcode_server_t * server, int client_index );
void netcode_server_disconnect_client( struct netcode_server_t * server, int client_index );
void netcode_server_disconnect_all_clients( struct netcode_server_t * server );
uint64_t netcode_server_next_packet_sequence( struct netcode_server_t * server, int client_index );
void netcode_server_send_packet( struct netcode_server_t * server, int client_index, uint8_t * packet_data, int packet_bytes );
void * netcode_server_receive_packet( struct netcode_server_t * server, int client_index, int * packet_bytes, uint64_t * packet_sequence );
void netcode_server_free_packet( struct netcode_server_t * server, void * packet );
int netcode_server_num_clients_connected( struct netcode_server_t * server );
void * netcode_server_client_user_data( struct netcode_server_t * server, int client_index );
void netcode_server_destroy( struct netcode_server_t * server );
void netcode_sleep( double seconds );
double netcode_time();
#endif