mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-14 03:58:18 +00:00
major update. server clean up and much added documentation
This commit is contained in:
parent
3705064b10
commit
9d632dd826
|
@ -43,7 +43,7 @@ const int prediction_margin = 7; /* magic network prediction value */
|
||||||
NETCLIENT *net;
|
NETCLIENT *net;
|
||||||
|
|
||||||
/* TODO: ugly, fix me */
|
/* TODO: ugly, fix me */
|
||||||
extern void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *info);
|
extern void client_serverbrowse_set(NETADDR *addr, int request, SERVER_INFO *info);
|
||||||
|
|
||||||
static int snapshot_part;
|
static int snapshot_part;
|
||||||
static int64 local_start_time;
|
static int64 local_start_time;
|
||||||
|
@ -53,7 +53,7 @@ static float frametime = 0.0001f;
|
||||||
static float frametime_low = 1.0f;
|
static float frametime_low = 1.0f;
|
||||||
static float frametime_high = 0.0f;
|
static float frametime_high = 0.0f;
|
||||||
static int frames = 0;
|
static int frames = 0;
|
||||||
static NETADDR4 server_address;
|
static NETADDR server_address;
|
||||||
static int window_must_refocus = 0;
|
static int window_must_refocus = 0;
|
||||||
static int snaploss = 0;
|
static int snaploss = 0;
|
||||||
static int snapcrcerrors = 0;
|
static int snapcrcerrors = 0;
|
||||||
|
@ -490,10 +490,12 @@ void client_connect(const char *server_address_str)
|
||||||
if(port_str)
|
if(port_str)
|
||||||
port = atoi(port_str);
|
port = atoi(port_str);
|
||||||
|
|
||||||
if(net_host_lookup(buf, port, &server_address) != 0)
|
/* TODO: IPv6 support */
|
||||||
|
if(net_host_lookup(buf, &server_address, NETTYPE_IPV4) != 0)
|
||||||
dbg_msg("client", "could not find the address of %s, connecting to localhost", buf);
|
dbg_msg("client", "could not find the address of %s, connecting to localhost", buf);
|
||||||
|
|
||||||
rcon_authed = 0;
|
rcon_authed = 0;
|
||||||
|
server_address.port = port;
|
||||||
netclient_connect(net, &server_address);
|
netclient_connect(net, &server_address);
|
||||||
client_set_state(CLIENTSTATE_CONNECTING);
|
client_set_state(CLIENTSTATE_CONNECTING);
|
||||||
|
|
||||||
|
@ -534,6 +536,8 @@ static int client_load_data()
|
||||||
extern int snapshot_data_rate[0xffff];
|
extern int snapshot_data_rate[0xffff];
|
||||||
extern int snapshot_data_updates[0xffff];
|
extern int snapshot_data_updates[0xffff];
|
||||||
|
|
||||||
|
const char *modc_getitemname(int type);
|
||||||
|
|
||||||
static void client_debug_render()
|
static void client_debug_render()
|
||||||
{
|
{
|
||||||
static NETSTATS prev, current;
|
static NETSTATS prev, current;
|
||||||
|
@ -555,29 +559,50 @@ static void client_debug_render()
|
||||||
net_stats(¤t);
|
net_stats(¤t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
eth = 14
|
||||||
|
ip = 20
|
||||||
|
udp = 8
|
||||||
|
total = 42
|
||||||
|
*/
|
||||||
|
|
||||||
frametime_avg = frametime_avg*0.9f + frametime*0.1f;
|
frametime_avg = frametime_avg*0.9f + frametime*0.1f;
|
||||||
str_format(buffer, sizeof(buffer), "ticks: %8d %8d send: %5d/%3d recv: %5d/%3d snaploss: %d mem %dk gfxmem: %dk fps: %3d",
|
str_format(buffer, sizeof(buffer), "ticks: %8d %8d snaploss: %d mem %dk gfxmem: %dk fps: %3d",
|
||||||
current_tick, current_predtick,
|
current_tick, current_predtick,
|
||||||
(current.sent_bytes-prev.sent_bytes),
|
|
||||||
(current.sent_packets-prev.sent_packets),
|
|
||||||
(current.recv_bytes-prev.recv_bytes),
|
|
||||||
(current.recv_packets-prev.recv_packets),
|
|
||||||
snaploss,
|
snaploss,
|
||||||
mem_allocated()/1024,
|
mem_allocated()/1024,
|
||||||
gfx_memory_usage()/1024,
|
gfx_memory_usage()/1024,
|
||||||
(int)(1.0f/frametime_avg));
|
(int)(1.0f/frametime_avg));
|
||||||
gfx_quads_text(2, 2, 16, buffer);
|
gfx_quads_text(2, 2, 16, buffer);
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
int send_packets = (current.sent_packets-prev.sent_packets);
|
||||||
|
int send_bytes = (current.sent_bytes-prev.sent_bytes);
|
||||||
|
int send_total = send_bytes + send_packets*42;
|
||||||
|
int recv_packets = (current.recv_packets-prev.recv_packets);
|
||||||
|
int recv_bytes = (current.recv_bytes-prev.recv_bytes);
|
||||||
|
int recv_total = recv_bytes + recv_packets*42;
|
||||||
|
|
||||||
|
if(!send_packets) send_packets++;
|
||||||
|
if(!recv_packets) recv_packets++;
|
||||||
|
str_format(buffer, sizeof(buffer), "send: %3d %5d+%4d=%5d (%3d kbps) avg: %5d\nrecv: %3d %5d+%4d=%5d (%3d kbps) avg: %5d",
|
||||||
|
send_packets, send_bytes, send_packets*42, send_total, (send_total*8)/1024, send_bytes/send_packets,
|
||||||
|
recv_packets, recv_bytes, recv_packets*42, recv_total, (recv_total*8)/1024, recv_bytes/recv_packets);
|
||||||
|
gfx_quads_text(2, 14, 16, buffer);
|
||||||
|
}
|
||||||
/* render rates */
|
/* render rates */
|
||||||
{
|
{
|
||||||
|
int y = 0;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 256; i++)
|
for(i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
if(snapshot_data_rate[i])
|
if(snapshot_data_rate[i])
|
||||||
{
|
{
|
||||||
str_format(buffer, sizeof(buffer), "%4d : %8d %8d %8d", i, snapshot_data_rate[i]/8, snapshot_data_updates[i],
|
str_format(buffer, sizeof(buffer), "%4d %20s: %8d %8d %8d", i, modc_getitemname(i), snapshot_data_rate[i]/8, snapshot_data_updates[i],
|
||||||
(snapshot_data_rate[i]/snapshot_data_updates[i])/8);
|
(snapshot_data_rate[i]/snapshot_data_updates[i])/8);
|
||||||
gfx_quads_text(2, 100+i*8, 16, buffer);
|
gfx_quads_text(2, 100+y*12, 16, buffer);
|
||||||
|
y++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -684,13 +709,13 @@ static void client_process_packet(NETCHUNK *packet)
|
||||||
memcmp(packet->data, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)) == 0)
|
memcmp(packet->data, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)) == 0)
|
||||||
{
|
{
|
||||||
int size = packet->data_size-sizeof(SERVERBROWSE_LIST);
|
int size = packet->data_size-sizeof(SERVERBROWSE_LIST);
|
||||||
int num = size/sizeof(NETADDR4);
|
int num = size/sizeof(NETADDR);
|
||||||
NETADDR4 *addrs = (NETADDR4 *)((char*)packet->data+sizeof(SERVERBROWSE_LIST));
|
NETADDR *addrs = (NETADDR *)((char*)packet->data+sizeof(SERVERBROWSE_LIST));
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < num; i++)
|
for(i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
NETADDR4 addr = addrs[i];
|
NETADDR addr = addrs[i];
|
||||||
SERVER_INFO info = {0};
|
SERVER_INFO info = {0};
|
||||||
|
|
||||||
#if defined(CONF_ARCH_ENDIAN_BIG)
|
#if defined(CONF_ARCH_ENDIAN_BIG)
|
||||||
|
@ -1016,12 +1041,16 @@ static void client_process_packet(NETCHUNK *packet)
|
||||||
purgetick = delta_tick;
|
purgetick = delta_tick;
|
||||||
snapsize = snapshot_unpack_delta(deltashot, (SNAPSHOT*)tmpbuffer3, deltadata, deltasize);
|
snapsize = snapshot_unpack_delta(deltashot, (SNAPSHOT*)tmpbuffer3, deltadata, deltasize);
|
||||||
if(snapsize < 0)
|
if(snapsize < 0)
|
||||||
|
{
|
||||||
|
dbg_msg("client", "delta unpack failed!");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(msg != NETMSG_SNAPEMPTY && snapshot_crc((SNAPSHOT*)tmpbuffer3) != crc)
|
if(msg != NETMSG_SNAPEMPTY && snapshot_crc((SNAPSHOT*)tmpbuffer3) != crc)
|
||||||
{
|
{
|
||||||
if(config.debug)
|
if(config.debug)
|
||||||
dbg_msg("client", "snapshot crc error %d", snapcrcerrors);
|
dbg_msg("client", "snapshot crc error #%d - tick=%d wantedcrc=%d gotcrc=%d compressed_size=%d", snapcrcerrors, game_tick, crc, snapshot_crc((SNAPSHOT*)tmpbuffer3), complete_size);
|
||||||
|
|
||||||
snapcrcerrors++;
|
snapcrcerrors++;
|
||||||
if(snapcrcerrors > 10)
|
if(snapcrcerrors > 10)
|
||||||
{
|
{
|
||||||
|
@ -1248,7 +1277,7 @@ extern void editor_init();
|
||||||
|
|
||||||
static void client_run()
|
static void client_run()
|
||||||
{
|
{
|
||||||
NETADDR4 bindaddr;
|
NETADDR bindaddr;
|
||||||
int64 reporttime = time_get();
|
int64 reporttime = time_get();
|
||||||
int64 reportinterval = time_freq()*1;
|
int64 reportinterval = time_freq()*1;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern NETCLIENT *net;
|
||||||
typedef struct SERVERENTRY_t SERVERENTRY;
|
typedef struct SERVERENTRY_t SERVERENTRY;
|
||||||
struct SERVERENTRY_t
|
struct SERVERENTRY_t
|
||||||
{
|
{
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
int64 request_time;
|
int64 request_time;
|
||||||
int got_info;
|
int got_info;
|
||||||
SERVER_INFO info;
|
SERVER_INFO info;
|
||||||
|
@ -264,7 +264,7 @@ static void client_serverbrowse_remove_request(SERVERENTRY *entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *info)
|
void client_serverbrowse_set(NETADDR *addr, int request, SERVER_INFO *info)
|
||||||
{
|
{
|
||||||
int hash = addr->ip[0];
|
int hash = addr->ip[0];
|
||||||
SERVERENTRY *entry = 0;
|
SERVERENTRY *entry = 0;
|
||||||
|
@ -272,7 +272,7 @@ void client_serverbrowse_set(NETADDR4 *addr, int request, SERVER_INFO *info)
|
||||||
entry = serverlist_ip[hash];
|
entry = serverlist_ip[hash];
|
||||||
while(entry)
|
while(entry)
|
||||||
{
|
{
|
||||||
if(net_addr4_cmp(&entry->addr, addr) == 0)
|
if(net_addr_comp(&entry->addr, addr) == 0)
|
||||||
{
|
{
|
||||||
/* update the server that we already have */
|
/* update the server that we already have */
|
||||||
if(!serverlist_lan)
|
if(!serverlist_lan)
|
||||||
|
@ -377,7 +377,7 @@ void client_serverbrowse_refresh(int lan)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
NETCHUNK p;
|
NETCHUNK p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -235,11 +235,11 @@ enum
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char hostname[128];
|
char hostname[128];
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
|
|
||||||
/* these are used for lookups */
|
/* these are used for lookups */
|
||||||
struct {
|
struct {
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
int result;
|
int result;
|
||||||
void *thread;
|
void *thread;
|
||||||
volatile int state;
|
volatile int state;
|
||||||
|
@ -264,7 +264,7 @@ void lookup_thread(void *user)
|
||||||
for(i = 0; i < info->num; i++)
|
for(i = 0; i < info->num; i++)
|
||||||
{
|
{
|
||||||
int index = info->start+i;
|
int index = info->start+i;
|
||||||
master_servers[index].lookup.result = net_host_lookup(master_servers[index].hostname, 8300, &master_servers[index].lookup.addr);
|
master_servers[index].lookup.result = net_host_lookup(master_servers[index].hostname, &master_servers[index].lookup.addr, NETTYPE_IPV4);
|
||||||
master_servers[index].lookup.state = STATE_RESULT;
|
master_servers[index].lookup.state = STATE_RESULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,6 +304,7 @@ void mastersrv_update()
|
||||||
if(master_servers[i].lookup.result == 0)
|
if(master_servers[i].lookup.result == 0)
|
||||||
{
|
{
|
||||||
master_servers[i].addr = master_servers[i].lookup.addr;
|
master_servers[i].addr = master_servers[i].lookup.addr;
|
||||||
|
master_servers[i].addr.port = 8300;
|
||||||
}
|
}
|
||||||
master_servers[i].lookup.state = STATE_PROCESSED;
|
master_servers[i].lookup.state = STATE_PROCESSED;
|
||||||
}
|
}
|
||||||
|
@ -332,7 +333,7 @@ int mastersrv_refreshing()
|
||||||
return needs_update;
|
return needs_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETADDR4 mastersrv_get(int index)
|
NETADDR mastersrv_get(int index)
|
||||||
{
|
{
|
||||||
return master_servers[index].addr;
|
return master_servers[index].addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,5 +24,5 @@ int mastersrv_refresh_addresses();
|
||||||
void mastersrv_update();
|
void mastersrv_update();
|
||||||
int mastersrv_refreshing();
|
int mastersrv_refreshing();
|
||||||
void mastersrv_dump_servers();
|
void mastersrv_dump_servers();
|
||||||
NETADDR4 mastersrv_get(int index);
|
NETADDR mastersrv_get(int index);
|
||||||
const char *mastersrv_name(int index);
|
const char *mastersrv_name(int index);
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#ifndef ENGINE_IF_CLIENT_H
|
#ifndef ENGINE_IF_CLIENT_H
|
||||||
#define ENGINE_IF_CLIENT_H
|
#define ENGINE_IF_CLIENT_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
Title: Client Interface
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Section: Constants
|
Section: Constants
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +25,6 @@ enum
|
||||||
CLIENTSTATE_ONLINE,
|
CLIENTSTATE_ONLINE,
|
||||||
CLIENTSTATE_QUITING,
|
CLIENTSTATE_QUITING,
|
||||||
|
|
||||||
|
|
||||||
/* Constants: Image Formats
|
/* Constants: Image Formats
|
||||||
IMG_AUTO - Lets the engine choose the format.
|
IMG_AUTO - Lets the engine choose the format.
|
||||||
IMG_RGB - 8-Bit uncompressed RGB
|
IMG_RGB - 8-Bit uncompressed RGB
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#ifndef ENGINE_IF_GFX_H
|
#ifndef ENGINE_IF_GFX_H
|
||||||
#define ENGINE_IF_GFX_H
|
#define ENGINE_IF_GFX_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
Title: Graphics
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Section: Structures
|
Section: Structures
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -281,6 +281,20 @@ void snap_invalidate_item(int snapid, int index);
|
||||||
*/
|
*/
|
||||||
void snap_input(void *data, int size);
|
void snap_input(void *data, int size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: snap_set_staticsize
|
||||||
|
Tells the engine how big a specific item always will be. This
|
||||||
|
helps the engine to compress snapshots better.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
type - Item type
|
||||||
|
size - Size of the data.
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
Size must be in a multiple of 4.
|
||||||
|
*/
|
||||||
|
void snap_set_staticsize(int type, int size);
|
||||||
|
|
||||||
/* message packing */
|
/* message packing */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#define ENGINE_IF_SERVER_H
|
#define ENGINE_IF_SERVER_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Section: Server Hooks
|
Section: Server Interface
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* server */
|
/* server */
|
||||||
|
|
|
@ -170,7 +170,7 @@ typedef struct
|
||||||
|
|
||||||
NETPACKETCONSTRUCT construct;
|
NETPACKETCONSTRUCT construct;
|
||||||
|
|
||||||
NETADDR4 peeraddr;
|
NETADDR peeraddr;
|
||||||
NETSOCKET socket;
|
NETSOCKET socket;
|
||||||
NETSTATS stats;
|
NETSTATS stats;
|
||||||
} NETCONNECTION;
|
} NETCONNECTION;
|
||||||
|
@ -182,7 +182,7 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
NETCONNECTION *conn;
|
NETCONNECTION *conn;
|
||||||
int current_chunk;
|
int current_chunk;
|
||||||
int client_id;
|
int client_id;
|
||||||
|
@ -205,7 +205,7 @@ struct NETSERVER_t
|
||||||
|
|
||||||
struct NETCLIENT_t
|
struct NETCLIENT_t
|
||||||
{
|
{
|
||||||
NETADDR4 server_addr;
|
NETADDR server_addr;
|
||||||
NETSOCKET socket;
|
NETSOCKET socket;
|
||||||
|
|
||||||
NETRECVINFO recv;
|
NETRECVINFO recv;
|
||||||
|
@ -215,7 +215,7 @@ struct NETCLIENT_t
|
||||||
static IOHANDLE datalog = 0;
|
static IOHANDLE datalog = 0;
|
||||||
static HUFFSTATE huffmanstate;
|
static HUFFSTATE huffmanstate;
|
||||||
|
|
||||||
#define COMPRESSION 0
|
#define COMPRESSION 1
|
||||||
|
|
||||||
typedef struct pcap_hdr_s {
|
typedef struct pcap_hdr_s {
|
||||||
unsigned magic_number; /* magic number */
|
unsigned magic_number; /* magic number */
|
||||||
|
@ -235,7 +235,7 @@ typedef struct pcaprec_hdr_s {
|
||||||
} pcaprec_hdr_t;
|
} pcaprec_hdr_t;
|
||||||
|
|
||||||
/* packs the data tight and sends it */
|
/* packs the data tight and sends it */
|
||||||
static void send_packet(NETSOCKET socket, NETADDR4 *addr, NETPACKETCONSTRUCT *packet)
|
static void send_packet(NETSOCKET socket, NETADDR *addr, NETPACKETCONSTRUCT *packet)
|
||||||
{
|
{
|
||||||
unsigned char buffer[NET_MAX_PACKETSIZE];
|
unsigned char buffer[NET_MAX_PACKETSIZE];
|
||||||
buffer[0] = ((packet->flags<<4)&0xf0)|((packet->ack>>8)&0xf);
|
buffer[0] = ((packet->flags<<4)&0xf0)|((packet->ack>>8)&0xf);
|
||||||
|
@ -249,13 +249,13 @@ static void send_packet(NETSOCKET socket, NETADDR4 *addr, NETPACKETCONSTRUCT *pa
|
||||||
|
|
||||||
if(COMPRESSION)
|
if(COMPRESSION)
|
||||||
{
|
{
|
||||||
int compressed_size = (huffman_compress(&huffmanstate, packet->chunk_data, packet->data_size, &buffer[4], NET_MAX_PACKETSIZE-4)+7)/8;
|
int compressed_size = (huffman_compress(&huffmanstate, packet->chunk_data, packet->data_size, &buffer[3], NET_MAX_PACKETSIZE-4)+7)/8;
|
||||||
net_udp4_send(socket, addr, buffer, NET_PACKETHEADERSIZE+compressed_size);
|
net_udp_send(socket, addr, buffer, NET_PACKETHEADERSIZE+compressed_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mem_copy(&buffer[3], packet->chunk_data, packet->data_size);
|
mem_copy(&buffer[3], packet->chunk_data, packet->data_size);
|
||||||
net_udp4_send(socket, addr, buffer, NET_PACKETHEADERSIZE+packet->data_size);
|
net_udp_send(socket, addr, buffer, NET_PACKETHEADERSIZE+packet->data_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ static void conn_resend(NETCONNECTION *conn)
|
||||||
dbg_msg("conn", "resent %d packets", resend_count);
|
dbg_msg("conn", "resent %d packets", resend_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int conn_connect(NETCONNECTION *conn, NETADDR4 *addr)
|
static int conn_connect(NETCONNECTION *conn, NETADDR *addr)
|
||||||
{
|
{
|
||||||
if(conn->state != NET_CONNSTATE_OFFLINE)
|
if(conn->state != NET_CONNSTATE_OFFLINE)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -504,7 +504,7 @@ static void conn_disconnect(NETCONNECTION *conn, const char *reason)
|
||||||
conn_reset(conn);
|
conn_reset(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int conn_feed(NETCONNECTION *conn, NETPACKETCONSTRUCT *packet, NETADDR4 *addr)
|
static int conn_feed(NETCONNECTION *conn, NETPACKETCONSTRUCT *packet, NETADDR *addr)
|
||||||
{
|
{
|
||||||
int64 now = time_get();
|
int64 now = time_get();
|
||||||
conn->last_recv_time = now;
|
conn->last_recv_time = now;
|
||||||
|
@ -685,11 +685,11 @@ static int conn_update(NETCONNECTION *conn)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETSERVER *netserver_open(NETADDR4 bindaddr, int max_clients, int flags)
|
NETSERVER *netserver_open(NETADDR bindaddr, int max_clients, int flags)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
NETSERVER *server;
|
NETSERVER *server;
|
||||||
NETSOCKET socket = net_udp4_create(bindaddr);
|
NETSOCKET socket = net_udp_create(bindaddr);
|
||||||
if(socket == NETSOCKET_INVALID)
|
if(socket == NETSOCKET_INVALID)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -756,7 +756,7 @@ static void recvinfo_clear(NETRECVINFO *info)
|
||||||
info->valid = 0;
|
info->valid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void recvinfo_start(NETRECVINFO *info, NETADDR4 *addr, NETCONNECTION *conn, int cid)
|
static void recvinfo_start(NETRECVINFO *info, NETADDR *addr, NETCONNECTION *conn, int cid)
|
||||||
{
|
{
|
||||||
info->addr = *addr;
|
info->addr = *addr;
|
||||||
info->conn = conn;
|
info->conn = conn;
|
||||||
|
@ -823,7 +823,7 @@ int netserver_recv(NETSERVER *s, NETCHUNK *chunk)
|
||||||
{
|
{
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
int i, bytes, found;
|
int i, bytes, found;
|
||||||
|
|
||||||
/* check for a chunk */
|
/* check for a chunk */
|
||||||
|
@ -831,7 +831,7 @@ int netserver_recv(NETSERVER *s, NETCHUNK *chunk)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* TODO: empty the recvinfo */
|
/* TODO: empty the recvinfo */
|
||||||
bytes = net_udp4_recv(s->socket, &addr, s->recv.buffer, NET_MAX_PACKETSIZE);
|
bytes = net_udp_recv(s->socket, &addr, s->recv.buffer, NET_MAX_PACKETSIZE);
|
||||||
|
|
||||||
/* no more packets for now */
|
/* no more packets for now */
|
||||||
if(bytes <= 0)
|
if(bytes <= 0)
|
||||||
|
@ -849,7 +849,7 @@ int netserver_recv(NETSERVER *s, NETCHUNK *chunk)
|
||||||
for(i = 0; i < s->max_clients; i++)
|
for(i = 0; i < s->max_clients; i++)
|
||||||
{
|
{
|
||||||
if(s->slots[i].conn.state != NET_CONNSTATE_OFFLINE &&
|
if(s->slots[i].conn.state != NET_CONNSTATE_OFFLINE &&
|
||||||
net_addr4_cmp(&s->slots[i].conn.peeraddr, &addr) == 0)
|
net_addr_comp(&s->slots[i].conn.peeraddr, &addr) == 0)
|
||||||
{
|
{
|
||||||
found = 1; /* silent ignore.. we got this client already */
|
found = 1; /* silent ignore.. we got this client already */
|
||||||
break;
|
break;
|
||||||
|
@ -884,7 +884,7 @@ int netserver_recv(NETSERVER *s, NETCHUNK *chunk)
|
||||||
/* normal packet, find matching slot */
|
/* normal packet, find matching slot */
|
||||||
for(i = 0; i < s->max_clients; i++)
|
for(i = 0; i < s->max_clients; i++)
|
||||||
{
|
{
|
||||||
if(net_addr4_cmp(&s->slots[i].conn.peeraddr, &addr) == 0)
|
if(net_addr_comp(&s->slots[i].conn.peeraddr, &addr) == 0)
|
||||||
{
|
{
|
||||||
if(conn_feed(&s->slots[i].conn, &s->recv.data, &addr))
|
if(conn_feed(&s->slots[i].conn, &s->recv.data, &addr))
|
||||||
{
|
{
|
||||||
|
@ -952,17 +952,17 @@ NETSOCKET netserver_socket(NETSERVER *s)
|
||||||
return s->socket;
|
return s->socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
int netserver_client_addr(NETSERVER *s, int client_id, NETADDR4 *addr)
|
int netserver_client_addr(NETSERVER *s, int client_id, NETADDR *addr)
|
||||||
{
|
{
|
||||||
*addr = s->slots[client_id].conn.peeraddr;
|
*addr = s->slots[client_id].conn.peeraddr;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETCLIENT *netclient_open(NETADDR4 bindaddr, int flags)
|
NETCLIENT *netclient_open(NETADDR bindaddr, int flags)
|
||||||
{
|
{
|
||||||
NETCLIENT *client = (NETCLIENT *)mem_alloc(sizeof(NETCLIENT), 1);
|
NETCLIENT *client = (NETCLIENT *)mem_alloc(sizeof(NETCLIENT), 1);
|
||||||
mem_zero(client, sizeof(NETCLIENT));
|
mem_zero(client, sizeof(NETCLIENT));
|
||||||
client->socket = net_udp4_create(bindaddr);
|
client->socket = net_udp_create(bindaddr);
|
||||||
conn_init(&client->conn, client->socket);
|
conn_init(&client->conn, client->socket);
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@ -988,7 +988,7 @@ int netclient_disconnect(NETCLIENT *c, const char *reason)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int netclient_connect(NETCLIENT *c, NETADDR4 *addr)
|
int netclient_connect(NETCLIENT *c, NETADDR *addr)
|
||||||
{
|
{
|
||||||
conn_connect(&c->conn, addr);
|
conn_connect(&c->conn, addr);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -998,7 +998,7 @@ int netclient_recv(NETCLIENT *c, NETCHUNK *chunk)
|
||||||
{
|
{
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
/* check for a chunk */
|
/* check for a chunk */
|
||||||
|
@ -1006,7 +1006,7 @@ int netclient_recv(NETCLIENT *c, NETCHUNK *chunk)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* TODO: empty the recvinfo */
|
/* TODO: empty the recvinfo */
|
||||||
bytes = net_udp4_recv(c->socket, &addr, c->recv.buffer, NET_MAX_PACKETSIZE);
|
bytes = net_udp_recv(c->socket, &addr, c->recv.buffer, NET_MAX_PACKETSIZE);
|
||||||
|
|
||||||
/* no more packets for now */
|
/* no more packets for now */
|
||||||
if(bytes <= 0)
|
if(bytes <= 0)
|
||||||
|
@ -1089,7 +1089,7 @@ void netcommon_openlog(const char *filename)
|
||||||
|
|
||||||
|
|
||||||
static const int freq_table[256+1] = {
|
static const int freq_table[256+1] = {
|
||||||
31230,4545,2657,431,1950,919,444,482,2244,617,838,542,715,1814,304,240,754,212,647,186,
|
1<<30,4545,2657,431,1950,919,444,482,2244,617,838,542,715,1814,304,240,754,212,647,186,
|
||||||
283,131,146,166,543,164,167,136,179,859,363,113,157,154,204,108,137,180,202,176,
|
283,131,146,166,543,164,167,136,179,859,363,113,157,154,204,108,137,180,202,176,
|
||||||
872,404,168,134,151,111,113,109,120,126,129,100,41,20,16,22,18,18,17,19,
|
872,404,168,134,151,111,113,109,120,126,129,100,41,20,16,22,18,18,17,19,
|
||||||
16,37,13,21,362,166,99,78,95,88,81,70,83,284,91,187,77,68,52,68,
|
16,37,13,21,362,166,99,78,95,88,81,70,83,284,91,187,77,68,52,68,
|
||||||
|
|
|
@ -5,7 +5,7 @@ typedef struct
|
||||||
/* -1 means that it's a stateless packet */
|
/* -1 means that it's a stateless packet */
|
||||||
/* 0 on the client means the server */
|
/* 0 on the client means the server */
|
||||||
int client_id;
|
int client_id;
|
||||||
NETADDR4 address; /* only used when client_id == -1 */
|
NETADDR address; /* only used when client_id == -1 */
|
||||||
int flags;
|
int flags;
|
||||||
int data_size;
|
int data_size;
|
||||||
const void *data;
|
const void *data;
|
||||||
|
@ -45,7 +45,7 @@ void netcommon_openlog(const char *filename);
|
||||||
void netcommon_init();
|
void netcommon_init();
|
||||||
|
|
||||||
/* server side */
|
/* server side */
|
||||||
NETSERVER *netserver_open(NETADDR4 bindaddr, int max_clients, int flags);
|
NETSERVER *netserver_open(NETADDR bindaddr, int max_clients, int flags);
|
||||||
int netserver_set_callbacks(NETSERVER *s, NETFUNC_NEWCLIENT new_client, NETFUNC_DELCLIENT del_client, void *user);
|
int netserver_set_callbacks(NETSERVER *s, NETFUNC_NEWCLIENT new_client, NETFUNC_DELCLIENT del_client, void *user);
|
||||||
int netserver_recv(NETSERVER *s, NETCHUNK *chunk);
|
int netserver_recv(NETSERVER *s, NETCHUNK *chunk);
|
||||||
int netserver_send(NETSERVER *s, NETCHUNK *chunk);
|
int netserver_send(NETSERVER *s, NETCHUNK *chunk);
|
||||||
|
@ -53,14 +53,14 @@ int netserver_close(NETSERVER *s);
|
||||||
int netserver_update(NETSERVER *s);
|
int netserver_update(NETSERVER *s);
|
||||||
NETSOCKET netserver_socket(NETSERVER *s);
|
NETSOCKET netserver_socket(NETSERVER *s);
|
||||||
int netserver_drop(NETSERVER *s, int client_id, const char *reason);
|
int netserver_drop(NETSERVER *s, int client_id, const char *reason);
|
||||||
int netserver_client_addr(NETSERVER *s, int client_id, NETADDR4 *addr);
|
int netserver_client_addr(NETSERVER *s, int client_id, NETADDR *addr);
|
||||||
int netserver_max_clients(NETSERVER *s);
|
int netserver_max_clients(NETSERVER *s);
|
||||||
/*void netserver_stats(NETSERVER *s, NETSTATS *stats);*/
|
/*void netserver_stats(NETSERVER *s, NETSTATS *stats);*/
|
||||||
|
|
||||||
/* client side */
|
/* client side */
|
||||||
NETCLIENT *netclient_open(NETADDR4 bindaddr, int flags);
|
NETCLIENT *netclient_open(NETADDR bindaddr, int flags);
|
||||||
int netclient_disconnect(NETCLIENT *c, const char *reason);
|
int netclient_disconnect(NETCLIENT *c, const char *reason);
|
||||||
int netclient_connect(NETCLIENT *c, NETADDR4 *addr);
|
int netclient_connect(NETCLIENT *c, NETADDR *addr);
|
||||||
int netclient_recv(NETCLIENT *c, NETCHUNK *chunk);
|
int netclient_recv(NETCLIENT *c, NETCHUNK *chunk);
|
||||||
int netclient_send(NETCLIENT *c, NETCHUNK *chunk);
|
int netclient_send(NETCLIENT *c, NETCHUNK *chunk);
|
||||||
int netclient_close(NETCLIENT *c);
|
int netclient_close(NETCLIENT *c);
|
||||||
|
@ -79,7 +79,7 @@ public:
|
||||||
net_server() : ptr(0) {}
|
net_server() : ptr(0) {}
|
||||||
~net_server() { close(); }
|
~net_server() { close(); }
|
||||||
|
|
||||||
int open(NETADDR4 bindaddr, int max, int flags) { ptr = netserver_open(bindaddr, max, flags); return ptr != 0; }
|
int open(NETADDR bindaddr, int max, int flags) { ptr = netserver_open(bindaddr, max, flags); return ptr != 0; }
|
||||||
int close() { int r = netserver_close(ptr); ptr = 0; return r; }
|
int close() { int r = netserver_close(ptr); ptr = 0; return r; }
|
||||||
|
|
||||||
int set_callbacks(NETFUNC_NEWCLIENT new_client, NETFUNC_DELCLIENT del_client, void *user)
|
int set_callbacks(NETFUNC_NEWCLIENT new_client, NETFUNC_DELCLIENT del_client, void *user)
|
||||||
|
@ -103,10 +103,10 @@ public:
|
||||||
net_client() : ptr(0) {}
|
net_client() : ptr(0) {}
|
||||||
~net_client() { close(); }
|
~net_client() { close(); }
|
||||||
|
|
||||||
int open(NETADDR4 bindaddr, int flags) { ptr = netclient_open(bindaddr, flags); return ptr != 0; }
|
int open(NETADDR bindaddr, int flags) { ptr = netclient_open(bindaddr, flags); return ptr != 0; }
|
||||||
int close() { int r = netclient_close(ptr); ptr = 0; return r; }
|
int close() { int r = netclient_close(ptr); ptr = 0; return r; }
|
||||||
|
|
||||||
int connect(NETADDR4 *addr) { return netclient_connect(ptr, addr); }
|
int connect(NETADDR *addr) { return netclient_connect(ptr, addr); }
|
||||||
int disconnect(const char *reason) { return netclient_disconnect(ptr, reason); }
|
int disconnect(const char *reason) { return netclient_disconnect(ptr, reason); }
|
||||||
|
|
||||||
int recv(NETCHUNK *chunk) { return netclient_recv(ptr, chunk); }
|
int recv(NETCHUNK *chunk) { return netclient_recv(ptr, chunk); }
|
||||||
|
|
|
@ -6,6 +6,15 @@
|
||||||
#include "e_common_interface.h"
|
#include "e_common_interface.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: strange arbitrary number */
|
||||||
|
static short item_sizes[64] = {0};
|
||||||
|
|
||||||
|
void snap_set_staticsize(int itemtype, int size)
|
||||||
|
{
|
||||||
|
dbg_msg("","%d = %d", itemtype, size);
|
||||||
|
item_sizes[itemtype] = size;
|
||||||
|
}
|
||||||
|
|
||||||
int *snapitem_data(SNAPSHOT_ITEM *item) { return (int *)(item+1); }
|
int *snapitem_data(SNAPSHOT_ITEM *item) { return (int *)(item+1); }
|
||||||
int snapitem_type(SNAPSHOT_ITEM *item) { return item->type_and_id>>16; }
|
int snapitem_type(SNAPSHOT_ITEM *item) { return item->type_and_id>>16; }
|
||||||
int snapitem_id(SNAPSHOT_ITEM *item) { return item->type_and_id&0xffff; }
|
int snapitem_id(SNAPSHOT_ITEM *item) { return item->type_and_id&0xffff; }
|
||||||
|
@ -253,14 +262,21 @@ int snapshot_create_delta(SNAPSHOT *from, SNAPSHOT *to, void *dstdata)
|
||||||
if(pastindex != -1)
|
if(pastindex != -1)
|
||||||
{
|
{
|
||||||
static PERFORMACE_INFO scope = {"diff", 0};
|
static PERFORMACE_INFO scope = {"diff", 0};
|
||||||
|
int *item_data_dst = data+3;
|
||||||
perf_start(&scope);
|
perf_start(&scope);
|
||||||
|
|
||||||
pastitem = snapshot_get_item(from, pastindex);
|
pastitem = snapshot_get_item(from, pastindex);
|
||||||
if(diff_item((int*)snapitem_data(pastitem), (int*)snapitem_data(curitem), data+3, itemsize/4))
|
|
||||||
|
if(item_sizes[snapitem_type(curitem)])
|
||||||
|
item_data_dst = data+2;
|
||||||
|
|
||||||
|
if(diff_item((int*)snapitem_data(pastitem), (int*)snapitem_data(curitem), item_data_dst, itemsize/4))
|
||||||
{
|
{
|
||||||
*data++ = itemsize;
|
|
||||||
*data++ = snapitem_type(curitem);
|
*data++ = snapitem_type(curitem);
|
||||||
*data++ = snapitem_id(curitem);
|
*data++ = snapitem_id(curitem);
|
||||||
|
if(!item_sizes[snapitem_type(curitem)])
|
||||||
|
*data++ = itemsize/4;
|
||||||
data += itemsize/4;
|
data += itemsize/4;
|
||||||
delta->num_update_items++;
|
delta->num_update_items++;
|
||||||
}
|
}
|
||||||
|
@ -271,9 +287,10 @@ int snapshot_create_delta(SNAPSHOT *from, SNAPSHOT *to, void *dstdata)
|
||||||
static PERFORMACE_INFO scope = {"copy", 0};
|
static PERFORMACE_INFO scope = {"copy", 0};
|
||||||
perf_start(&scope);
|
perf_start(&scope);
|
||||||
|
|
||||||
*data++ = itemsize;
|
|
||||||
*data++ = snapitem_type(curitem);
|
*data++ = snapitem_type(curitem);
|
||||||
*data++ = snapitem_id(curitem);
|
*data++ = snapitem_id(curitem);
|
||||||
|
if(!item_sizes[snapitem_type(curitem)])
|
||||||
|
*data++ = itemsize/4;
|
||||||
|
|
||||||
mem_copy(data, snapitem_data(curitem), itemsize);
|
mem_copy(data, snapitem_data(curitem), itemsize);
|
||||||
size_count += itemsize;
|
size_count += itemsize;
|
||||||
|
@ -370,12 +387,19 @@ int snapshot_unpack_delta(SNAPSHOT *from, SNAPSHOT *to, void *srcdata, int data_
|
||||||
/* unpack updated stuff */
|
/* unpack updated stuff */
|
||||||
for(i = 0; i < delta->num_update_items; i++)
|
for(i = 0; i < delta->num_update_items; i++)
|
||||||
{
|
{
|
||||||
if(data+3 > end)
|
if(data+2 > end)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
itemsize = *data++;
|
|
||||||
type = *data++;
|
type = *data++;
|
||||||
id = *data++;
|
id = *data++;
|
||||||
|
if(item_sizes[type])
|
||||||
|
itemsize = item_sizes[type];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(data+1 > end)
|
||||||
|
return -1;
|
||||||
|
itemsize = (*data++) * 4;
|
||||||
|
}
|
||||||
snapshot_current = type;
|
snapshot_current = type;
|
||||||
|
|
||||||
if(range_check(end, data, itemsize) || itemsize < 0) return -1;
|
if(range_check(end, data, itemsize) || itemsize < 0) return -1;
|
||||||
|
|
|
@ -465,8 +465,9 @@ int64 time_freq()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----- network ----- */
|
/* ----- network ----- */
|
||||||
static void netaddr4_to_sockaddr(const NETADDR4 *src, struct sockaddr *dest)
|
static void netaddr_to_sockaddr(const NETADDR *src, struct sockaddr *dest)
|
||||||
{
|
{
|
||||||
|
/* TODO: IPv6 support */
|
||||||
struct sockaddr_in *p = (struct sockaddr_in *)dest;
|
struct sockaddr_in *p = (struct sockaddr_in *)dest;
|
||||||
mem_zero(p, sizeof(struct sockaddr_in));
|
mem_zero(p, sizeof(struct sockaddr_in));
|
||||||
p->sin_family = AF_INET;
|
p->sin_family = AF_INET;
|
||||||
|
@ -474,9 +475,11 @@ static void netaddr4_to_sockaddr(const NETADDR4 *src, struct sockaddr *dest)
|
||||||
p->sin_addr.s_addr = htonl(src->ip[0]<<24|src->ip[1]<<16|src->ip[2]<<8|src->ip[3]);
|
p->sin_addr.s_addr = htonl(src->ip[0]<<24|src->ip[1]<<16|src->ip[2]<<8|src->ip[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sockaddr_to_netaddr4(const struct sockaddr *src, NETADDR4 *dst)
|
static void sockaddr_to_netaddr(const struct sockaddr *src, NETADDR *dst)
|
||||||
{
|
{
|
||||||
|
/* TODO: IPv6 support */
|
||||||
unsigned int ip = htonl(((struct sockaddr_in*)src)->sin_addr.s_addr);
|
unsigned int ip = htonl(((struct sockaddr_in*)src)->sin_addr.s_addr);
|
||||||
|
dst->type = NETTYPE_IPV4;
|
||||||
dst->port = htons(((struct sockaddr_in*)src)->sin_port);
|
dst->port = htons(((struct sockaddr_in*)src)->sin_port);
|
||||||
dst->ip[0] = (unsigned char)((ip>>24)&0xFF);
|
dst->ip[0] = (unsigned char)((ip>>24)&0xFF);
|
||||||
dst->ip[1] = (unsigned char)((ip>>16)&0xFF);
|
dst->ip[1] = (unsigned char)((ip>>16)&0xFF);
|
||||||
|
@ -484,21 +487,15 @@ static void sockaddr_to_netaddr4(const struct sockaddr *src, NETADDR4 *dst)
|
||||||
dst->ip[3] = (unsigned char)(ip&0xFF);
|
dst->ip[3] = (unsigned char)(ip&0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_addr4_cmp(const NETADDR4 *a, const NETADDR4 *b)
|
int net_addr_comp(const NETADDR *a, const NETADDR *b)
|
||||||
{
|
{
|
||||||
if( a->ip[0] != b->ip[0] ||
|
return mem_comp(a, b, sizeof(NETADDR));
|
||||||
a->ip[1] != b->ip[1] ||
|
|
||||||
a->ip[2] != b->ip[2] ||
|
|
||||||
a->ip[3] != b->ip[3] ||
|
|
||||||
a->port != b->port
|
|
||||||
)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int net_host_lookup(const char *hostname, unsigned short port, NETADDR4 *addr)
|
int net_host_lookup(const char *hostname, NETADDR *addr, int types)
|
||||||
{
|
{
|
||||||
|
/* TODO: IPv6 support */
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
struct addrinfo *result;
|
struct addrinfo *result;
|
||||||
int e;
|
int e;
|
||||||
|
@ -510,14 +507,15 @@ int net_host_lookup(const char *hostname, unsigned short port, NETADDR4 *addr)
|
||||||
if(e != 0 || !result)
|
if(e != 0 || !result)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
sockaddr_to_netaddr4(result->ai_addr, addr);
|
sockaddr_to_netaddr(result->ai_addr, addr);
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
addr->port = port;
|
addr->port = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETSOCKET net_udp4_create(NETADDR4 bindaddr)
|
NETSOCKET net_udp_create(NETADDR bindaddr)
|
||||||
{
|
{
|
||||||
|
/* TODO: IPv6 support */
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
unsigned int mode = 1;
|
unsigned int mode = 1;
|
||||||
int broadcast = 1;
|
int broadcast = 1;
|
||||||
|
@ -528,10 +526,10 @@ NETSOCKET net_udp4_create(NETADDR4 bindaddr)
|
||||||
return NETSOCKET_INVALID;
|
return NETSOCKET_INVALID;
|
||||||
|
|
||||||
/* bind, we should check for error */
|
/* bind, we should check for error */
|
||||||
netaddr4_to_sockaddr(&bindaddr, &addr);
|
netaddr_to_sockaddr(&bindaddr, &addr);
|
||||||
if(bind(sock, &addr, sizeof(addr)) != 0)
|
if(bind(sock, &addr, sizeof(addr)) != 0)
|
||||||
{
|
{
|
||||||
net_udp4_close(sock);
|
net_udp_close(sock);
|
||||||
return NETSOCKET_INVALID;
|
return NETSOCKET_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,12 +547,12 @@ NETSOCKET net_udp4_create(NETADDR4 bindaddr)
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_udp4_send(NETSOCKET sock, const NETADDR4 *addr, const void *data, int size)
|
int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size)
|
||||||
{
|
{
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
int d;
|
int d;
|
||||||
mem_zero(&sa, sizeof(sa));
|
mem_zero(&sa, sizeof(sa));
|
||||||
netaddr4_to_sockaddr(addr, &sa);
|
netaddr_to_sockaddr(addr, &sa);
|
||||||
d = sendto((int)sock, (const char*)data, size, 0, &sa, sizeof(sa));
|
d = sendto((int)sock, (const char*)data, size, 0, &sa, sizeof(sa));
|
||||||
if(d < 0)
|
if(d < 0)
|
||||||
dbg_msg("net", "sendto error %d %x", d, d);
|
dbg_msg("net", "sendto error %d %x", d, d);
|
||||||
|
@ -563,7 +561,7 @@ int net_udp4_send(NETSOCKET sock, const NETADDR4 *addr, const void *data, int si
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_udp4_recv(NETSOCKET sock, NETADDR4 *addr, void *data, int maxsize)
|
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize)
|
||||||
{
|
{
|
||||||
struct sockaddr from;
|
struct sockaddr from;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
@ -571,7 +569,7 @@ int net_udp4_recv(NETSOCKET sock, NETADDR4 *addr, void *data, int maxsize)
|
||||||
bytes = recvfrom(sock, (char*)data, maxsize, 0, &from, &fromlen);
|
bytes = recvfrom(sock, (char*)data, maxsize, 0, &from, &fromlen);
|
||||||
if(bytes > 0)
|
if(bytes > 0)
|
||||||
{
|
{
|
||||||
sockaddr_to_netaddr4(&from, addr);
|
sockaddr_to_netaddr(&from, addr);
|
||||||
network_stats.recv_bytes += bytes;
|
network_stats.recv_bytes += bytes;
|
||||||
network_stats.recv_packets++;
|
network_stats.recv_packets++;
|
||||||
return bytes;
|
return bytes;
|
||||||
|
@ -581,7 +579,7 @@ int net_udp4_recv(NETSOCKET sock, NETADDR4 *addr, void *data, int maxsize)
|
||||||
return -1; /* error */
|
return -1; /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_udp4_close(NETSOCKET sock)
|
int net_udp_close(NETSOCKET sock)
|
||||||
{
|
{
|
||||||
#if defined(CONF_FAMILY_WINDOWS)
|
#if defined(CONF_FAMILY_WINDOWS)
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
|
@ -591,8 +589,9 @@ int net_udp4_close(NETSOCKET sock)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETSOCKET net_tcp4_create(const NETADDR4 *a)
|
NETSOCKET net_tcp_create(const NETADDR *a)
|
||||||
{
|
{
|
||||||
|
/* TODO: IPv6 support */
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
|
|
||||||
/* create socket */
|
/* create socket */
|
||||||
|
@ -601,14 +600,14 @@ NETSOCKET net_tcp4_create(const NETADDR4 *a)
|
||||||
return NETSOCKET_INVALID;
|
return NETSOCKET_INVALID;
|
||||||
|
|
||||||
/* bind, we should check for error */
|
/* bind, we should check for error */
|
||||||
netaddr4_to_sockaddr(a, &addr);
|
netaddr_to_sockaddr(a, &addr);
|
||||||
bind(sock, &addr, sizeof(addr));
|
bind(sock, &addr, sizeof(addr));
|
||||||
|
|
||||||
/* return */
|
/* return */
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_set_non_blocking(NETSOCKET sock)
|
int net_tcp_set_non_blocking(NETSOCKET sock)
|
||||||
{
|
{
|
||||||
unsigned int mode = 1;
|
unsigned int mode = 1;
|
||||||
#if defined(CONF_FAMILY_WINDOWS)
|
#if defined(CONF_FAMILY_WINDOWS)
|
||||||
|
@ -618,7 +617,7 @@ int net_tcp4_set_non_blocking(NETSOCKET sock)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_set_blocking(NETSOCKET sock)
|
int net_tcp_set_blocking(NETSOCKET sock)
|
||||||
{
|
{
|
||||||
unsigned int mode = 0;
|
unsigned int mode = 0;
|
||||||
#if defined(CONF_FAMILY_WINDOWS)
|
#if defined(CONF_FAMILY_WINDOWS)
|
||||||
|
@ -628,12 +627,12 @@ int net_tcp4_set_blocking(NETSOCKET sock)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_listen(NETSOCKET sock, int backlog)
|
int net_tcp_listen(NETSOCKET sock, int backlog)
|
||||||
{
|
{
|
||||||
return listen(sock, backlog);
|
return listen(sock, backlog);
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR4 *a)
|
int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
socklen_t sockaddr_len;
|
socklen_t sockaddr_len;
|
||||||
|
@ -645,48 +644,48 @@ int net_tcp4_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR4 *a)
|
||||||
|
|
||||||
if (s != -1)
|
if (s != -1)
|
||||||
{
|
{
|
||||||
sockaddr_to_netaddr4(&addr, a);
|
sockaddr_to_netaddr(&addr, a);
|
||||||
*new_sock = s;
|
*new_sock = s;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_connect(NETSOCKET sock, const NETADDR4 *a)
|
int net_tcp_connect(NETSOCKET sock, const NETADDR *a)
|
||||||
{
|
{
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
|
|
||||||
netaddr4_to_sockaddr(a, &addr);
|
netaddr_to_sockaddr(a, &addr);
|
||||||
return connect(sock, &addr, sizeof(addr));
|
return connect(sock, &addr, sizeof(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_connect_non_blocking(NETSOCKET sock, const NETADDR4 *a)
|
int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a)
|
||||||
{
|
{
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
netaddr4_to_sockaddr(a, &addr);
|
netaddr_to_sockaddr(a, &addr);
|
||||||
net_tcp4_set_non_blocking(sock);
|
net_tcp_set_non_blocking(sock);
|
||||||
res = connect(sock, &addr, sizeof(addr));
|
res = connect(sock, &addr, sizeof(addr));
|
||||||
net_tcp4_set_blocking(sock);
|
net_tcp_set_blocking(sock);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_send(NETSOCKET sock, const void *data, int size)
|
int net_tcp_send(NETSOCKET sock, const void *data, int size)
|
||||||
{
|
{
|
||||||
int d;
|
int d;
|
||||||
d = send((int)sock, (const char*)data, size, 0);
|
d = send((int)sock, (const char*)data, size, 0);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_recv(NETSOCKET sock, void *data, int maxsize)
|
int net_tcp_recv(NETSOCKET sock, void *data, int maxsize)
|
||||||
{
|
{
|
||||||
int bytes;
|
int bytes;
|
||||||
bytes = recv((int)sock, (char*)data, maxsize, 0);
|
bytes = recv((int)sock, (char*)data, maxsize, 0);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_tcp4_close(NETSOCKET sock)
|
int net_tcp_close(NETSOCKET sock)
|
||||||
{
|
{
|
||||||
#if defined(CONF_FAMILY_WINDOWS)
|
#if defined(CONF_FAMILY_WINDOWS)
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
|
@ -958,6 +957,11 @@ void str_hex(char *dst, int dst_size, const void *data, int data_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mem_comp(const void *a, const void *b, int size)
|
||||||
|
{
|
||||||
|
return memcmp(a,b,size);
|
||||||
|
}
|
||||||
|
|
||||||
void net_stats(NETSTATS *stats_inout)
|
void net_stats(NETSTATS *stats_inout)
|
||||||
{
|
{
|
||||||
*stats_inout = network_stats;
|
*stats_inout = network_stats;
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Title: OS Abstraction
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BASE_SYSTEM_H
|
#ifndef BASE_SYSTEM_H
|
||||||
#define BASE_SYSTEM_H
|
#define BASE_SYSTEM_H
|
||||||
|
|
||||||
|
@ -9,10 +14,9 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Group: Debug */
|
/* Group: Debug */
|
||||||
/**********
|
/*
|
||||||
Function: dbg_assert
|
Function: dbg_assert
|
||||||
|
Breaks into the debugger based on a test.
|
||||||
Breaks into the debugger based on a test.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
test - Result of the test.
|
test - Result of the test.
|
||||||
|
@ -23,25 +27,24 @@ extern "C" {
|
||||||
|
|
||||||
See Also:
|
See Also:
|
||||||
<dbg_break>
|
<dbg_break>
|
||||||
**********/
|
*/
|
||||||
void dbg_assert(int test, const char *msg);
|
void dbg_assert(int test, const char *msg);
|
||||||
#define dbg_assert(test,msg) dbg_assert_imp(__FILE__, __LINE__, test, msg)
|
#define dbg_assert(test,msg) dbg_assert_imp(__FILE__, __LINE__, test, msg)
|
||||||
void dbg_assert_imp(const char *filename, int line, int test, const char *msg);
|
void dbg_assert_imp(const char *filename, int line, int test, const char *msg);
|
||||||
|
|
||||||
/**********
|
/*
|
||||||
Function: dbg_break
|
Function: dbg_break
|
||||||
|
Breaks into the debugger.
|
||||||
Breaks into the debugger.
|
|
||||||
|
|
||||||
Remarks:
|
Remarks:
|
||||||
Does nothing in release version of the library.
|
Does nothing in release version of the library.
|
||||||
|
|
||||||
See Also:
|
See Also:
|
||||||
<dbg_assert>
|
<dbg_assert>
|
||||||
**********/
|
*/
|
||||||
void dbg_break();
|
void dbg_break();
|
||||||
|
|
||||||
/**********
|
/*
|
||||||
Function: dbg_msg
|
Function: dbg_msg
|
||||||
|
|
||||||
Prints a debug message.
|
Prints a debug message.
|
||||||
|
@ -55,15 +58,14 @@ void dbg_break();
|
||||||
|
|
||||||
See Also:
|
See Also:
|
||||||
<dbg_assert>
|
<dbg_assert>
|
||||||
**********/
|
*/
|
||||||
void dbg_msg(const char *sys, const char *fmt, ...);
|
void dbg_msg(const char *sys, const char *fmt, ...);
|
||||||
|
|
||||||
/* Group: Memory */
|
/* Group: Memory */
|
||||||
|
|
||||||
/**********
|
/*
|
||||||
Function: mem_alloc
|
Function: mem_alloc
|
||||||
|
Allocates memory.
|
||||||
Allocates memory.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
size - Size of the needed block.
|
size - Size of the needed block.
|
||||||
|
@ -79,14 +81,13 @@ void dbg_msg(const char *sys, const char *fmt, ...);
|
||||||
|
|
||||||
See Also:
|
See Also:
|
||||||
<mem_free>
|
<mem_free>
|
||||||
**********/
|
*/
|
||||||
void *mem_alloc_debug(const char *filename, int line, unsigned size, unsigned alignment);
|
void *mem_alloc_debug(const char *filename, int line, unsigned size, unsigned alignment);
|
||||||
#define mem_alloc(s,a) mem_alloc_debug(__FILE__, __LINE__, (s), (a))
|
#define mem_alloc(s,a) mem_alloc_debug(__FILE__, __LINE__, (s), (a))
|
||||||
|
|
||||||
/**********
|
/*
|
||||||
Function: mem_free
|
Function: mem_free
|
||||||
|
Frees a block allocated through <mem_alloc>.
|
||||||
Frees a block allocated through <mem_alloc>.
|
|
||||||
|
|
||||||
Remarks:
|
Remarks:
|
||||||
- In the debug version of the library the function will assert if
|
- In the debug version of the library the function will assert if
|
||||||
|
@ -95,10 +96,10 @@ void *mem_alloc_debug(const char *filename, int line, unsigned size, unsigned al
|
||||||
|
|
||||||
See Also:
|
See Also:
|
||||||
<mem_alloc>
|
<mem_alloc>
|
||||||
**********/
|
*/
|
||||||
void mem_free(void *block);
|
void mem_free(void *block);
|
||||||
|
|
||||||
/**********
|
/*
|
||||||
Function: mem_copy
|
Function: mem_copy
|
||||||
Copies a a memory block.
|
Copies a a memory block.
|
||||||
|
|
||||||
|
@ -113,37 +114,54 @@ void mem_free(void *block);
|
||||||
|
|
||||||
See Also:
|
See Also:
|
||||||
<mem_move>
|
<mem_move>
|
||||||
**********/
|
*/
|
||||||
void mem_copy(void *dest, const void *source, unsigned size);
|
void mem_copy(void *dest, const void *source, unsigned size);
|
||||||
|
|
||||||
/**********
|
/*
|
||||||
Function: mem_move
|
Function: mem_move
|
||||||
Copies a a memory block.
|
Copies a a memory block
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
dest - Destination.
|
dest - Destination
|
||||||
source - Source to copy.
|
source - Source to copy
|
||||||
size - Size of the block to copy.
|
size - Size of the block to copy
|
||||||
|
|
||||||
Remarks:
|
Remarks:
|
||||||
- This functions handles cases where source and destination is overlapping.
|
- This functions handles cases where source and destination
|
||||||
|
is overlapping
|
||||||
|
|
||||||
See Also:
|
See Also:
|
||||||
<mem_copy>
|
<mem_copy>
|
||||||
**********/
|
*/
|
||||||
void mem_move(void *dest, const void *source, unsigned size);
|
void mem_move(void *dest, const void *source, unsigned size);
|
||||||
|
|
||||||
/**********
|
/*
|
||||||
Function: mem_zero
|
Function: mem_zero
|
||||||
Sets a complete memory block to 0.
|
Sets a complete memory block to 0
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
block - Pointer to the block to zero out.
|
block - Pointer to the block to zero out
|
||||||
size - Size of the block.
|
size - Size of the block
|
||||||
**********/
|
*/
|
||||||
void mem_zero(void *block, unsigned size);
|
void mem_zero(void *block, unsigned size);
|
||||||
|
|
||||||
/* ------- io ------- */
|
/*
|
||||||
|
Function: mem_comp
|
||||||
|
Compares two blocks of memory
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
a - First block of data
|
||||||
|
b - Second block of data
|
||||||
|
size - Size of the data to compare
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
<0 - Block a is lesser then block b
|
||||||
|
0 - Block a is equal to block b
|
||||||
|
>0 - Block a is greater then block b
|
||||||
|
*/
|
||||||
|
int mem_comp(const void *a, const void *b, int size);
|
||||||
|
|
||||||
|
/* Group: File IO */
|
||||||
enum {
|
enum {
|
||||||
IOFLAG_READ = 1,
|
IOFLAG_READ = 1,
|
||||||
IOFLAG_WRITE = 2,
|
IOFLAG_WRITE = 2,
|
||||||
|
@ -156,9 +174,7 @@ enum {
|
||||||
|
|
||||||
typedef struct IOINTERNAL *IOHANDLE;
|
typedef struct IOINTERNAL *IOHANDLE;
|
||||||
|
|
||||||
/**** Group: File IO ****/
|
/*
|
||||||
|
|
||||||
/****
|
|
||||||
Function: io_open
|
Function: io_open
|
||||||
Opens a file.
|
Opens a file.
|
||||||
|
|
||||||
|
@ -169,10 +185,10 @@ typedef struct IOINTERNAL *IOHANDLE;
|
||||||
Returns:
|
Returns:
|
||||||
Returns a handle to the file on success and 0 on failure.
|
Returns a handle to the file on success and 0 on failure.
|
||||||
|
|
||||||
****/
|
*/
|
||||||
IOHANDLE io_open(const char *filename, int flags);
|
IOHANDLE io_open(const char *filename, int flags);
|
||||||
|
|
||||||
/****
|
/*
|
||||||
Function: io_read
|
Function: io_read
|
||||||
Reads data into a buffer from a file.
|
Reads data into a buffer from a file.
|
||||||
|
|
||||||
|
@ -184,10 +200,10 @@ IOHANDLE io_open(const char *filename, int flags);
|
||||||
Returns:
|
Returns:
|
||||||
Number of bytes read.
|
Number of bytes read.
|
||||||
|
|
||||||
****/
|
*/
|
||||||
unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
|
unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: io_skip
|
Function: io_skip
|
||||||
Skips data in a file.
|
Skips data in a file.
|
||||||
|
|
||||||
|
@ -197,13 +213,12 @@ unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Number of bytes skipped.
|
Number of bytes skipped.
|
||||||
****/
|
*/
|
||||||
unsigned io_skip(IOHANDLE io, unsigned size);
|
unsigned io_skip(IOHANDLE io, unsigned size);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: io_write
|
Function: io_write
|
||||||
|
Writes data from a buffer to file.
|
||||||
Writes data from a buffer to file.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
io - Handle to the file.
|
io - Handle to the file.
|
||||||
|
@ -212,10 +227,10 @@ unsigned io_skip(IOHANDLE io, unsigned size);
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Number of bytes written.
|
Number of bytes written.
|
||||||
*****/
|
*/
|
||||||
unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
|
unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: io_seek
|
Function: io_seek
|
||||||
Seeks to a specified offset in the file.
|
Seeks to a specified offset in the file.
|
||||||
|
|
||||||
|
@ -226,10 +241,10 @@ unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Returns 0 on success.
|
Returns 0 on success.
|
||||||
*****/
|
*/
|
||||||
int io_seek(IOHANDLE io, int offset, int origin);
|
int io_seek(IOHANDLE io, int offset, int origin);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: io_tell
|
Function: io_tell
|
||||||
Gets the current position in the file.
|
Gets the current position in the file.
|
||||||
|
|
||||||
|
@ -238,10 +253,10 @@ int io_seek(IOHANDLE io, int offset, int origin);
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Returns the current position. -1L if an error occured.
|
Returns the current position. -1L if an error occured.
|
||||||
*****/
|
*/
|
||||||
long int io_tell(IOHANDLE io);
|
long int io_tell(IOHANDLE io);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: io_length
|
Function: io_length
|
||||||
Gets the total length of the file. Resetting cursor to the beginning
|
Gets the total length of the file. Resetting cursor to the beginning
|
||||||
|
|
||||||
|
@ -250,10 +265,10 @@ long int io_tell(IOHANDLE io);
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Returns the total size. -1L if an error occured.
|
Returns the total size. -1L if an error occured.
|
||||||
*****/
|
*/
|
||||||
long int io_length(IOHANDLE io);
|
long int io_length(IOHANDLE io);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: io_close
|
Function: io_close
|
||||||
Closes a file.
|
Closes a file.
|
||||||
|
|
||||||
|
@ -262,10 +277,10 @@ long int io_length(IOHANDLE io);
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Returns 0 on success.
|
Returns 0 on success.
|
||||||
*****/
|
*/
|
||||||
int io_close(IOHANDLE io);
|
int io_close(IOHANDLE io);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: io_flush
|
Function: io_flush
|
||||||
Empties all buffers and writes all pending data.
|
Empties all buffers and writes all pending data.
|
||||||
|
|
||||||
|
@ -274,22 +289,77 @@ int io_close(IOHANDLE io);
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Returns 0 on success.
|
Returns 0 on success.
|
||||||
*****/
|
*/
|
||||||
int io_flush(IOHANDLE io);
|
int io_flush(IOHANDLE io);
|
||||||
|
|
||||||
/**** Group: Threads ****/
|
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
|
Function: io_stdin
|
||||||
|
Returns an <IOHANDLE> to the standard input.
|
||||||
|
*/
|
||||||
|
IOHANDLE io_stdin();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: io_stdout
|
||||||
|
Returns an <IOHANDLE> to the standard output.
|
||||||
|
*/
|
||||||
|
IOHANDLE io_stdout();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: io_stderr
|
||||||
|
Returns an <IOHANDLE> to the standard error.
|
||||||
|
*/
|
||||||
|
IOHANDLE io_stderr();
|
||||||
|
|
||||||
|
|
||||||
|
/* Group: Threads */
|
||||||
|
|
||||||
|
/*
|
||||||
Function: thread_sleep
|
Function: thread_sleep
|
||||||
|
Suspends the current thread for a given period.
|
||||||
Suspends the current thread for a given period.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
milliseconds - Number of milliseconds to sleep.
|
milliseconds - Number of milliseconds to sleep.
|
||||||
*****/
|
*/
|
||||||
void thread_sleep(int milliseconds);
|
void thread_sleep(int milliseconds);
|
||||||
|
|
||||||
/**** Group: Locks ****/
|
/*
|
||||||
|
Function: thread_create
|
||||||
|
Creates a new thread.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
threadfunc - Entry point for the new thread.
|
||||||
|
user - Pointer to pass to the thread.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void *thread_create(void (*threadfunc)(void *), void *user);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: thread_wait
|
||||||
|
Waits for a thread to be done or destroyed.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
thread - Thread to wait for.
|
||||||
|
*/
|
||||||
|
void thread_wait(void *thread);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: thread_destoy
|
||||||
|
Destroys a thread.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
thread - Thread to destroy.
|
||||||
|
*/
|
||||||
|
void thread_destroy(void *thread);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: thread_yeild
|
||||||
|
Yeild the current threads execution slice.
|
||||||
|
*/
|
||||||
|
void thread_yield();
|
||||||
|
|
||||||
|
|
||||||
|
/* Group: Locks */
|
||||||
typedef void* LOCK;
|
typedef void* LOCK;
|
||||||
|
|
||||||
LOCK lock_create();
|
LOCK lock_create();
|
||||||
|
@ -299,7 +369,7 @@ int lock_try(LOCK lock);
|
||||||
void lock_wait(LOCK lock);
|
void lock_wait(LOCK lock);
|
||||||
void lock_release(LOCK lock);
|
void lock_release(LOCK lock);
|
||||||
|
|
||||||
/**** Group: Timer ****/
|
/* Group: Timer */
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
/* if compiled with -pedantic-errors it will complain about long
|
/* if compiled with -pedantic-errors it will complain about long
|
||||||
not being a C90 thing.
|
not being a C90 thing.
|
||||||
|
@ -308,71 +378,88 @@ __extension__ typedef long long int64;
|
||||||
#else
|
#else
|
||||||
typedef long long int64;
|
typedef long long int64;
|
||||||
#endif
|
#endif
|
||||||
/*****
|
/*
|
||||||
Function: time_get
|
Function: time_get
|
||||||
|
Fetches a sample from a high resolution timer.
|
||||||
Fetches a sample from a high resolution timer.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Current value of the timer.
|
Current value of the timer.
|
||||||
|
|
||||||
Remarks:
|
Remarks:
|
||||||
To know how fast the timer is ticking, see <time_freq>.
|
To know how fast the timer is ticking, see <time_freq>.
|
||||||
*****/
|
*/
|
||||||
int64 time_get();
|
int64 time_get();
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: time_freq
|
Function: time_freq
|
||||||
|
Returns the frequency of the high resolution timer.
|
||||||
Returns the frequency of the high resolution timer.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Returns the frequency of the high resolution timer.
|
Returns the frequency of the high resolution timer.
|
||||||
*****/
|
*/
|
||||||
int64 time_freq();
|
int64 time_freq();
|
||||||
|
|
||||||
/**** Group: Network General ipv4 ****/
|
/*
|
||||||
|
Function: time_timestamp
|
||||||
|
Retrives the current time as a UNIX timestamp
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The time as a UNIX timestamp
|
||||||
|
*/
|
||||||
|
unsigned time_timestamp();
|
||||||
|
|
||||||
|
/* Group: Network General ipv4 */
|
||||||
typedef int NETSOCKET;
|
typedef int NETSOCKET;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NETSOCKET_INVALID = -1
|
NETSOCKET_INVALID = -1,
|
||||||
|
|
||||||
|
NETTYPE_INVALID = 0,
|
||||||
|
NETTYPE_IPV4 = 1,
|
||||||
|
NETTYPE_IPV6 = 2,
|
||||||
|
NETTYPE_ALL = ~0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned char ip[4];
|
unsigned char ip[4];
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
} NETADDR4;
|
} NETADDR4;*/
|
||||||
|
|
||||||
/*****
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int type;
|
||||||
|
unsigned char ip[16];
|
||||||
|
unsigned short port;
|
||||||
|
} NETADDR;
|
||||||
|
|
||||||
|
/*
|
||||||
Function: net_host_lookup
|
Function: net_host_lookup
|
||||||
|
Does a hostname lookup by name and fills out the passed NETADDR struct with the recieved details.
|
||||||
Does a hostname lookup by name and fills out the passed NETADDE4 struct with the recieved details.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
0 on success.
|
0 on success.
|
||||||
*****/
|
*/
|
||||||
int net_host_lookup(const char *hostname, unsigned short port, NETADDR4 *addr);
|
int net_host_lookup(const char *hostname, NETADDR *addr, int types);
|
||||||
|
|
||||||
/**** Group: Network UDP4 ****/
|
/* Group: Network UDP */
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_udp4_create
|
Function: net_udp_create
|
||||||
|
Creates a UDP socket and binds it to a port.
|
||||||
Creates a UDP4 socket and binds it to a port.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
port - Port to bind the socket to.
|
port - Port to bind the socket to.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
On success it returns an handle to the socket. On failure it returns NETSOCKET_INVALID.
|
On success it returns an handle to the socket. On failure it returns NETSOCKET_INVALID.
|
||||||
*****/
|
*/
|
||||||
NETSOCKET net_udp4_create(NETADDR4 bindaddr);
|
NETSOCKET net_udp_create(NETADDR bindaddr);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_udp4_send
|
Function: net_udp_send
|
||||||
|
Sends a packet over an UDP socket.
|
||||||
Sends a packet over an UDP4 socket.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
sock - Socket to use.
|
sock - Socket to use.
|
||||||
|
@ -382,177 +469,322 @@ NETSOCKET net_udp4_create(NETADDR4 bindaddr);
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
On success it returns the number of bytes sent. Returns -1 on error.
|
On success it returns the number of bytes sent. Returns -1 on error.
|
||||||
*****/
|
*/
|
||||||
int net_udp4_send(NETSOCKET sock, const NETADDR4 *addr, const void *data, int size);
|
int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_udp4_recv
|
Function: net_udp_recv
|
||||||
|
Recives a packet over an UDP socket.
|
||||||
Recives a packet over an UDP4 socket.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
sock - Socket to use.
|
sock - Socket to use.
|
||||||
addr - Pointer to an NETADDR4 that will recive the address.
|
addr - Pointer to an NETADDR that will recive the address.
|
||||||
data - Pointer to a buffer that will recive the data.
|
data - Pointer to a buffer that will recive the data.
|
||||||
maxsize - Maximum size to recive.
|
maxsize - Maximum size to recive.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
On success it returns the number of bytes recived. Returns -1 on error.
|
On success it returns the number of bytes recived. Returns -1 on error.
|
||||||
*****/
|
*/
|
||||||
int net_udp4_recv(NETSOCKET sock, NETADDR4 *addr, void *data, int maxsize);
|
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_udp4_close
|
Function: net_udp_close
|
||||||
|
Closes an UDP socket.
|
||||||
Closes an UDP4 socket.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
sock - Socket to close.
|
sock - Socket to close.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Returns 0 on success. -1 on error.
|
Returns 0 on success. -1 on error.
|
||||||
*****/
|
*/
|
||||||
int net_udp4_close(NETSOCKET sock);
|
int net_udp_close(NETSOCKET sock);
|
||||||
|
|
||||||
|
|
||||||
/**** Group: Network TCP4 ****/
|
/* Group: Network TCP */
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_create
|
Function: net_tcp_create
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
NETSOCKET net_tcp4_create(const NETADDR4 *a);
|
NETSOCKET net_tcp_create(const NETADDR *a);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_set_non_blocking
|
Function: net_tcp_set_non_blocking
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_set_non_blocking(NETSOCKET sock);
|
int net_tcp_set_non_blocking(NETSOCKET sock);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_set_non_blocking
|
Function: net_tcp_set_non_blocking
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_set_blocking(NETSOCKET sock);
|
int net_tcp_set_blocking(NETSOCKET sock);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_listen
|
Function: net_tcp_listen
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_listen(NETSOCKET sock, int backlog);
|
int net_tcp_listen(NETSOCKET sock, int backlog);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_accept
|
Function: net_tcp_accept
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR4 *a);
|
int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *a);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_connect
|
Function: net_tcp_connect
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_connect(NETSOCKET sock, const NETADDR4 *a);
|
int net_tcp_connect(NETSOCKET sock, const NETADDR *a);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_connect_non_blocking
|
Function: net_tcp_connect_non_blocking
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_connect_non_blocking(NETSOCKET sock, const NETADDR4 *a);
|
int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_send
|
Function: net_tcp_send
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_send(NETSOCKET sock, const void *data, int size);
|
int net_tcp_send(NETSOCKET sock, const void *data, int size);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_recv
|
Function: net_tcp_recv
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_recv(NETSOCKET sock, void *data, int maxsize);
|
int net_tcp_recv(NETSOCKET sock, void *data, int maxsize);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_tcp4_close
|
Function: net_tcp_close
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_tcp4_close(NETSOCKET sock);
|
int net_tcp_close(NETSOCKET sock);
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_errno
|
Function: net_errno
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_errno();
|
int net_errno();
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_would_block
|
Function: net_would_block
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_would_block();
|
int net_would_block();
|
||||||
|
|
||||||
/*****
|
/*
|
||||||
Function: net_init
|
Function: net_init
|
||||||
|
|
||||||
DOCTODO: serp
|
DOCTODO: serp
|
||||||
*****/
|
*/
|
||||||
int net_init();
|
int net_init();
|
||||||
|
|
||||||
|
/* Group: Strings */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: str_append
|
||||||
|
Appends a string to another.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
dst - Pointer to a buffer that contains a string.
|
||||||
|
src - String to append.
|
||||||
|
dst_size - Size of the buffer of the dst string.
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- The strings are treated as zero-termineted strings.
|
||||||
|
- Garantees that dst string will contain zero-termination.
|
||||||
|
*/
|
||||||
|
void str_append(char *dst, const char *src, int dst_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: str_copy
|
||||||
|
Copies a string to another.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
dst - Pointer to a buffer that shall recive the string.
|
||||||
|
src - String to be copied.
|
||||||
|
dst_size - Size of the buffer dst.
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- The strings are treated as zero-termineted strings.
|
||||||
|
- Garantees that dst string will contain zero-termination.
|
||||||
|
*/
|
||||||
|
void str_copy(char *dst, const char *src, int dst_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: str_format
|
||||||
|
Performs printf formating into a buffer.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
buffer - Pointer to the buffer to recive the formated string.
|
||||||
|
buffer_size - Size of the buffer.
|
||||||
|
format - printf formating string.
|
||||||
|
... - Parameters for the formating.
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- See the C manual for syntax for the printf formating string.
|
||||||
|
- The strings are treated as zero-termineted strings.
|
||||||
|
- Garantees that dst string will contain zero-termination.
|
||||||
|
*/
|
||||||
|
void str_format(char *buffer, int buffer_size, const char *format, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: str_sanitize_strong
|
||||||
|
Replaces all characters below 32 and above 127 with whitespace.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
str - String to sanitize.
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- The strings are treated as zero-termineted strings.
|
||||||
|
*/
|
||||||
|
void str_sanitize_strong(char *str);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: str_sanitize
|
||||||
|
Replaces all characters below 32 and above 127 with whitespace with
|
||||||
|
exception to \r, \n and \r.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
str - String to sanitize.
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- The strings are treated as zero-termineted strings.
|
||||||
|
*/
|
||||||
|
void str_sanitize(char *str);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: str_comp_nocase
|
||||||
|
Compares to strings case insensitive.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
a - String to compare.
|
||||||
|
b - String to compare.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
<0 - String g a is lesser then string b
|
||||||
|
0 - String a is equal to string b
|
||||||
|
>0 - String a is greater then string b
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- Only garanted to work with a-z/A-Z.
|
||||||
|
- The strings are treated as zero-termineted strings.
|
||||||
|
*/
|
||||||
|
int str_comp_nocase(const char *a, const char *b);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: str_find_nocase
|
||||||
|
Finds a string inside another string case insensitive.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
haystack - String to search in
|
||||||
|
needle - String to search for
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A pointer into haystack where the needle was found.
|
||||||
|
Returns NULL of needle could not be found.
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- Only garanted to work with a-z/A-Z.
|
||||||
|
- The strings are treated as zero-termineted strings.
|
||||||
|
*/
|
||||||
|
const char *str_find_nocase(const char *haystack, const char *needle);
|
||||||
|
|
||||||
|
|
||||||
/* NOT DOCUMENTED */
|
/*
|
||||||
|
Function: str_hex
|
||||||
|
Takes a datablock and generates a hexstring of it.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
dst - Buffer to fill with hex data
|
||||||
|
dst_size - size of the buffer
|
||||||
|
data - Data to turn into hex
|
||||||
|
data - Size of the data
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- The desination buffer will be zero-terminated
|
||||||
|
*/
|
||||||
|
void str_hex(char *dst, int dst_size, const void *data, int data_size);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: fs_listdir
|
||||||
|
Lists the files in a directory
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
dir - Directory to list
|
||||||
|
cb - Callback function to call for each entry
|
||||||
|
user - Pointer to give to the callback
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
DOCTODO
|
||||||
|
*/
|
||||||
typedef void (*fs_listdir_callback)(const char *name, int is_dir, void *user);
|
typedef void (*fs_listdir_callback)(const char *name, int is_dir, void *user);
|
||||||
int fs_listdir(const char *dir, fs_listdir_callback cb, void *user);
|
int fs_listdir(const char *dir, fs_listdir_callback cb, void *user);
|
||||||
int fs_storage_path(const char *appname, char *path, int max);
|
|
||||||
|
/*
|
||||||
|
Function: fs_makedir
|
||||||
|
Creates a directory
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
path - Directory to create
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
DOCTODO
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
Does not create several directories if needed. "a/b/c" will result
|
||||||
|
in a failure if b or a does not exist.
|
||||||
|
*/
|
||||||
int fs_makedir(const char *path);
|
int fs_makedir(const char *path);
|
||||||
int net_addr4_cmp(const NETADDR4 *a, const NETADDR4 *b);
|
|
||||||
|
/*
|
||||||
|
Function: fs_storage_path
|
||||||
|
Fetches per user configuration directory.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
DOCTODO
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- Returns ~/.appname on UNIX based systems
|
||||||
|
- Returns %APPDATA%/Appname on Windows based systems
|
||||||
|
*/
|
||||||
|
int fs_storage_path(const char *appname, char *path, int max);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Group: Undocumented
|
||||||
|
*/
|
||||||
|
|
||||||
|
int net_addr_comp(const NETADDR *a, const NETADDR *b);
|
||||||
|
int net_addr_str(const NETADDR *addr, char *string, int max_length);
|
||||||
int net_socket_read_wait(NETSOCKET sock, int time);
|
int net_socket_read_wait(NETSOCKET sock, int time);
|
||||||
|
|
||||||
void mem_debug_dump();
|
void mem_debug_dump();
|
||||||
int mem_allocated();
|
int mem_allocated();
|
||||||
|
|
||||||
void *thread_create(void (*threadfunc)(void *), void *user);
|
|
||||||
void thread_wait(void *thread);
|
|
||||||
void thread_destroy(void *thread);
|
|
||||||
void thread_yield();
|
|
||||||
unsigned time_timestamp();
|
|
||||||
|
|
||||||
void swap_endian(void *data, unsigned elem_size, unsigned num);
|
void swap_endian(void *data, unsigned elem_size, unsigned num);
|
||||||
|
|
||||||
/* #define cache_prefetch(addr) __builtin_prefetch(addr) */
|
|
||||||
|
|
||||||
/*typedef unsigned char [256] pstr;
|
|
||||||
void pstr_format(pstr *str, )*/
|
|
||||||
|
|
||||||
void str_append(char *dst, const char *src, int dst_size);
|
|
||||||
void str_copy(char *dst, const char *src, int dst_size);
|
|
||||||
void str_format(char *buffer, int buffer_size, const char *format, ...);
|
|
||||||
void str_sanitize_strong(char *str);
|
|
||||||
void str_sanitize(char *str);
|
|
||||||
int str_comp_nocase(const char *a, const char *b);
|
|
||||||
const char *str_find_nocase(const char *haystack, const char *needle);
|
|
||||||
void str_hex(char *dst, int dst_size, const void *data, int data_size);
|
|
||||||
|
|
||||||
typedef void (*DBG_LOGGER)(const char *line);
|
typedef void (*DBG_LOGGER)(const char *line);
|
||||||
void dbg_logger(DBG_LOGGER logger);
|
void dbg_logger(DBG_LOGGER logger);
|
||||||
void dbg_logger_stdout();
|
void dbg_logger_stdout();
|
||||||
void dbg_logger_debugger();
|
void dbg_logger_debugger();
|
||||||
void dbg_logger_file(const char *filename);
|
void dbg_logger_file(const char *filename);
|
||||||
|
|
||||||
IOHANDLE io_stdin();
|
|
||||||
IOHANDLE io_stdout();
|
|
||||||
IOHANDLE io_stderr();
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int sent_packets;
|
int sent_packets;
|
||||||
|
@ -561,6 +793,7 @@ typedef struct
|
||||||
int recv_bytes;
|
int recv_bytes;
|
||||||
} NETSTATS;
|
} NETSTATS;
|
||||||
|
|
||||||
|
|
||||||
void net_stats(NETSTATS *stats);
|
void net_stats(NETSTATS *stats);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -29,7 +29,7 @@ static void register_new_state(int state)
|
||||||
register_state_start = time_get();
|
register_state_start = time_get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_send_fwcheckresponse(NETADDR4 *addr)
|
static void register_send_fwcheckresponse(NETADDR *addr)
|
||||||
{
|
{
|
||||||
NETCHUNK packet;
|
NETCHUNK packet;
|
||||||
packet.client_id = -1;
|
packet.client_id = -1;
|
||||||
|
@ -40,7 +40,7 @@ static void register_send_fwcheckresponse(NETADDR4 *addr)
|
||||||
netserver_send(net, &packet);
|
netserver_send(net, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_send_heartbeat(NETADDR4 addr)
|
static void register_send_heartbeat(NETADDR addr)
|
||||||
{
|
{
|
||||||
static unsigned char data[sizeof(SERVERBROWSE_HEARTBEAT) + 2];
|
static unsigned char data[sizeof(SERVERBROWSE_HEARTBEAT) + 2];
|
||||||
unsigned short port = config.sv_port;
|
unsigned short port = config.sv_port;
|
||||||
|
@ -62,7 +62,7 @@ static void register_send_heartbeat(NETADDR4 addr)
|
||||||
netserver_send(net, &packet);
|
netserver_send(net, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_send_count_request(NETADDR4 addr)
|
static void register_send_count_request(NETADDR addr)
|
||||||
{
|
{
|
||||||
NETCHUNK packet;
|
NETCHUNK packet;
|
||||||
packet.client_id = -1;
|
packet.client_id = -1;
|
||||||
|
@ -75,13 +75,13 @@ static void register_send_count_request(NETADDR4 addr)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
int count;
|
int count;
|
||||||
int valid;
|
int valid;
|
||||||
int64 last_send;
|
int64 last_send;
|
||||||
} MASTERSERVER_INFO;
|
} MASTERSERVER_INFO;
|
||||||
|
|
||||||
static MASTERSERVER_INFO masterserver_info[MAX_MASTERSERVERS] = {{{{0}}}};
|
static MASTERSERVER_INFO masterserver_info[MAX_MASTERSERVERS] = {{{0}}};
|
||||||
static int register_registered_server = -1;
|
static int register_registered_server = -1;
|
||||||
|
|
||||||
void register_update()
|
void register_update()
|
||||||
|
@ -111,7 +111,7 @@ void register_update()
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
||||||
{
|
{
|
||||||
NETADDR4 addr = mastersrv_get(i);
|
NETADDR addr = mastersrv_get(i);
|
||||||
masterserver_info[i].addr = addr;
|
masterserver_info[i].addr = addr;
|
||||||
masterserver_info[i].count = 0;
|
masterserver_info[i].count = 0;
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ static void register_got_count(NETCHUNK *p)
|
||||||
|
|
||||||
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
||||||
{
|
{
|
||||||
if(net_addr4_cmp(&masterserver_info[i].addr, &p->address) == 0)
|
if(net_addr_comp(&masterserver_info[i].addr, &p->address) == 0)
|
||||||
{
|
{
|
||||||
masterserver_info[i].count = count;
|
masterserver_info[i].count = count;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -147,8 +147,8 @@ int snap_new_id()
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
int64 now = time_get();
|
int64 now = time_get();
|
||||||
dbg_assert(snap_id_inited == 1, "requesting id too soon");
|
if(!snap_id_inited)
|
||||||
|
snap_init_id();
|
||||||
|
|
||||||
/* process timed ids */
|
/* process timed ids */
|
||||||
while(snap_first_timed_id != -1 && snap_ids[snap_first_timed_id].timeout < now)
|
while(snap_first_timed_id != -1 && snap_ids[snap_first_timed_id].timeout < now)
|
||||||
|
@ -453,16 +453,18 @@ static void server_do_snap()
|
||||||
|
|
||||||
{
|
{
|
||||||
static PERFORMACE_INFO scope = {"compress", 0};
|
static PERFORMACE_INFO scope = {"compress", 0};
|
||||||
|
/*char buffer[512];*/
|
||||||
perf_start(&scope);
|
perf_start(&scope);
|
||||||
snapshot_size = intpack_compress(deltadata, deltasize, compdata);
|
snapshot_size = intpack_compress(deltadata, deltasize, compdata);
|
||||||
|
|
||||||
|
/*str_hex(buffer, sizeof(buffer), compdata, snapshot_size);
|
||||||
|
dbg_msg("", "deltasize=%d -> %d : %s", deltasize, snapshot_size, buffer);*/
|
||||||
|
|
||||||
perf_end();
|
perf_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
numpackets = (snapshot_size+max_size-1)/max_size;
|
numpackets = (snapshot_size+max_size-1)/max_size;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for(n = 0, left = snapshot_size; left; n++)
|
for(n = 0, left = snapshot_size; left; n++)
|
||||||
{
|
{
|
||||||
int chunk = left < max_size ? left : max_size;
|
int chunk = left < max_size ? left : max_size;
|
||||||
|
@ -776,7 +778,7 @@ static void server_process_client_packet(NETCHUNK *packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void server_send_serverinfo(NETADDR4 *addr, int lan)
|
static void server_send_serverinfo(NETADDR *addr, int lan)
|
||||||
{
|
{
|
||||||
NETCHUNK packet;
|
NETCHUNK packet;
|
||||||
PACKER p;
|
PACKER p;
|
||||||
|
@ -904,10 +906,9 @@ static int server_load_map(const char *mapname)
|
||||||
|
|
||||||
static int server_run()
|
static int server_run()
|
||||||
{
|
{
|
||||||
NETADDR4 bindaddr;
|
NETADDR bindaddr;
|
||||||
|
|
||||||
net_init();
|
net_init();
|
||||||
snap_init_id();
|
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
console_register_print_callback(server_send_rcon_line_authed);
|
console_register_print_callback(server_send_rcon_line_authed);
|
||||||
|
@ -920,9 +921,11 @@ static int server_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start server */
|
/* start server */
|
||||||
if(config.sv_bindaddr[0] && net_host_lookup(config.sv_bindaddr, config.sv_port, &bindaddr) == 0)
|
/* TODO: IPv6 support */
|
||||||
|
if(config.sv_bindaddr[0] && net_host_lookup(config.sv_bindaddr, &bindaddr, NETTYPE_IPV4) == 0)
|
||||||
{
|
{
|
||||||
/* sweet! */
|
/* sweet! */
|
||||||
|
bindaddr.port = config.sv_port;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1108,7 +1111,7 @@ static void con_kick(void *result, void *user_data)
|
||||||
static void con_status(void *result, void *user_data)
|
static void con_status(void *result, void *user_data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
NETADDR4 addr;
|
NETADDR addr;
|
||||||
for(i = 0; i < MAX_CLIENTS; i++)
|
for(i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if(clients[i].state == SRVCLIENT_STATE_INGAME)
|
if(clients[i].state == SRVCLIENT_STATE_INGAME)
|
||||||
|
|
|
@ -880,7 +880,7 @@ void render_game()
|
||||||
// don't use predicted
|
// don't use predicted
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
local_character_pos = mix(predicted_prev_player.pos, predicted_player.pos, client_predintratick());
|
local_character_pos = mix(predicted_prev_char.pos, predicted_char.pos, client_predintratick());
|
||||||
}
|
}
|
||||||
else if(netobjects.local_character && netobjects.local_prev_character)
|
else if(netobjects.local_character && netobjects.local_prev_character)
|
||||||
{
|
{
|
||||||
|
@ -1663,3 +1663,8 @@ void render_game()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" const char *modc_getitemname(int type)
|
||||||
|
{
|
||||||
|
return netobj_get_name(type);
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <game/g_vmath.hpp>
|
#include <game/g_vmath.hpp>
|
||||||
#include <game/g_protocol.hpp>
|
#include <game/generated/g_protocol.hpp>
|
||||||
#include <game/g_game.hpp>
|
#include <game/g_game.hpp>
|
||||||
|
|
||||||
#include <game/client/gc_render.hpp>
|
#include <game/client/gc_render.hpp>
|
||||||
|
@ -22,8 +22,8 @@ extern vec2 local_target_pos;
|
||||||
// snap pointers
|
// snap pointers
|
||||||
struct SNAPSTATE
|
struct SNAPSTATE
|
||||||
{
|
{
|
||||||
const NETOBJ_PLAYER_CHARACTER *local_character;
|
const NETOBJ_CHARACTER *local_character;
|
||||||
const NETOBJ_PLAYER_CHARACTER *local_prev_character;
|
const NETOBJ_CHARACTER *local_prev_character;
|
||||||
const NETOBJ_PLAYER_INFO *local_info;
|
const NETOBJ_PLAYER_INFO *local_info;
|
||||||
const NETOBJ_FLAG *flags[2];
|
const NETOBJ_FLAG *flags[2];
|
||||||
const NETOBJ_GAME *gameobj;
|
const NETOBJ_GAME *gameobj;
|
||||||
|
@ -46,8 +46,8 @@ extern const NETOBJ_GAME *gameobj;
|
||||||
extern TUNING_PARAMS tuning;
|
extern TUNING_PARAMS tuning;
|
||||||
|
|
||||||
// predicted players
|
// predicted players
|
||||||
extern PLAYER_CORE predicted_prev_player;
|
extern CHARACTER_CORE predicted_prev_char;
|
||||||
extern PLAYER_CORE predicted_player;
|
extern CHARACTER_CORE predicted_char;
|
||||||
|
|
||||||
// input
|
// input
|
||||||
extern NETOBJ_PLAYER_INPUT input_data;
|
extern NETOBJ_PLAYER_INPUT input_data;
|
||||||
|
@ -148,7 +148,7 @@ struct CLIENT_DATA
|
||||||
int team;
|
int team;
|
||||||
int emoticon;
|
int emoticon;
|
||||||
int emoticon_start;
|
int emoticon_start;
|
||||||
PLAYER_CORE predicted;
|
CHARACTER_CORE predicted;
|
||||||
|
|
||||||
TEE_RENDER_INFO skin_info; // this is what the server reports
|
TEE_RENDER_INFO skin_info; // this is what the server reports
|
||||||
TEE_RENDER_INFO render_info; // this is what we use
|
TEE_RENDER_INFO render_info; // this is what we use
|
||||||
|
|
|
@ -56,6 +56,9 @@ static void load_sounds_thread(void *do_render)
|
||||||
|
|
||||||
extern "C" void modc_init()
|
extern "C" void modc_init()
|
||||||
{
|
{
|
||||||
|
for(int i = 0; i < NUM_NETOBJTYPES; i++)
|
||||||
|
snap_set_staticsize(i, netobj_get_size(i));
|
||||||
|
|
||||||
static FONT_SET default_font;
|
static FONT_SET default_font;
|
||||||
int64 start = time_get();
|
int64 start = time_get();
|
||||||
|
|
||||||
|
@ -128,17 +131,17 @@ extern "C" void modc_shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PLAYER_CORE predicted_prev_player;
|
CHARACTER_CORE predicted_prev_char;
|
||||||
PLAYER_CORE predicted_player;
|
CHARACTER_CORE predicted_char;
|
||||||
static int predicted_tick = 0;
|
static int predicted_tick = 0;
|
||||||
static int last_new_predicted_tick = -1;
|
static int last_new_predicted_tick = -1;
|
||||||
|
|
||||||
extern "C" void modc_predict()
|
extern "C" void modc_predict()
|
||||||
{
|
{
|
||||||
PLAYER_CORE before_prev_player = predicted_prev_player;
|
CHARACTER_CORE before_prev_char = predicted_prev_char;
|
||||||
PLAYER_CORE before_player = predicted_player;
|
CHARACTER_CORE before_char = predicted_char;
|
||||||
|
|
||||||
// repredict player
|
// repredict character
|
||||||
WORLD_CORE world;
|
WORLD_CORE world;
|
||||||
world.tuning = tuning;
|
world.tuning = tuning;
|
||||||
int local_cid = -1;
|
int local_cid = -1;
|
||||||
|
@ -150,11 +153,11 @@ extern "C" void modc_predict()
|
||||||
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
int client_id = item.id;
|
int client_id = item.id;
|
||||||
|
|
||||||
if(item.type == NETOBJTYPE_PLAYER_CHARACTER)
|
if(item.type == NETOBJTYPE_CHARACTER)
|
||||||
{
|
{
|
||||||
const NETOBJ_PLAYER_CHARACTER *character = (const NETOBJ_PLAYER_CHARACTER *)data;
|
const NETOBJ_CHARACTER *character = (const NETOBJ_CHARACTER *)data;
|
||||||
client_datas[client_id].predicted.world = &world;
|
client_datas[client_id].predicted.world = &world;
|
||||||
world.players[client_id] = &client_datas[client_id].predicted;
|
world.characters[client_id] = &client_datas[client_id].predicted;
|
||||||
|
|
||||||
client_datas[client_id].predicted.read(character);
|
client_datas[client_id].predicted.read(character);
|
||||||
}
|
}
|
||||||
|
@ -174,45 +177,45 @@ extern "C" void modc_predict()
|
||||||
for(int tick = client_tick()+1; tick <= client_predtick(); tick++)
|
for(int tick = client_tick()+1; tick <= client_predtick(); tick++)
|
||||||
{
|
{
|
||||||
// fetch the local
|
// fetch the local
|
||||||
if(tick == client_predtick() && world.players[local_cid])
|
if(tick == client_predtick() && world.characters[local_cid])
|
||||||
predicted_prev_player = *world.players[local_cid];
|
predicted_prev_char = *world.characters[local_cid];
|
||||||
|
|
||||||
// first calculate where everyone should move
|
// first calculate where everyone should move
|
||||||
for(int c = 0; c < MAX_CLIENTS; c++)
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
{
|
{
|
||||||
if(!world.players[c])
|
if(!world.characters[c])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mem_zero(&world.players[c]->input, sizeof(world.players[c]->input));
|
mem_zero(&world.characters[c]->input, sizeof(world.characters[c]->input));
|
||||||
if(local_cid == c)
|
if(local_cid == c)
|
||||||
{
|
{
|
||||||
// apply player input
|
// apply player input
|
||||||
int *input = client_get_input(tick);
|
int *input = client_get_input(tick);
|
||||||
if(input)
|
if(input)
|
||||||
world.players[c]->input = *((NETOBJ_PLAYER_INPUT*)input);
|
world.characters[c]->input = *((NETOBJ_PLAYER_INPUT*)input);
|
||||||
}
|
}
|
||||||
|
|
||||||
world.players[c]->tick();
|
world.characters[c]->tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
// move all players and quantize their data
|
// move all players and quantize their data
|
||||||
for(int c = 0; c < MAX_CLIENTS; c++)
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
{
|
{
|
||||||
if(!world.players[c])
|
if(!world.characters[c])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
world.players[c]->move();
|
world.characters[c]->move();
|
||||||
world.players[c]->quantize();
|
world.characters[c]->quantize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tick > last_new_predicted_tick)
|
if(tick > last_new_predicted_tick)
|
||||||
{
|
{
|
||||||
last_new_predicted_tick = tick;
|
last_new_predicted_tick = tick;
|
||||||
|
|
||||||
if(local_cid != -1 && world.players[local_cid])
|
if(local_cid != -1 && world.characters[local_cid])
|
||||||
{
|
{
|
||||||
vec2 pos = world.players[local_cid]->pos;
|
vec2 pos = world.characters[local_cid]->pos;
|
||||||
int events = world.players[local_cid]->triggered_events;
|
int events = world.characters[local_cid]->triggered_events;
|
||||||
if(events&COREEVENT_GROUND_JUMP) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos);
|
if(events&COREEVENT_GROUND_JUMP) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos);
|
||||||
if(events&COREEVENT_AIR_JUMP)
|
if(events&COREEVENT_AIR_JUMP)
|
||||||
{
|
{
|
||||||
|
@ -232,26 +235,26 @@ extern "C" void modc_predict()
|
||||||
(int)world.players[c]->vel.x, (int)world.players[c]->vel.y);*/
|
(int)world.players[c]->vel.x, (int)world.players[c]->vel.y);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tick == client_predtick() && world.players[local_cid])
|
if(tick == client_predtick() && world.characters[local_cid])
|
||||||
predicted_player = *world.players[local_cid];
|
predicted_char = *world.characters[local_cid];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config.debug && predicted_tick == client_predtick())
|
if(config.debug && predicted_tick == client_predtick())
|
||||||
{
|
{
|
||||||
if(predicted_player.pos.x != before_player.pos.x ||
|
if(predicted_char.pos.x != before_char.pos.x ||
|
||||||
predicted_player.pos.y != before_player.pos.y)
|
predicted_char.pos.y != before_char.pos.y)
|
||||||
{
|
{
|
||||||
dbg_msg("client", "prediction error, (%d %d) (%d %d)",
|
dbg_msg("client", "prediction error, (%d %d) (%d %d)",
|
||||||
(int)before_player.pos.x, (int)before_player.pos.y,
|
(int)before_char.pos.x, (int)before_char.pos.y,
|
||||||
(int)predicted_player.pos.x, (int)predicted_player.pos.y);
|
(int)predicted_char.pos.x, (int)predicted_char.pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(predicted_prev_player.pos.x != before_prev_player.pos.x ||
|
if(predicted_prev_char.pos.x != before_prev_char.pos.x ||
|
||||||
predicted_prev_player.pos.y != before_prev_player.pos.y)
|
predicted_prev_char.pos.y != before_prev_char.pos.y)
|
||||||
{
|
{
|
||||||
dbg_msg("client", "prediction error, prev (%d %d) (%d %d)",
|
dbg_msg("client", "prediction error, prev (%d %d) (%d %d)",
|
||||||
(int)before_prev_player.pos.x, (int)before_prev_player.pos.y,
|
(int)before_prev_char.pos.x, (int)before_prev_char.pos.y,
|
||||||
(int)predicted_prev_player.pos.x, (int)predicted_prev_player.pos.y);
|
(int)predicted_prev_char.pos.x, (int)predicted_prev_char.pos.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,15 +319,15 @@ extern "C" void modc_newsnapshot()
|
||||||
if(info->local)
|
if(info->local)
|
||||||
{
|
{
|
||||||
netobjects.local_info = info;
|
netobjects.local_info = info;
|
||||||
const void *data = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_CHARACTER, item.id);
|
const void *data = snap_find_item(SNAP_CURRENT, NETOBJTYPE_CHARACTER, item.id);
|
||||||
if(data)
|
if(data)
|
||||||
{
|
{
|
||||||
netobjects.local_character = (const NETOBJ_PLAYER_CHARACTER *)data;
|
netobjects.local_character = (const NETOBJ_CHARACTER *)data;
|
||||||
local_character_pos = vec2(netobjects.local_character->x, netobjects.local_character->y);
|
local_character_pos = vec2(netobjects.local_character->x, netobjects.local_character->y);
|
||||||
|
|
||||||
const void *p = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_CHARACTER, item.id);
|
const void *p = snap_find_item(SNAP_PREV, NETOBJTYPE_CHARACTER, item.id);
|
||||||
if(p)
|
if(p)
|
||||||
netobjects.local_prev_character = (NETOBJ_PLAYER_CHARACTER *)p;
|
netobjects.local_prev_character = (NETOBJ_CHARACTER *)p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../g_version.hpp"
|
#include "../g_version.hpp"
|
||||||
#include "../g_protocol.hpp"
|
#include <game/generated/g_protocol.hpp>
|
||||||
|
|
||||||
#include "../generated/gc_data.hpp"
|
#include "../generated/gc_data.hpp"
|
||||||
#include "gc_render.hpp"
|
#include "gc_render.hpp"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <engine/e_client_interface.h>
|
#include <engine/e_client_interface.h>
|
||||||
#include <engine/e_config.h>
|
#include <engine/e_config.h>
|
||||||
#include <game/generated/gc_data.hpp>
|
#include <game/generated/gc_data.hpp>
|
||||||
#include <game/g_protocol.hpp>
|
#include <game/generated/g_protocol.hpp>
|
||||||
#include <game/g_math.hpp>
|
#include <game/g_math.hpp>
|
||||||
#include <game/g_layers.hpp>
|
#include <game/g_layers.hpp>
|
||||||
#include "gc_render.hpp"
|
#include "gc_render.hpp"
|
||||||
|
@ -473,7 +473,7 @@ static void render_players()
|
||||||
SNAP_ITEM item;
|
SNAP_ITEM item;
|
||||||
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
|
|
||||||
if(item.type == NETOBJTYPE_PLAYER_CHARACTER)
|
if(item.type == NETOBJTYPE_CHARACTER)
|
||||||
{
|
{
|
||||||
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
||||||
const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, item.id);
|
const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, item.id);
|
||||||
|
@ -482,8 +482,8 @@ static void render_players()
|
||||||
if(prev && prev_info && info)
|
if(prev && prev_info && info)
|
||||||
{
|
{
|
||||||
render_player(
|
render_player(
|
||||||
(const NETOBJ_PLAYER_CHARACTER *)prev,
|
(const NETOBJ_CHARACTER *)prev,
|
||||||
(const NETOBJ_PLAYER_CHARACTER *)data,
|
(const NETOBJ_CHARACTER *)data,
|
||||||
(const NETOBJ_PLAYER_INFO *)prev_info,
|
(const NETOBJ_PLAYER_INFO *)prev_info,
|
||||||
(const NETOBJ_PLAYER_INFO *)info
|
(const NETOBJ_PLAYER_INFO *)info
|
||||||
);
|
);
|
||||||
|
|
|
@ -66,7 +66,7 @@ void render_pickup(const struct NETOBJ_PICKUP *prev, const struct NETOBJ_PICKUP
|
||||||
void render_projectile(const struct NETOBJ_PROJECTILE *current, int itemid);
|
void render_projectile(const struct NETOBJ_PROJECTILE *current, int itemid);
|
||||||
void render_laser(const struct NETOBJ_LASER *current);
|
void render_laser(const struct NETOBJ_LASER *current);
|
||||||
void render_player(
|
void render_player(
|
||||||
const struct NETOBJ_PLAYER_CHARACTER *prev_char, const struct NETOBJ_PLAYER_CHARACTER *player_char,
|
const struct NETOBJ_CHARACTER *prev_char, const struct NETOBJ_CHARACTER *player_char,
|
||||||
const struct NETOBJ_PLAYER_INFO *prev_info, const struct NETOBJ_PLAYER_INFO *player_info);
|
const struct NETOBJ_PLAYER_INFO *prev_info, const struct NETOBJ_PLAYER_INFO *player_info);
|
||||||
|
|
||||||
// map render methods (gc_render_map.cpp)
|
// map render methods (gc_render_map.cpp)
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <engine/e_client_interface.h>
|
#include <engine/e_client_interface.h>
|
||||||
#include <engine/e_config.h>
|
#include <engine/e_config.h>
|
||||||
#include "../generated/gc_data.hpp"
|
#include <game/generated/gc_data.hpp>
|
||||||
#include "../g_protocol.hpp"
|
#include <game/generated/g_protocol.hpp>
|
||||||
#include "../g_math.hpp"
|
#include "../g_math.hpp"
|
||||||
#include "gc_render.hpp"
|
#include "gc_render.hpp"
|
||||||
#include "gc_anim.hpp"
|
#include "gc_anim.hpp"
|
||||||
|
@ -265,14 +265,14 @@ static void render_hand(TEE_RENDER_INFO *info, vec2 center_pos, vec2 dir, float
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_player(
|
void render_player(
|
||||||
const NETOBJ_PLAYER_CHARACTER *prev_char,
|
const NETOBJ_CHARACTER *prev_char,
|
||||||
const NETOBJ_PLAYER_CHARACTER *player_char,
|
const NETOBJ_CHARACTER *player_char,
|
||||||
const NETOBJ_PLAYER_INFO *prev_info,
|
const NETOBJ_PLAYER_INFO *prev_info,
|
||||||
const NETOBJ_PLAYER_INFO *player_info
|
const NETOBJ_PLAYER_INFO *player_info
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NETOBJ_PLAYER_CHARACTER prev;
|
NETOBJ_CHARACTER prev;
|
||||||
NETOBJ_PLAYER_CHARACTER player;
|
NETOBJ_CHARACTER player;
|
||||||
prev = *prev_char;
|
prev = *prev_char;
|
||||||
player = *player_char;
|
player = *player_char;
|
||||||
|
|
||||||
|
@ -330,8 +330,8 @@ void render_player(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// apply predicted results
|
// apply predicted results
|
||||||
predicted_player.write(&player);
|
predicted_char.write(&player);
|
||||||
predicted_prev_player.write(&prev);
|
predicted_prev_char.write(&prev);
|
||||||
intratick = client_predintratick();
|
intratick = client_predintratick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,8 +403,8 @@ void render_player(
|
||||||
{
|
{
|
||||||
if(netobjects.local_info && player_char->hooked_player == netobjects.local_info->cid)
|
if(netobjects.local_info && player_char->hooked_player == netobjects.local_info->cid)
|
||||||
{
|
{
|
||||||
hook_pos = mix(vec2(predicted_prev_player.pos.x, predicted_prev_player.pos.y),
|
hook_pos = mix(vec2(predicted_prev_char.pos.x, predicted_prev_char.pos.y),
|
||||||
vec2(predicted_player.pos.x, predicted_player.pos.y), client_predintratick());
|
vec2(predicted_char.pos.x, predicted_char.pos.y), client_predintratick());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hook_pos = mix(vec2(prev_char->hook_x, prev_char->hook_y), vec2(player_char->hook_x, player_char->hook_y), client_intratick());
|
hook_pos = mix(vec2(prev_char->hook_x, prev_char->hook_y), vec2(player_char->hook_x, player_char->hook_y), client_intratick());
|
||||||
|
@ -541,7 +541,6 @@ void render_player(
|
||||||
vec2 diry(-dir.y,dir.x);
|
vec2 diry(-dir.y,dir.x);
|
||||||
vec2 muzzlepos = p + dir * data->weapons.id[iw].muzzleoffsetx + diry * offsety;
|
vec2 muzzlepos = p + dir * data->weapons.id[iw].muzzleoffsetx + diry * offsety;
|
||||||
|
|
||||||
dbg_msg("", "%d", data->weapons.id[iw].num_sprite_muzzles);
|
|
||||||
draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons.id[iw].visual_size);
|
draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons.id[iw].visual_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ float velocity_ramp(float value, float start, float range, float curvature)
|
||||||
return 1.0f/pow(curvature, (value-start)/range);
|
return 1.0f/pow(curvature, (value-start)/range);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PLAYER_CORE::reset()
|
void CHARACTER_CORE::reset()
|
||||||
{
|
{
|
||||||
pos = vec2(0,0);
|
pos = vec2(0,0);
|
||||||
vel = vec2(0,0);
|
vel = vec2(0,0);
|
||||||
|
@ -179,7 +179,7 @@ void PLAYER_CORE::reset()
|
||||||
triggered_events = 0;
|
triggered_events = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PLAYER_CORE::tick()
|
void CHARACTER_CORE::tick()
|
||||||
{
|
{
|
||||||
float phys_size = 28.0f;
|
float phys_size = 28.0f;
|
||||||
triggered_events = 0;
|
triggered_events = 0;
|
||||||
|
@ -273,7 +273,7 @@ void PLAYER_CORE::tick()
|
||||||
// Check against other players first
|
// Check against other players first
|
||||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
PLAYER_CORE *p = world->players[i];
|
CHARACTER_CORE *p = world->characters[i];
|
||||||
if(!p || p == this)
|
if(!p || p == this)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ void PLAYER_CORE::tick()
|
||||||
{
|
{
|
||||||
if(hooked_player != -1)
|
if(hooked_player != -1)
|
||||||
{
|
{
|
||||||
PLAYER_CORE *p = world->players[hooked_player];
|
CHARACTER_CORE *p = world->characters[hooked_player];
|
||||||
if(p)
|
if(p)
|
||||||
hook_pos = p->pos;
|
hook_pos = p->pos;
|
||||||
else
|
else
|
||||||
|
@ -366,7 +366,7 @@ void PLAYER_CORE::tick()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
PLAYER_CORE *p = world->players[i];
|
CHARACTER_CORE *p = world->characters[i];
|
||||||
if(!p)
|
if(!p)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -414,7 +414,7 @@ void PLAYER_CORE::tick()
|
||||||
vel = normalize(vel) * 6000;
|
vel = normalize(vel) * 6000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PLAYER_CORE::move()
|
void CHARACTER_CORE::move()
|
||||||
{
|
{
|
||||||
float rampvalue = velocity_ramp(length(vel)*50, world->tuning.velramp_start, world->tuning.velramp_range, world->tuning.velramp_curvature);
|
float rampvalue = velocity_ramp(length(vel)*50, world->tuning.velramp_start, world->tuning.velramp_range, world->tuning.velramp_curvature);
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ void PLAYER_CORE::move()
|
||||||
vel.x = vel.x*(1.0f/rampvalue);
|
vel.x = vel.x*(1.0f/rampvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PLAYER_CORE::write(NETOBJ_PLAYER_CORE *obj_core)
|
void CHARACTER_CORE::write(NETOBJ_CHARACTER_CORE *obj_core)
|
||||||
{
|
{
|
||||||
obj_core->x = (int)pos.x;
|
obj_core->x = (int)pos.x;
|
||||||
obj_core->y = (int)pos.y;
|
obj_core->y = (int)pos.y;
|
||||||
|
@ -450,7 +450,7 @@ void PLAYER_CORE::write(NETOBJ_PLAYER_CORE *obj_core)
|
||||||
obj_core->angle = (int)(a*256.0f);
|
obj_core->angle = (int)(a*256.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PLAYER_CORE::read(const NETOBJ_PLAYER_CORE *obj_core)
|
void CHARACTER_CORE::read(const NETOBJ_CHARACTER_CORE *obj_core)
|
||||||
{
|
{
|
||||||
pos.x = obj_core->x;
|
pos.x = obj_core->x;
|
||||||
pos.y = obj_core->y;
|
pos.y = obj_core->y;
|
||||||
|
@ -466,9 +466,9 @@ void PLAYER_CORE::read(const NETOBJ_PLAYER_CORE *obj_core)
|
||||||
jumped = obj_core->jumped;
|
jumped = obj_core->jumped;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PLAYER_CORE::quantize()
|
void CHARACTER_CORE::quantize()
|
||||||
{
|
{
|
||||||
NETOBJ_PLAYER_CORE c;
|
NETOBJ_CHARACTER_CORE c;
|
||||||
write(&c);
|
write(&c);
|
||||||
read(&c);
|
read(&c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "g_math.hpp"
|
#include "g_math.hpp"
|
||||||
#include "g_collision.hpp"
|
#include "g_collision.hpp"
|
||||||
#include "g_protocol.hpp"
|
#include <game/generated/g_protocol.hpp>
|
||||||
|
|
||||||
struct TUNING_PARAMS
|
struct TUNING_PARAMS
|
||||||
{
|
{
|
||||||
|
@ -114,14 +114,14 @@ class WORLD_CORE
|
||||||
public:
|
public:
|
||||||
WORLD_CORE()
|
WORLD_CORE()
|
||||||
{
|
{
|
||||||
mem_zero(players, sizeof(players));
|
mem_zero(characters, sizeof(characters));
|
||||||
}
|
}
|
||||||
|
|
||||||
TUNING_PARAMS tuning;
|
TUNING_PARAMS tuning;
|
||||||
class PLAYER_CORE *players[MAX_CLIENTS];
|
class CHARACTER_CORE *characters[MAX_CLIENTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
class PLAYER_CORE
|
class CHARACTER_CORE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WORLD_CORE *world;
|
WORLD_CORE *world;
|
||||||
|
@ -144,8 +144,8 @@ public:
|
||||||
void tick();
|
void tick();
|
||||||
void move();
|
void move();
|
||||||
|
|
||||||
void read(const NETOBJ_PLAYER_CORE *obj_core);
|
void read(const NETOBJ_CHARACTER_CORE *obj_core);
|
||||||
void write(NETOBJ_PLAYER_CORE *obj_core);
|
void write(NETOBJ_CHARACTER_CORE *obj_core);
|
||||||
void quantize();
|
void quantize();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,217 +0,0 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
|
||||||
// NOTE: Be very careful when editing this file as it will change the network version
|
|
||||||
|
|
||||||
#ifndef GAME_PROTOCOL_H
|
|
||||||
#define GAME_PROTOCOL_H
|
|
||||||
|
|
||||||
#include <game/generated/g_protocol.hpp>
|
|
||||||
|
|
||||||
// Network stuff
|
|
||||||
/*
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
OBJTYPE_NULL=0,
|
|
||||||
OBJTYPE_GAME,
|
|
||||||
OBJTYPE_PLAYER_INFO,
|
|
||||||
OBJTYPE_PLAYER_CHARACTER, // use this if you are searching for the player entity
|
|
||||||
OBJTYPE_PROJECTILE,
|
|
||||||
OBJTYPE_LASER,
|
|
||||||
OBJTYPE_POWERUP,
|
|
||||||
OBJTYPE_FLAG,
|
|
||||||
EVENT_EXPLOSION,
|
|
||||||
EVENT_DAMAGEINDICATION,
|
|
||||||
EVENT_SOUND_WORLD,
|
|
||||||
EVENT_SMOKE,
|
|
||||||
EVENT_PLAYERSPAWN,
|
|
||||||
EVENT_DEATH,
|
|
||||||
EVENT_AIR_JUMP,
|
|
||||||
|
|
||||||
EVENT_DUMMY
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
MSG_NULL=0,
|
|
||||||
MSG_SAY, // client -> server
|
|
||||||
MSG_CHAT, // server -> client
|
|
||||||
MSG_SETINFO, // server -> client - contains name, skin and color info
|
|
||||||
MSG_KILLMSG, // server -> client
|
|
||||||
MSG_SETTEAM,
|
|
||||||
MSG_JOIN,
|
|
||||||
MSG_QUIT,
|
|
||||||
MSG_EMOTICON,
|
|
||||||
MSG_STARTINFO, // client -> server
|
|
||||||
MSG_CHANGEINFO, // client -> server
|
|
||||||
MSG_READY_TO_ENTER, // server -> client
|
|
||||||
MSG_WEAPON_PICKUP,
|
|
||||||
MSG_SOUND_GLOBAL,
|
|
||||||
MSG_TUNE_PARAMS,
|
|
||||||
MSG_KILL,
|
|
||||||
MSG_EXTRA_PROJECTILE, // server -> client
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
EMOTE_NORMAL=0,
|
|
||||||
EMOTE_PAIN,
|
|
||||||
EMOTE_HAPPY,
|
|
||||||
EMOTE_SURPRISE,
|
|
||||||
EMOTE_ANGRY,
|
|
||||||
EMOTE_BLINK,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
INPUT_STATE_MASK=0x1f,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PLAYERSTATE_UNKNOWN=0,
|
|
||||||
PLAYERSTATE_PLAYING,
|
|
||||||
PLAYERSTATE_IN_MENU,
|
|
||||||
PLAYERSTATE_CHATTING,
|
|
||||||
|
|
||||||
GAMETYPE_DM=0,
|
|
||||||
GAMETYPE_TDM,
|
|
||||||
GAMETYPE_CTF,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct player_input
|
|
||||||
{
|
|
||||||
int left;
|
|
||||||
int right;
|
|
||||||
|
|
||||||
int target_x;
|
|
||||||
int target_y;
|
|
||||||
|
|
||||||
int jump;
|
|
||||||
int fire;
|
|
||||||
int hook;
|
|
||||||
int blink;
|
|
||||||
|
|
||||||
int player_state;
|
|
||||||
|
|
||||||
int wanted_weapon;
|
|
||||||
int next_weapon;
|
|
||||||
int prev_weapon;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ev_common
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ev_explosion : public ev_common
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ev_spawn : public ev_common
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ev_death : public ev_common
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ev_sound : public ev_common
|
|
||||||
{
|
|
||||||
int sound;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ev_damageind : public ev_common
|
|
||||||
{
|
|
||||||
int angle;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct obj_game
|
|
||||||
{
|
|
||||||
int round_start_tick;
|
|
||||||
int game_over;
|
|
||||||
int sudden_death;
|
|
||||||
int paused;
|
|
||||||
|
|
||||||
int score_limit;
|
|
||||||
int time_limit;
|
|
||||||
int gametype;
|
|
||||||
|
|
||||||
int warmup;
|
|
||||||
|
|
||||||
int teamscore[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct obj_projectile
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
int vx, vy; // should be an angle instead
|
|
||||||
int type;
|
|
||||||
int start_tick;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct obj_laser
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
int from_x, from_y;
|
|
||||||
int eval_tick;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct obj_powerup
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
int type; // why do we need two types?
|
|
||||||
int subtype;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct obj_flag
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
int team;
|
|
||||||
int carried_by; // is set if the local player has the flag
|
|
||||||
};
|
|
||||||
|
|
||||||
// core object needed for physics
|
|
||||||
struct obj_player_core
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
int vx, vy;
|
|
||||||
int angle;
|
|
||||||
int jumped;
|
|
||||||
|
|
||||||
int hooked_player;
|
|
||||||
int hook_state;
|
|
||||||
int hook_tick;
|
|
||||||
int hook_x, hook_y;
|
|
||||||
int hook_dx, hook_dy;
|
|
||||||
};
|
|
||||||
|
|
||||||
// info about the player that is only needed when it's on screen
|
|
||||||
struct obj_player_character : public obj_player_core
|
|
||||||
{
|
|
||||||
int player_state;
|
|
||||||
|
|
||||||
int health;
|
|
||||||
int armor;
|
|
||||||
int ammocount;
|
|
||||||
int weaponstage;
|
|
||||||
|
|
||||||
int weapon; // current active weapon
|
|
||||||
|
|
||||||
int emote;
|
|
||||||
|
|
||||||
int attacktick; // num attack ticks left of current attack
|
|
||||||
};
|
|
||||||
|
|
||||||
// information about the player that is always needed
|
|
||||||
struct obj_player_info
|
|
||||||
{
|
|
||||||
int local;
|
|
||||||
int clientid;
|
|
||||||
|
|
||||||
int team;
|
|
||||||
int score;
|
|
||||||
int latency;
|
|
||||||
int latency_flux;
|
|
||||||
};*/
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -2,16 +2,15 @@
|
||||||
#include "../g_game.hpp"
|
#include "../g_game.hpp"
|
||||||
#include "../generated/gs_data.hpp"
|
#include "../generated/gs_data.hpp"
|
||||||
|
|
||||||
|
|
||||||
extern TUNING_PARAMS tuning;
|
extern TUNING_PARAMS tuning;
|
||||||
|
|
||||||
void create_sound_global(int sound, int target=-1);
|
|
||||||
|
|
||||||
inline int cmask_all() { return -1; }
|
inline int cmask_all() { return -1; }
|
||||||
inline int cmask_one(int cid) { return 1<<cid; }
|
inline int cmask_one(int cid) { return 1<<cid; }
|
||||||
inline int cmask_all_except_one(int cid) { return 0x7fffffff^cmask_one(cid); }
|
inline int cmask_all_except_one(int cid) { return 0x7fffffff^cmask_one(cid); }
|
||||||
inline bool cmask_is_set(int mask, int cid) { return (mask&cmask_one(cid)) != 0; }
|
inline bool cmask_is_set(int mask, int cid) { return (mask&cmask_one(cid)) != 0; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
class EVENT_HANDLER
|
class EVENT_HANDLER
|
||||||
{
|
{
|
||||||
|
@ -33,57 +32,94 @@ public:
|
||||||
void snap(int snapping_client);
|
void snap(int snapping_client);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EVENT_HANDLER events;
|
/*
|
||||||
|
Class: Entity
|
||||||
// a basic entity
|
Basic entity class.
|
||||||
|
*/
|
||||||
class ENTITY
|
class ENTITY
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend class GAMEWORLD; // thy these?
|
friend class GAMEWORLD; // thy these?
|
||||||
friend class PLAYER;
|
|
||||||
ENTITY *prev_entity;
|
ENTITY *prev_entity;
|
||||||
ENTITY *next_entity;
|
ENTITY *next_entity;
|
||||||
|
|
||||||
ENTITY *prev_type_entity;
|
ENTITY *prev_type_entity;
|
||||||
ENTITY *next_type_entity;
|
ENTITY *next_type_entity;
|
||||||
protected:
|
protected:
|
||||||
|
bool marked_for_destroy;
|
||||||
int id;
|
int id;
|
||||||
public:
|
|
||||||
float proximity_radius;
|
|
||||||
unsigned flags;
|
|
||||||
int objtype;
|
int objtype;
|
||||||
vec2 pos;
|
public:
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
FLAG_DESTROY=0x00000001,
|
|
||||||
FLAG_PHYSICS=0x00000002,
|
|
||||||
};
|
|
||||||
|
|
||||||
ENTITY(int objtype);
|
ENTITY(int objtype);
|
||||||
virtual ~ENTITY();
|
virtual ~ENTITY();
|
||||||
|
|
||||||
virtual void reset() {}
|
ENTITY *typenext() { return next_type_entity; }
|
||||||
virtual void post_reset() {}
|
ENTITY *typeprev() { return prev_type_entity; }
|
||||||
|
|
||||||
void set_flag(unsigned flag) { flags |= flag; }
|
|
||||||
void clear_flag(unsigned flag) { flags &= ~flag; }
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: destroy
|
||||||
|
Destorys the entity.
|
||||||
|
*/
|
||||||
virtual void destroy() { delete this; }
|
virtual void destroy() { delete this; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: reset
|
||||||
|
Called when the game resets the map. Puts the entity
|
||||||
|
back to it's starting state or perhaps destroys it.
|
||||||
|
*/
|
||||||
|
virtual void reset() {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: tick
|
||||||
|
Called progress the entity to the next tick. Updates
|
||||||
|
and moves the entity to it's new state and position.
|
||||||
|
*/
|
||||||
virtual void tick() {}
|
virtual void tick() {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: tick
|
||||||
|
Called after all entities tick() function has been called.
|
||||||
|
*/
|
||||||
virtual void tick_defered() {}
|
virtual void tick_defered() {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: snap
|
||||||
|
Called when a new snapshot is being generated for a specific
|
||||||
|
client.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
snapping_client - ID of the client which snapshot is
|
||||||
|
being generated. Could be -1 to create a complete
|
||||||
|
snapshot of everything in the game for demo
|
||||||
|
recording.
|
||||||
|
*/
|
||||||
virtual void snap(int snapping_client) {}
|
virtual void snap(int snapping_client) {}
|
||||||
|
|
||||||
virtual bool take_damage(vec2 force, int dmg, int from, int weapon) { return true; }
|
/*
|
||||||
|
Variable: proximity_radius
|
||||||
|
Contains the physical size of the entity.
|
||||||
|
*/
|
||||||
|
float proximity_radius;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Variable: pos
|
||||||
|
Contains the current posititon of the entity.
|
||||||
|
*/
|
||||||
|
vec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class: Game World
|
||||||
|
Tracks all entities in the game. Propagates tick and
|
||||||
|
snap calls to all entities.
|
||||||
|
*/
|
||||||
class GAMEWORLD
|
class GAMEWORLD
|
||||||
{
|
{
|
||||||
void reset();
|
void reset();
|
||||||
void remove_entities();
|
void remove_entities();
|
||||||
public:
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NUM_ENT_TYPES=10, // TODO: are more exact value perhaps? :)
|
NUM_ENT_TYPES=10, // TODO: are more exact value perhaps? :)
|
||||||
|
@ -92,30 +128,108 @@ public:
|
||||||
// TODO: two lists seams kinda not good, shouldn't be needed
|
// TODO: two lists seams kinda not good, shouldn't be needed
|
||||||
ENTITY *first_entity;
|
ENTITY *first_entity;
|
||||||
ENTITY *first_entity_types[NUM_ENT_TYPES];
|
ENTITY *first_entity_types[NUM_ENT_TYPES];
|
||||||
bool paused;
|
|
||||||
bool reset_requested;
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool reset_requested;
|
||||||
|
bool paused;
|
||||||
WORLD_CORE core;
|
WORLD_CORE core;
|
||||||
|
|
||||||
GAMEWORLD();
|
GAMEWORLD();
|
||||||
~GAMEWORLD();
|
~GAMEWORLD();
|
||||||
int find_entities(vec2 pos, float radius, ENTITY **ents, int max);
|
|
||||||
int find_entities(vec2 pos, float radius, ENTITY **ents, int max, const int* types, int maxtypes);
|
|
||||||
|
|
||||||
void insert_entity(ENTITY *ent);
|
ENTITY *find_first() { return first_entity; }
|
||||||
void destroy_entity(ENTITY *ent);
|
ENTITY *find_first(int type);
|
||||||
void remove_entity(ENTITY *ent);
|
|
||||||
|
|
||||||
//
|
/*
|
||||||
|
Function: find_entities
|
||||||
|
Finds entities close to a position and returns them in a list.
|
||||||
|
Arguments:
|
||||||
|
pos - Position.
|
||||||
|
radius - How close the entities have to be.
|
||||||
|
ents - Pointer to a list that should be filled with the pointers
|
||||||
|
to the entities.
|
||||||
|
max - Number of entities that fits into the ents array.
|
||||||
|
type - Type of the entities to find. -1 for all types.
|
||||||
|
Returns:
|
||||||
|
Number of entities found and added to the ents array.
|
||||||
|
*/
|
||||||
|
int find_entities(vec2 pos, float radius, ENTITY **ents, int max, int type = -1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: interserct_character
|
||||||
|
Finds the closest character that intersects the line.
|
||||||
|
Arguments:
|
||||||
|
pos0 - Start position
|
||||||
|
pos2 - End position
|
||||||
|
radius - How for from the line the character is allowed to be.
|
||||||
|
new_pos - Intersection position
|
||||||
|
notthis - Entity to ignore intersecting with
|
||||||
|
Returns:
|
||||||
|
Returns a pointer to the closest hit or NULL of there is no intersection.
|
||||||
|
*/
|
||||||
|
class CHARACTER *intersect_character(vec2 pos0, vec2 pos1, float radius, vec2 &new_pos, class ENTITY *notthis = 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: closest_character
|
||||||
|
Finds the closest character to a specific point.
|
||||||
|
Arguments:
|
||||||
|
pos - The center position.
|
||||||
|
radius - How far off the character is allowed to be
|
||||||
|
notthis - Entity to ignore
|
||||||
|
Returns:
|
||||||
|
Returns a pointer to the closest character or NULL if no character is close enough.
|
||||||
|
*/
|
||||||
|
class CHARACTER *closest_character(vec2 pos, float radius, ENTITY *notthis);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: insert_entity
|
||||||
|
Adds an entity to the world.
|
||||||
|
Arguments:
|
||||||
|
entity - Entity to add
|
||||||
|
*/
|
||||||
|
void insert_entity(ENTITY *entity);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: remove_entity
|
||||||
|
Removes an entity from the world.
|
||||||
|
Arguments:
|
||||||
|
entity - Entity to remove
|
||||||
|
*/
|
||||||
|
void remove_entity(ENTITY *entity);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: destroy_entity
|
||||||
|
Destroys an entity in the world.
|
||||||
|
Arguments:
|
||||||
|
entity - Entity to destroy
|
||||||
|
*/
|
||||||
|
void destroy_entity(ENTITY *entity);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: snap
|
||||||
|
Calls snap on all the entities in the world to create
|
||||||
|
the snapshot.
|
||||||
|
Arguments:
|
||||||
|
snapping_client - ID of the client which snapshot
|
||||||
|
is being created.
|
||||||
|
*/
|
||||||
void snap(int snapping_client);
|
void snap(int snapping_client);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: tick
|
||||||
|
Calls tick on all the entities in the world to progress
|
||||||
|
the world to the next tick.
|
||||||
|
|
||||||
|
*/
|
||||||
void tick();
|
void tick();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GAMEWORLD *world;
|
/*
|
||||||
|
Class: Game Controller
|
||||||
// game object
|
Controls the main game logic. Keeping track of team and player score,
|
||||||
// TODO: should change name of this one
|
winning conditions and specific game logic.
|
||||||
class GAMECONTROLLER : public ENTITY
|
*/
|
||||||
|
class GAMECONTROLLER
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void cyclemap();
|
void cyclemap();
|
||||||
|
@ -146,25 +260,57 @@ public:
|
||||||
|
|
||||||
bool is_friendly_fire(int cid1, int cid2);
|
bool is_friendly_fire(int cid1, int cid2);
|
||||||
|
|
||||||
virtual bool on_entity(int index, vec2 pos);
|
/*
|
||||||
|
|
||||||
virtual void post_reset();
|
*/
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
|
|
||||||
virtual void on_player_spawn(class PLAYER *p) {}
|
virtual void snap(int snapping_client);
|
||||||
virtual int on_player_death(class PLAYER *victim, class PLAYER *killer, int weapon);
|
|
||||||
|
/*
|
||||||
|
Function: on_entity
|
||||||
|
Called when the map is loaded to process an entity
|
||||||
|
in the map.
|
||||||
|
Arguments:
|
||||||
|
index - Entity index.
|
||||||
|
pos - Where the entity is located in the world.
|
||||||
|
Returns:
|
||||||
|
bool?
|
||||||
|
*/
|
||||||
|
virtual bool on_entity(int index, vec2 pos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: on_character_spawn
|
||||||
|
Called when a character spawns into the game world.
|
||||||
|
Arguments:
|
||||||
|
chr - The character that was spawned.
|
||||||
|
*/
|
||||||
|
virtual void on_character_spawn(class CHARACTER *chr) {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: on_character_death
|
||||||
|
Called when a character in the world dies.
|
||||||
|
Arguments:
|
||||||
|
victim - The character that died.
|
||||||
|
killer - The player that killed it.
|
||||||
|
weapon - What weapon that killed it. Can be -1 for undefined
|
||||||
|
weapon when switching team or player suicides.
|
||||||
|
*/
|
||||||
|
virtual int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
|
||||||
|
|
||||||
virtual void on_player_info_change(class PLAYER *p);
|
virtual void on_player_info_change(class PLAYER *p);
|
||||||
|
|
||||||
virtual void snap(int snapping_client);
|
/*
|
||||||
|
|
||||||
|
*/
|
||||||
|
virtual const char *get_team_name(int team);
|
||||||
virtual int get_auto_team(int notthisid);
|
virtual int get_auto_team(int notthisid);
|
||||||
virtual bool can_join_team(int team, int notthisid);
|
virtual bool can_join_team(int team, int notthisid);
|
||||||
int clampteam(int team);
|
int clampteam(int team);
|
||||||
|
|
||||||
|
virtual void post_reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GAMECONTROLLER *gamecontroller;
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: move to seperate file
|
// TODO: move to seperate file
|
||||||
class PICKUP : public ENTITY
|
class PICKUP : public ENTITY
|
||||||
{
|
{
|
||||||
|
@ -221,25 +367,28 @@ class LASER : public ENTITY
|
||||||
float energy;
|
float energy;
|
||||||
int bounces;
|
int bounces;
|
||||||
int eval_tick;
|
int eval_tick;
|
||||||
PLAYER *owner;
|
CHARACTER *owner;
|
||||||
|
|
||||||
bool hit_player(vec2 from, vec2 to);
|
bool hit_character(vec2 from, vec2 to);
|
||||||
void do_bounce();
|
void do_bounce();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LASER(vec2 pos, vec2 direction, float start_energy, PLAYER *owner);
|
LASER(vec2 pos, vec2 direction, float start_energy, CHARACTER *owner);
|
||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
virtual void snap(int snapping_client);
|
virtual void snap(int snapping_client);
|
||||||
};
|
};
|
||||||
|
|
||||||
// player entity
|
|
||||||
class PLAYER : public ENTITY
|
class CHARACTER : public ENTITY
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const int phys_size = 28;
|
// player controlling this character
|
||||||
|
class PLAYER *player;
|
||||||
|
|
||||||
|
bool alive;
|
||||||
|
|
||||||
// weapon info
|
// weapon info
|
||||||
ENTITY *hitobjects[10];
|
ENTITY *hitobjects[10];
|
||||||
|
@ -264,15 +413,14 @@ public:
|
||||||
int emote_type;
|
int emote_type;
|
||||||
int emote_stop;
|
int emote_stop;
|
||||||
|
|
||||||
int last_action; // last tick that the player took any action ie some input
|
// TODO: clean this up
|
||||||
|
|
||||||
//
|
|
||||||
int client_id;
|
|
||||||
char skin_name[64];
|
char skin_name[64];
|
||||||
int use_custom_color;
|
int use_custom_color;
|
||||||
int color_body;
|
int color_body;
|
||||||
int color_feet;
|
int color_feet;
|
||||||
|
|
||||||
|
int last_action; // last tick that the player took any action ie some input
|
||||||
|
|
||||||
// these are non-heldback inputs
|
// these are non-heldback inputs
|
||||||
NETOBJ_PLAYER_INPUT latest_previnput;
|
NETOBJ_PLAYER_INPUT latest_previnput;
|
||||||
NETOBJ_PLAYER_INPUT latest_input;
|
NETOBJ_PLAYER_INPUT latest_input;
|
||||||
|
@ -298,40 +446,19 @@ public:
|
||||||
} ninja;
|
} ninja;
|
||||||
|
|
||||||
//
|
//
|
||||||
int score;
|
//int score;
|
||||||
int team;
|
int team;
|
||||||
int player_state; // if the client is chatting, accessing a menu or so
|
int player_state; // if the client is chatting, accessing a menu or so
|
||||||
|
|
||||||
bool spawning;
|
|
||||||
bool dead;
|
|
||||||
int die_tick;
|
|
||||||
vec2 die_pos;
|
|
||||||
|
|
||||||
// latency calculations
|
|
||||||
int latency_accum;
|
|
||||||
int latency_accum_min;
|
|
||||||
int latency_accum_max;
|
|
||||||
int latency_avg;
|
|
||||||
int latency_min;
|
|
||||||
int latency_max;
|
|
||||||
|
|
||||||
// the player core for the physics
|
// the player core for the physics
|
||||||
PLAYER_CORE core;
|
CHARACTER_CORE core;
|
||||||
|
|
||||||
//
|
//
|
||||||
int64 last_chat;
|
CHARACTER();
|
||||||
|
|
||||||
//
|
|
||||||
PLAYER();
|
|
||||||
void init();
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void destroy();
|
virtual void destroy();
|
||||||
|
|
||||||
void try_respawn();
|
|
||||||
void respawn();
|
|
||||||
|
|
||||||
void set_team(int team);
|
|
||||||
|
|
||||||
bool is_grounded();
|
bool is_grounded();
|
||||||
|
|
||||||
void set_weapon(int w);
|
void set_weapon(int w);
|
||||||
|
@ -342,16 +469,122 @@ public:
|
||||||
int handle_weapons();
|
int handle_weapons();
|
||||||
int handle_ninja();
|
int handle_ninja();
|
||||||
|
|
||||||
void on_direct_input(NETOBJ_PLAYER_INPUT *input);
|
void on_predicted_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||||
|
void on_direct_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||||
void fire_weapon();
|
void fire_weapon();
|
||||||
|
|
||||||
virtual void tick();
|
|
||||||
virtual void tick_defered();
|
|
||||||
|
|
||||||
void die(int killer, int weapon);
|
void die(int killer, int weapon);
|
||||||
|
|
||||||
virtual bool take_damage(vec2 force, int dmg, int from, int weapon);
|
bool take_damage(vec2 force, int dmg, int from, int weapon);
|
||||||
|
|
||||||
|
|
||||||
|
bool spawn(PLAYER *player, vec2 pos, int team);
|
||||||
|
//bool init_tryspawn(int team);
|
||||||
|
bool remove();
|
||||||
|
|
||||||
|
static const int phys_size = 28;
|
||||||
|
|
||||||
|
virtual void tick();
|
||||||
|
virtual void tick_defered();
|
||||||
virtual void snap(int snaping_client);
|
virtual void snap(int snaping_client);
|
||||||
|
|
||||||
|
bool increase_health(int amount);
|
||||||
|
bool increase_armor(int amount);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern PLAYER *players;
|
// player object
|
||||||
|
class PLAYER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PLAYER();
|
||||||
|
|
||||||
|
// TODO: clean this up
|
||||||
|
char skin_name[64];
|
||||||
|
int use_custom_color;
|
||||||
|
int color_body;
|
||||||
|
int color_feet;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool spawning;
|
||||||
|
int client_id;
|
||||||
|
int team;
|
||||||
|
int score;
|
||||||
|
|
||||||
|
//
|
||||||
|
int64 last_chat;
|
||||||
|
|
||||||
|
// network latency calculations
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int accum;
|
||||||
|
int accum_min;
|
||||||
|
int accum_max;
|
||||||
|
int avg;
|
||||||
|
int min;
|
||||||
|
int max;
|
||||||
|
} latency;
|
||||||
|
|
||||||
|
CHARACTER character;
|
||||||
|
|
||||||
|
// this is used for snapping so we know how we can clip the view for the player
|
||||||
|
vec2 view_pos;
|
||||||
|
|
||||||
|
void init(int client_id);
|
||||||
|
|
||||||
|
CHARACTER *get_character();
|
||||||
|
|
||||||
|
void kill_character();
|
||||||
|
|
||||||
|
void try_respawn();
|
||||||
|
void respawn();
|
||||||
|
void set_team(int team);
|
||||||
|
|
||||||
|
void tick();
|
||||||
|
void snap(int snaping_client);
|
||||||
|
|
||||||
|
void on_direct_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||||
|
void on_predicted_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||||
|
void on_disconnect();
|
||||||
|
};
|
||||||
|
|
||||||
|
class GAMECONTEXT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GAMECONTEXT();
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
EVENT_HANDLER events;
|
||||||
|
PLAYER players[MAX_CLIENTS];
|
||||||
|
|
||||||
|
GAMECONTROLLER *controller;
|
||||||
|
GAMEWORLD world;
|
||||||
|
|
||||||
|
void tick();
|
||||||
|
void snap(int client_id);
|
||||||
|
|
||||||
|
// helper functions
|
||||||
|
void create_damageind(vec2 p, float angle_mod, int amount);
|
||||||
|
void create_explosion(vec2 p, int owner, int weapon, bool bnodamage);
|
||||||
|
void create_smoke(vec2 p);
|
||||||
|
void create_playerspawn(vec2 p);
|
||||||
|
void create_death(vec2 p, int who);
|
||||||
|
void create_sound(vec2 pos, int sound, int mask=-1);
|
||||||
|
void create_sound_global(int sound, int target=-1);
|
||||||
|
|
||||||
|
// network
|
||||||
|
void send_chat(int cid, int team, const char *text);
|
||||||
|
void send_emoticon(int cid, int emoticon);
|
||||||
|
void send_weapon_pickup(int cid, int weapon);
|
||||||
|
void send_broadcast(const char *text, int cid);
|
||||||
|
void send_info(int who, int to_who);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GAMECONTEXT game;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CHAT_ALL=-2,
|
||||||
|
CHAT_SPEC=-1,
|
||||||
|
CHAT_RED=0,
|
||||||
|
CHAT_BLUE=1
|
||||||
|
};
|
||||||
|
|
140
src/game/server/gs_ent_pickup.cpp
Normal file
140
src/game/server/gs_ent_pickup.cpp
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
#include <engine/e_server_interface.h>
|
||||||
|
#include "gs_common.hpp"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// powerup
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
PICKUP::PICKUP(int _type, int _subtype)
|
||||||
|
: ENTITY(NETOBJTYPE_PICKUP)
|
||||||
|
{
|
||||||
|
type = _type;
|
||||||
|
subtype = _subtype;
|
||||||
|
proximity_radius = phys_size;
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
// TODO: should this be done here?
|
||||||
|
game.world.insert_entity(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PICKUP::reset()
|
||||||
|
{
|
||||||
|
if (data->pickups[type].spawndelay > 0)
|
||||||
|
spawntick = server_tick() + server_tickspeed() * data->pickups[type].spawndelay;
|
||||||
|
else
|
||||||
|
spawntick = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PICKUP::tick()
|
||||||
|
{
|
||||||
|
// wait for respawn
|
||||||
|
if(spawntick > 0)
|
||||||
|
{
|
||||||
|
if(server_tick() > spawntick)
|
||||||
|
{
|
||||||
|
// respawn
|
||||||
|
spawntick = -1;
|
||||||
|
|
||||||
|
if(type == POWERUP_WEAPON)
|
||||||
|
game.create_sound(pos, SOUND_WEAPON_SPAWN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check if a player intersected us
|
||||||
|
CHARACTER *chr = game.world.closest_character(pos, 20.0f, 0);
|
||||||
|
if(chr)
|
||||||
|
{
|
||||||
|
// player picked us up, is someone was hooking us, let them go
|
||||||
|
int respawntime = -1;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case POWERUP_HEALTH:
|
||||||
|
if(chr->increase_health(1))
|
||||||
|
{
|
||||||
|
game.create_sound(pos, SOUND_PICKUP_HEALTH);
|
||||||
|
respawntime = data->pickups[type].respawntime;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case POWERUP_ARMOR:
|
||||||
|
if(chr->increase_armor(1))
|
||||||
|
{
|
||||||
|
game.create_sound(pos, SOUND_PICKUP_ARMOR);
|
||||||
|
respawntime = data->pickups[type].respawntime;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POWERUP_WEAPON:
|
||||||
|
if(subtype >= 0 && subtype < NUM_WEAPONS)
|
||||||
|
{
|
||||||
|
if(chr->weapons[subtype].ammo < data->weapons.id[subtype].maxammo || !chr->weapons[subtype].got)
|
||||||
|
{
|
||||||
|
chr->weapons[subtype].got = true;
|
||||||
|
chr->weapons[subtype].ammo = min(data->weapons.id[subtype].maxammo, chr->weapons[subtype].ammo + 10);
|
||||||
|
respawntime = data->pickups[type].respawntime;
|
||||||
|
|
||||||
|
// TODO: data compiler should take care of stuff like this
|
||||||
|
if(subtype == WEAPON_GRENADE)
|
||||||
|
game.create_sound(pos, SOUND_PICKUP_GRENADE);
|
||||||
|
else if(subtype == WEAPON_SHOTGUN)
|
||||||
|
game.create_sound(pos, SOUND_PICKUP_SHOTGUN);
|
||||||
|
else if(subtype == WEAPON_RIFLE)
|
||||||
|
game.create_sound(pos, SOUND_PICKUP_SHOTGUN);
|
||||||
|
|
||||||
|
if(chr->player)
|
||||||
|
game.send_weapon_pickup(chr->player->client_id, subtype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case POWERUP_NINJA:
|
||||||
|
{
|
||||||
|
// activate ninja on target player
|
||||||
|
chr->ninja.activationtick = server_tick();
|
||||||
|
chr->weapons[WEAPON_NINJA].got = true;
|
||||||
|
chr->last_weapon = chr->active_weapon;
|
||||||
|
chr->active_weapon = WEAPON_NINJA;
|
||||||
|
respawntime = data->pickups[type].respawntime;
|
||||||
|
game.create_sound(pos, SOUND_PICKUP_NINJA);
|
||||||
|
|
||||||
|
// loop through all players, setting their emotes
|
||||||
|
ENTITY *ents[64];
|
||||||
|
int num = game.world.find_entities(vec2(0, 0), 1000000, ents, 64, NETOBJTYPE_CHARACTER);
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
CHARACTER *c = (CHARACTER *)ents[i];
|
||||||
|
if (c != chr)
|
||||||
|
{
|
||||||
|
c->emote_type = EMOTE_SURPRISE;
|
||||||
|
c->emote_stop = server_tick() + server_tickspeed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chr->emote_type = EMOTE_ANGRY;
|
||||||
|
chr->emote_stop = server_tick() + 1200 * server_tickspeed() / 1000;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(respawntime >= 0)
|
||||||
|
{
|
||||||
|
dbg_msg("game", "pickup player='%d:%s' item=%d/%d",
|
||||||
|
chr->player->client_id, server_clientname(chr->player->client_id), type, subtype);
|
||||||
|
spawntick = server_tick() + server_tickspeed() * respawntime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PICKUP::snap(int snapping_client)
|
||||||
|
{
|
||||||
|
if(spawntick != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NETOBJ_PICKUP *up = (NETOBJ_PICKUP *)snap_new_item(NETOBJTYPE_PICKUP, id, sizeof(NETOBJ_PICKUP));
|
||||||
|
up->x = (int)pos.x;
|
||||||
|
up->y = (int)pos.y;
|
||||||
|
up->type = type; // TODO: two diffrent types? what gives?
|
||||||
|
up->subtype = subtype;
|
||||||
|
}
|
1128
src/game/server/gs_ent_player.cpp
Normal file
1128
src/game/server/gs_ent_player.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,6 @@
|
||||||
#include "gs_common.hpp"
|
#include "gs_common.hpp"
|
||||||
|
|
||||||
GAMECONTROLLER::GAMECONTROLLER()
|
GAMECONTROLLER::GAMECONTROLLER()
|
||||||
: ENTITY(NETOBJTYPE_GAME)
|
|
||||||
{
|
{
|
||||||
// select gametype
|
// select gametype
|
||||||
if(strcmp(config.sv_gametype, "ctf") == 0)
|
if(strcmp(config.sv_gametype, "ctf") == 0)
|
||||||
|
@ -91,14 +90,32 @@ void GAMECONTROLLER::endround()
|
||||||
if(warmup) // game can't end when we are running warmup
|
if(warmup) // game can't end when we are running warmup
|
||||||
return;
|
return;
|
||||||
|
|
||||||
world->paused = true;
|
game.world.paused = true;
|
||||||
game_over_tick = server_tick();
|
game_over_tick = server_tick();
|
||||||
sudden_death = 0;
|
sudden_death = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GAMECONTROLLER::resetgame()
|
void GAMECONTROLLER::resetgame()
|
||||||
{
|
{
|
||||||
world->reset_requested = true;
|
game.world.reset_requested = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *GAMECONTROLLER::get_team_name(int team)
|
||||||
|
{
|
||||||
|
if(is_teamplay)
|
||||||
|
{
|
||||||
|
if(team == 0)
|
||||||
|
return "red team";
|
||||||
|
else if(team == 1)
|
||||||
|
return "blue team";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(team == 0)
|
||||||
|
return "game";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "spectators";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_separator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
|
static bool is_separator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
|
||||||
|
@ -110,7 +127,7 @@ void GAMECONTROLLER::startround()
|
||||||
round_start_tick = server_tick();
|
round_start_tick = server_tick();
|
||||||
sudden_death = 0;
|
sudden_death = 0;
|
||||||
game_over_tick = -1;
|
game_over_tick = -1;
|
||||||
world->paused = false;
|
game.world.paused = false;
|
||||||
teamscore[0] = 0;
|
teamscore[0] = 0;
|
||||||
teamscore[1] = 0;
|
teamscore[1] = 0;
|
||||||
round_count++;
|
round_count++;
|
||||||
|
@ -178,8 +195,8 @@ void GAMECONTROLLER::post_reset()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if(players[i].client_id != -1)
|
if(game.players[i].client_id != -1)
|
||||||
players[i].respawn();
|
game.players[i].respawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,13 +215,13 @@ void GAMECONTROLLER::on_player_info_change(class PLAYER *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GAMECONTROLLER::on_player_death(class PLAYER *victim, class PLAYER *killer, int weapon)
|
int GAMECONTROLLER::on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon)
|
||||||
{
|
{
|
||||||
// do scoreing
|
// do scoreing
|
||||||
if(!killer)
|
if(!killer)
|
||||||
return 0;
|
return 0;
|
||||||
if(killer == victim)
|
if(killer == victim->player)
|
||||||
victim->score--; // suicide
|
victim->player->score--; // suicide
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(is_teamplay && victim->team == killer->team)
|
if(is_teamplay && victim->team == killer->team)
|
||||||
|
@ -227,7 +244,7 @@ bool GAMECONTROLLER::is_friendly_fire(int cid1, int cid2)
|
||||||
|
|
||||||
if(is_teamplay)
|
if(is_teamplay)
|
||||||
{
|
{
|
||||||
if(players[cid1].team == players[cid2].team)
|
if(game.players[cid1].team == game.players[cid2].team)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,8 +288,8 @@ void GAMECONTROLLER::tick()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if(players[i].client_id != -1)
|
if(game.players[i].client_id != -1)
|
||||||
prog = max(prog, (players[i].score*100)/config.sv_scorelimit);
|
prog = max(prog, (game.players[i].score*100)/config.sv_scorelimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,20 +302,20 @@ void GAMECONTROLLER::tick()
|
||||||
|
|
||||||
void GAMECONTROLLER::snap(int snapping_client)
|
void GAMECONTROLLER::snap(int snapping_client)
|
||||||
{
|
{
|
||||||
NETOBJ_GAME *game = (NETOBJ_GAME *)snap_new_item(NETOBJTYPE_GAME, 0, sizeof(NETOBJ_GAME));
|
NETOBJ_GAME *gameobj = (NETOBJ_GAME *)snap_new_item(NETOBJTYPE_GAME, 0, sizeof(NETOBJ_GAME));
|
||||||
game->paused = world->paused;
|
gameobj->paused = game.world.paused;
|
||||||
game->game_over = game_over_tick==-1?0:1;
|
gameobj->game_over = game_over_tick==-1?0:1;
|
||||||
game->sudden_death = sudden_death;
|
gameobj->sudden_death = sudden_death;
|
||||||
|
|
||||||
game->score_limit = config.sv_scorelimit;
|
gameobj->score_limit = config.sv_scorelimit;
|
||||||
game->time_limit = config.sv_timelimit;
|
gameobj->time_limit = config.sv_timelimit;
|
||||||
game->round_start_tick = round_start_tick;
|
gameobj->round_start_tick = round_start_tick;
|
||||||
game->gametype = gametype;
|
gameobj->gametype = gametype;
|
||||||
|
|
||||||
game->warmup = warmup;
|
gameobj->warmup = warmup;
|
||||||
|
|
||||||
game->teamscore_red = teamscore[0];
|
gameobj->teamscore_red = teamscore[0];
|
||||||
game->teamscore_blue = teamscore[1];
|
gameobj->teamscore_blue = teamscore[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
int GAMECONTROLLER::get_auto_team(int notthisid)
|
int GAMECONTROLLER::get_auto_team(int notthisid)
|
||||||
|
@ -306,10 +323,10 @@ int GAMECONTROLLER::get_auto_team(int notthisid)
|
||||||
int numplayers[2] = {0,0};
|
int numplayers[2] = {0,0};
|
||||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if(players[i].client_id != -1 && players[i].client_id != notthisid)
|
if(game.players[i].client_id != -1 && game.players[i].client_id != notthisid)
|
||||||
{
|
{
|
||||||
if(players[i].team == 0 || players[i].team == 1)
|
if(game.players[i].team == 0 || game.players[i].team == 1)
|
||||||
numplayers[players[i].team]++;
|
numplayers[game.players[i].team]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,10 +345,10 @@ bool GAMECONTROLLER::can_join_team(int team, int notthisid)
|
||||||
int numplayers[2] = {0,0};
|
int numplayers[2] = {0,0};
|
||||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if(players[i].client_id != -1 && players[i].client_id != notthisid)
|
if(game.players[i].client_id != -1 && game.players[i].client_id != notthisid)
|
||||||
{
|
{
|
||||||
if(players[i].team >= 0 || players[i].team == 1)
|
if(game.players[i].team >= 0 || game.players[i].team == 1)
|
||||||
numplayers[players[i].team]++;
|
numplayers[game.players[i].team]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,14 +364,14 @@ void GAMECONTROLLER::do_player_score_wincheck()
|
||||||
int topscore_count = 0;
|
int topscore_count = 0;
|
||||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if(players[i].client_id != -1)
|
if(game.players[i].client_id != -1)
|
||||||
{
|
{
|
||||||
if(players[i].score > topscore)
|
if(game.players[i].score > topscore)
|
||||||
{
|
{
|
||||||
topscore = players[i].score;
|
topscore = game.players[i].score;
|
||||||
topscore_count = 1;
|
topscore_count = 1;
|
||||||
}
|
}
|
||||||
else if(players[i].score == topscore)
|
else if(game.players[i].score == topscore)
|
||||||
topscore_count++;
|
topscore_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,26 +29,22 @@ bool GAMECONTROLLER_CTF::on_entity(int index, vec2 pos)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GAMECONTROLLER_CTF::on_player_spawn(class PLAYER *p)
|
int GAMECONTROLLER_CTF::on_character_death(class CHARACTER *victim, class PLAYER *killer, int weaponid)
|
||||||
{
|
{
|
||||||
}
|
GAMECONTROLLER::on_character_death(victim, killer, weaponid);
|
||||||
|
|
||||||
int GAMECONTROLLER_CTF::on_player_death(class PLAYER *victim, class PLAYER *killer, int weaponid)
|
|
||||||
{
|
|
||||||
GAMECONTROLLER::on_player_death(victim, killer, weaponid);
|
|
||||||
int had_flag = 0;
|
int had_flag = 0;
|
||||||
|
|
||||||
// drop flags
|
// drop flags
|
||||||
for(int fi = 0; fi < 2; fi++)
|
for(int fi = 0; fi < 2; fi++)
|
||||||
{
|
{
|
||||||
FLAG *f = flags[fi];
|
FLAG *f = flags[fi];
|
||||||
if(f && f->carrying_player == killer)
|
if(f && f->carrying_character == &killer->character)
|
||||||
had_flag |= 2;
|
had_flag |= 2;
|
||||||
if(f && f->carrying_player == victim)
|
if(f && f->carrying_character == victim)
|
||||||
{
|
{
|
||||||
create_sound_global(SOUND_CTF_DROP);
|
game.create_sound_global(SOUND_CTF_DROP);
|
||||||
f->drop_tick = server_tick();
|
f->drop_tick = server_tick();
|
||||||
f->carrying_player = 0;
|
f->carrying_character = 0;
|
||||||
f->vel = vec2(0,0);
|
f->vel = vec2(0,0);
|
||||||
|
|
||||||
if(killer && killer->team != victim->team)
|
if(killer && killer->team != victim->team)
|
||||||
|
@ -75,10 +71,10 @@ void GAMECONTROLLER_CTF::tick()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//
|
//
|
||||||
if(f->carrying_player)
|
if(f->carrying_character)
|
||||||
{
|
{
|
||||||
// update flag position
|
// update flag position
|
||||||
f->pos = f->carrying_player->pos;
|
f->pos = f->carrying_character->pos;
|
||||||
|
|
||||||
if(flags[fi^1] && flags[fi^1]->at_stand)
|
if(flags[fi^1] && flags[fi^1]->at_stand)
|
||||||
{
|
{
|
||||||
|
@ -86,35 +82,38 @@ void GAMECONTROLLER_CTF::tick()
|
||||||
{
|
{
|
||||||
// CAPTURE! \o/
|
// CAPTURE! \o/
|
||||||
teamscore[fi^1] += 100;
|
teamscore[fi^1] += 100;
|
||||||
f->carrying_player->score += 5;
|
f->carrying_character->player->score += 5;
|
||||||
|
|
||||||
dbg_msg("game", "flag_capture player='%d:%s'", f->carrying_player->client_id, server_clientname(f->carrying_player->client_id));
|
dbg_msg("game", "flag_capture player='%d:%s'",
|
||||||
|
f->carrying_character->player->client_id,
|
||||||
|
server_clientname(f->carrying_character->player->client_id));
|
||||||
|
|
||||||
for(int i = 0; i < 2; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
flags[i]->reset();
|
flags[i]->reset();
|
||||||
|
|
||||||
create_sound_global(SOUND_CTF_CAPTURE);
|
game.create_sound_global(SOUND_CTF_CAPTURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PLAYER *close_players[MAX_CLIENTS];
|
CHARACTER *close_characters[MAX_CLIENTS];
|
||||||
int types[] = {NETOBJTYPE_PLAYER_CHARACTER};
|
int num = game.world.find_entities(f->pos, 32.0f, (ENTITY**)close_characters, MAX_CLIENTS, NETOBJTYPE_CHARACTER);
|
||||||
int num = world->find_entities(f->pos, 32.0f, (ENTITY**)close_players, MAX_CLIENTS, types, 1);
|
|
||||||
for(int i = 0; i < num; i++)
|
for(int i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
if(close_players[i]->team == f->team)
|
if(close_characters[i]->team == f->team)
|
||||||
{
|
{
|
||||||
// return the flag
|
// return the flag
|
||||||
if(!f->at_stand)
|
if(!f->at_stand)
|
||||||
{
|
{
|
||||||
PLAYER *p = close_players[i];
|
CHARACTER *chr = close_characters[i];
|
||||||
p->score += 1;
|
chr->player->score += 1;
|
||||||
|
|
||||||
dbg_msg("game", "flag_return player='%d:%s'", p->client_id, server_clientname(p->client_id));
|
dbg_msg("game", "flag_return player='%d:%s'",
|
||||||
|
chr->player->client_id,
|
||||||
|
server_clientname(chr->player->client_id));
|
||||||
|
|
||||||
create_sound_global(SOUND_CTF_RETURN);
|
game.create_sound_global(SOUND_CTF_RETURN);
|
||||||
f->reset();
|
f->reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,35 +123,37 @@ void GAMECONTROLLER_CTF::tick()
|
||||||
if(f->at_stand)
|
if(f->at_stand)
|
||||||
teamscore[fi^1]++;
|
teamscore[fi^1]++;
|
||||||
f->at_stand = 0;
|
f->at_stand = 0;
|
||||||
f->carrying_player = close_players[i];
|
f->carrying_character = close_characters[i];
|
||||||
f->carrying_player->score += 1;
|
f->carrying_character->player->score += 1;
|
||||||
|
|
||||||
dbg_msg("game", "flag_grab player='%d:%s'", f->carrying_player->client_id, server_clientname(f->carrying_player->client_id));
|
dbg_msg("game", "flag_grab player='%d:%s'",
|
||||||
|
f->carrying_character->player->client_id,
|
||||||
|
server_clientname(f->carrying_character->player->client_id));
|
||||||
|
|
||||||
for(int c = 0; c < MAX_CLIENTS; c++)
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
{
|
{
|
||||||
if(players[c].client_id == -1)
|
if(game.players[c].client_id == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(players[c].team == fi)
|
if(game.players[c].team == fi)
|
||||||
create_sound_global(SOUND_CTF_GRAB_EN, players[c].client_id);
|
game.create_sound_global(SOUND_CTF_GRAB_EN, game.players[c].client_id);
|
||||||
else
|
else
|
||||||
create_sound_global(SOUND_CTF_GRAB_PL, players[c].client_id);
|
game.create_sound_global(SOUND_CTF_GRAB_PL, game.players[c].client_id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!f->carrying_player && !f->at_stand)
|
if(!f->carrying_character && !f->at_stand)
|
||||||
{
|
{
|
||||||
if(server_tick() > f->drop_tick + server_tickspeed()*30)
|
if(server_tick() > f->drop_tick + server_tickspeed()*30)
|
||||||
{
|
{
|
||||||
create_sound_global(SOUND_CTF_RETURN);
|
game.create_sound_global(SOUND_CTF_RETURN);
|
||||||
f->reset();
|
f->reset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
f->vel.y += world->core.tuning.gravity;
|
f->vel.y += game.world.core.tuning.gravity;
|
||||||
move_box(&f->pos, &f->vel, vec2(f->phys_size, f->phys_size), 0.5f);
|
move_box(&f->pos, &f->vel, vec2(f->phys_size, f->phys_size), 0.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,17 +167,17 @@ FLAG::FLAG(int _team)
|
||||||
{
|
{
|
||||||
team = _team;
|
team = _team;
|
||||||
proximity_radius = phys_size;
|
proximity_radius = phys_size;
|
||||||
carrying_player = 0x0;
|
carrying_character = 0x0;
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
// TODO: should this be done here?
|
// TODO: should this be done here?
|
||||||
world->insert_entity(this);
|
game.world.insert_entity(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FLAG::reset()
|
void FLAG::reset()
|
||||||
{
|
{
|
||||||
carrying_player = 0;
|
carrying_character = 0;
|
||||||
at_stand = 1;
|
at_stand = 1;
|
||||||
pos = stand_pos;
|
pos = stand_pos;
|
||||||
vel = vec2(0,0);
|
vel = vec2(0,0);
|
||||||
|
@ -192,6 +193,6 @@ void FLAG::snap(int snapping_client)
|
||||||
|
|
||||||
if(at_stand)
|
if(at_stand)
|
||||||
flag->carried_by = -2;
|
flag->carried_by = -2;
|
||||||
else if(carrying_player)
|
else if(carrying_character)
|
||||||
flag->carried_by = carrying_player->client_id;
|
flag->carried_by = carrying_character->player->client_id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,7 @@ public:
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
|
|
||||||
virtual bool on_entity(int index, vec2 pos);
|
virtual bool on_entity(int index, vec2 pos);
|
||||||
|
virtual int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
|
||||||
virtual void on_player_spawn(class PLAYER *p);
|
|
||||||
virtual int on_player_death(class PLAYER *victim, class PLAYER *killer, int weapon);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: move to seperate file
|
// TODO: move to seperate file
|
||||||
|
@ -20,7 +18,7 @@ class FLAG : public ENTITY
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const int phys_size = 14;
|
static const int phys_size = 14;
|
||||||
PLAYER *carrying_player;
|
CHARACTER *carrying_character;
|
||||||
vec2 vel;
|
vec2 vel;
|
||||||
vec2 stand_pos;
|
vec2 stand_pos;
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,14 @@ GAMECONTROLLER_TDM::GAMECONTROLLER_TDM()
|
||||||
is_teamplay = true;
|
is_teamplay = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GAMECONTROLLER_TDM::on_player_death(class PLAYER *victim, class PLAYER *killer, int weapon)
|
int GAMECONTROLLER_TDM::on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon)
|
||||||
{
|
{
|
||||||
GAMECONTROLLER::on_player_death(victim, killer, weapon);
|
GAMECONTROLLER::on_character_death(victim, killer, weapon);
|
||||||
|
|
||||||
if(weapon >= 0)
|
if(weapon >= 0)
|
||||||
{
|
{
|
||||||
// do team scoring
|
// do team scoring
|
||||||
if(killer == victim)
|
if(killer == victim->player)
|
||||||
teamscore[killer->team&1]--; // klant arschel
|
teamscore[killer->team&1]--; // klant arschel
|
||||||
else
|
else
|
||||||
teamscore[killer->team&1]++; // good shit
|
teamscore[killer->team&1]++; // good shit
|
||||||
|
|
|
@ -5,6 +5,6 @@ class GAMECONTROLLER_TDM : public GAMECONTROLLER
|
||||||
public:
|
public:
|
||||||
GAMECONTROLLER_TDM();
|
GAMECONTROLLER_TDM();
|
||||||
|
|
||||||
int on_player_death(class PLAYER *victim, class PLAYER *killer, int weapon);
|
int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,22 +13,22 @@ enum {
|
||||||
EXPIRE_TIME = 90
|
EXPIRE_TIME = 90
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct check_server
|
static struct CHECK_SERVER
|
||||||
{
|
{
|
||||||
NETADDR4 address;
|
NETADDR address;
|
||||||
NETADDR4 alt_address;
|
NETADDR alt_address;
|
||||||
int try_count;
|
int try_count;
|
||||||
int64 try_time;
|
int64 try_time;
|
||||||
} check_servers[MAX_SERVERS];
|
} check_servers[MAX_SERVERS];
|
||||||
static int num_checkservers = 0;
|
static int num_checkservers = 0;
|
||||||
|
|
||||||
static struct packet_data
|
static struct PACKET_DATA
|
||||||
{
|
{
|
||||||
unsigned char header[sizeof(SERVERBROWSE_LIST)];
|
unsigned char header[sizeof(SERVERBROWSE_LIST)];
|
||||||
NETADDR4 servers[MAX_SERVERS];
|
NETADDR servers[MAX_SERVERS];
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
static struct count_packet_data
|
static struct COUNT_PACKET_DATA
|
||||||
{
|
{
|
||||||
unsigned char header[sizeof(SERVERBROWSE_COUNT)];
|
unsigned char header[sizeof(SERVERBROWSE_COUNT)];
|
||||||
unsigned char high;
|
unsigned char high;
|
||||||
|
@ -41,7 +41,7 @@ static int num_servers = 0;
|
||||||
static net_client net_checker; // NAT/FW checker
|
static net_client net_checker; // NAT/FW checker
|
||||||
static net_client net_op; // main
|
static net_client net_op; // main
|
||||||
|
|
||||||
void send_ok(NETADDR4 *addr)
|
void send_ok(NETADDR *addr)
|
||||||
{
|
{
|
||||||
NETCHUNK p;
|
NETCHUNK p;
|
||||||
p.client_id = -1;
|
p.client_id = -1;
|
||||||
|
@ -55,7 +55,7 @@ void send_ok(NETADDR4 *addr)
|
||||||
net_op.send(&p);
|
net_op.send(&p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_error(NETADDR4 *addr)
|
void send_error(NETADDR *addr)
|
||||||
{
|
{
|
||||||
NETCHUNK p;
|
NETCHUNK p;
|
||||||
p.client_id = -1;
|
p.client_id = -1;
|
||||||
|
@ -66,7 +66,7 @@ void send_error(NETADDR4 *addr)
|
||||||
net_op.send(&p);
|
net_op.send(&p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_check(NETADDR4 *addr)
|
void send_check(NETADDR *addr)
|
||||||
{
|
{
|
||||||
NETCHUNK p;
|
NETCHUNK p;
|
||||||
p.client_id = -1;
|
p.client_id = -1;
|
||||||
|
@ -77,7 +77,7 @@ void send_check(NETADDR4 *addr)
|
||||||
net_checker.send(&p);
|
net_checker.send(&p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_checkserver(NETADDR4 *info, NETADDR4 *alt)
|
void add_checkserver(NETADDR *info, NETADDR *alt)
|
||||||
{
|
{
|
||||||
// add server
|
// add server
|
||||||
if(num_checkservers == MAX_SERVERS)
|
if(num_checkservers == MAX_SERVERS)
|
||||||
|
@ -96,13 +96,13 @@ void add_checkserver(NETADDR4 *info, NETADDR4 *alt)
|
||||||
num_checkservers++;
|
num_checkservers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_server(NETADDR4 *info)
|
void add_server(NETADDR *info)
|
||||||
{
|
{
|
||||||
// see if server already exists in list
|
// see if server already exists in list
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < num_servers; i++)
|
for(i = 0; i < num_servers; i++)
|
||||||
{
|
{
|
||||||
if(net_addr4_cmp(&data.servers[i], info) == 0)
|
if(net_addr_comp(&data.servers[i], info) == 0)
|
||||||
{
|
{
|
||||||
dbg_msg("mastersrv", "updated: %d.%d.%d.%d:%d",
|
dbg_msg("mastersrv", "updated: %d.%d.%d.%d:%d",
|
||||||
info->ip[0], info->ip[1], info->ip[2], info->ip[3], info->port);
|
info->ip[0], info->ip[1], info->ip[2], info->ip[3], info->port);
|
||||||
|
@ -183,7 +183,7 @@ void purge_servers()
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
NETADDR4 bindaddr;
|
NETADDR bindaddr;
|
||||||
mem_zero(&bindaddr, sizeof(bindaddr));
|
mem_zero(&bindaddr, sizeof(bindaddr));
|
||||||
bindaddr.port = MASTERSERVER_PORT;
|
bindaddr.port = MASTERSERVER_PORT;
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ int main(int argc, char **argv)
|
||||||
if(packet.data_size == sizeof(SERVERBROWSE_HEARTBEAT)+2 &&
|
if(packet.data_size == sizeof(SERVERBROWSE_HEARTBEAT)+2 &&
|
||||||
memcmp(packet.data, SERVERBROWSE_HEARTBEAT, sizeof(SERVERBROWSE_HEARTBEAT)) == 0)
|
memcmp(packet.data, SERVERBROWSE_HEARTBEAT, sizeof(SERVERBROWSE_HEARTBEAT)) == 0)
|
||||||
{
|
{
|
||||||
NETADDR4 alt;
|
NETADDR alt;
|
||||||
unsigned char *d = (unsigned char *)packet.data;
|
unsigned char *d = (unsigned char *)packet.data;
|
||||||
alt = packet.address;
|
alt = packet.address;
|
||||||
alt.port =
|
alt.port =
|
||||||
|
@ -244,7 +244,7 @@ int main(int argc, char **argv)
|
||||||
p.client_id = -1;
|
p.client_id = -1;
|
||||||
p.address = packet.address;
|
p.address = packet.address;
|
||||||
p.flags = NETSENDFLAG_CONNLESS;
|
p.flags = NETSENDFLAG_CONNLESS;
|
||||||
p.data_size = num_servers*sizeof(NETADDR4)+sizeof(SERVERBROWSE_LIST);
|
p.data_size = num_servers*sizeof(NETADDR)+sizeof(SERVERBROWSE_LIST);
|
||||||
p.data = &data;
|
p.data = &data;
|
||||||
net_op.send(&p);
|
net_op.send(&p);
|
||||||
}
|
}
|
||||||
|
@ -259,8 +259,8 @@ int main(int argc, char **argv)
|
||||||
// remove it from checking
|
// remove it from checking
|
||||||
for(int i = 0; i < num_checkservers; i++)
|
for(int i = 0; i < num_checkservers; i++)
|
||||||
{
|
{
|
||||||
if(net_addr4_cmp(&check_servers[i].address, &packet.address) == 0 ||
|
if(net_addr_comp(&check_servers[i].address, &packet.address) == 0 ||
|
||||||
net_addr4_cmp(&check_servers[i].alt_address, &packet.address) == 0)
|
net_addr_comp(&check_servers[i].alt_address, &packet.address) == 0)
|
||||||
{
|
{
|
||||||
num_checkservers--;
|
num_checkservers--;
|
||||||
check_servers[i] = check_servers[num_checkservers];
|
check_servers[i] = check_servers[num_checkservers];
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct packet
|
||||||
packet *prev;
|
packet *prev;
|
||||||
packet *next;
|
packet *next;
|
||||||
|
|
||||||
NETADDR4 send_to;
|
NETADDR send_to;
|
||||||
int64 timestamp;
|
int64 timestamp;
|
||||||
int id;
|
int id;
|
||||||
int data_size;
|
int data_size;
|
||||||
|
@ -20,10 +20,10 @@ static packet *last = (packet *)0;
|
||||||
static int current_latency = 0;
|
static int current_latency = 0;
|
||||||
static int debug = 0;
|
static int debug = 0;
|
||||||
|
|
||||||
int run(int port, NETADDR4 dest)
|
int run(int port, NETADDR dest)
|
||||||
{
|
{
|
||||||
NETADDR4 src = {{0,0,0,0},port};
|
NETADDR src = {NETTYPE_IPV4, {0,0,0,0},port};
|
||||||
NETSOCKET socket = net_udp4_create(src);
|
NETSOCKET socket = net_udp_create(src);
|
||||||
|
|
||||||
char buffer[1024*2];
|
char buffer[1024*2];
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
@ -35,8 +35,8 @@ int run(int port, NETADDR4 dest)
|
||||||
{
|
{
|
||||||
// fetch data
|
// fetch data
|
||||||
int data_trash = 0;
|
int data_trash = 0;
|
||||||
NETADDR4 from;
|
NETADDR from;
|
||||||
int bytes = net_udp4_recv(socket, &from, buffer, 1024*2);
|
int bytes = net_udp_recv(socket, &from, buffer, 1024*2);
|
||||||
if(bytes <= 0)
|
if(bytes <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ int run(int port, NETADDR4 dest)
|
||||||
// create new packet
|
// create new packet
|
||||||
packet *p = (packet *)mem_alloc(sizeof(packet)+bytes, 1);
|
packet *p = (packet *)mem_alloc(sizeof(packet)+bytes, 1);
|
||||||
|
|
||||||
if(net_addr4_cmp(&from, &dest) == 0)
|
if(net_addr_comp(&from, &dest) == 0)
|
||||||
{
|
{
|
||||||
p->send_to = src; // from the server
|
p->send_to = src; // from the server
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ int run(int port, NETADDR4 dest)
|
||||||
|
|
||||||
// send and remove packet
|
// send and remove packet
|
||||||
//if((rand()%20) != 0) // heavy packetloss
|
//if((rand()%20) != 0) // heavy packetloss
|
||||||
net_udp4_send(socket, &p->send_to, p->data, p->data_size);
|
net_udp_send(socket, &p->send_to, p->data, p->data_size);
|
||||||
|
|
||||||
// update lag
|
// update lag
|
||||||
double flux = rand()/(double)RAND_MAX;
|
double flux = rand()/(double)RAND_MAX;
|
||||||
|
@ -136,7 +136,7 @@ int run(int port, NETADDR4 dest)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
NETADDR4 a = {{127,0,0,1},8303};
|
NETADDR a = {NETTYPE_IPV4, {127,0,0,1},8303};
|
||||||
run(8302, a);
|
run(8302, a);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ int flags = 0;
|
||||||
const char *version = "0.3.0 2d82e361de24cb25";
|
const char *version = "0.3.0 2d82e361de24cb25";
|
||||||
const char *map = "somemap";
|
const char *map = "somemap";
|
||||||
const char *server_name = "unnamed server";
|
const char *server_name = "unnamed server";
|
||||||
NETADDR4 master_servers[16] = {{{0},0}};
|
NETADDR master_servers[16] = {{0,{0},0}};
|
||||||
int num_masters = 0;
|
int num_masters = 0;
|
||||||
|
|
||||||
const char *player_names[16] = {0};
|
const char *player_names[16] = {0};
|
||||||
|
@ -109,7 +109,7 @@ static void build_infomessage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_serverinfo(NETADDR4 *addr)
|
static void send_serverinfo(NETADDR *addr)
|
||||||
{
|
{
|
||||||
NETCHUNK p;
|
NETCHUNK p;
|
||||||
p.client_id = -1;
|
p.client_id = -1;
|
||||||
|
@ -120,7 +120,7 @@ static void send_serverinfo(NETADDR4 *addr)
|
||||||
netserver_send(net, &p);
|
netserver_send(net, &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_fwcheckresponse(NETADDR4 *addr)
|
static void send_fwcheckresponse(NETADDR *addr)
|
||||||
{
|
{
|
||||||
NETCHUNK p;
|
NETCHUNK p;
|
||||||
p.client_id = -1;
|
p.client_id = -1;
|
||||||
|
@ -134,7 +134,7 @@ static void send_fwcheckresponse(NETADDR4 *addr)
|
||||||
static int run()
|
static int run()
|
||||||
{
|
{
|
||||||
int64 next_heartbeat = 0;
|
int64 next_heartbeat = 0;
|
||||||
NETADDR4 bindaddr = {{0},0};
|
NETADDR bindaddr = {NETTYPE_IPV4, {0},0};
|
||||||
net = netserver_open(bindaddr, 0, 0);
|
net = netserver_open(bindaddr, 0, 0);
|
||||||
if(!net)
|
if(!net)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -3,15 +3,15 @@
|
||||||
|
|
||||||
enum { NUM_SOCKETS = 64 };
|
enum { NUM_SOCKETS = 64 };
|
||||||
|
|
||||||
int run(NETADDR4 dest)
|
int run(NETADDR dest)
|
||||||
{
|
{
|
||||||
NETSOCKET sockets[NUM_SOCKETS];
|
NETSOCKET sockets[NUM_SOCKETS];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < NUM_SOCKETS; i++)
|
for(i = 0; i < NUM_SOCKETS; i++)
|
||||||
{
|
{
|
||||||
NETADDR4 bindaddr = {{0,0,0,0}, 0};
|
NETADDR bindaddr = {NETTYPE_IPV4, {0}, 0};
|
||||||
sockets[i] = net_udp4_create(bindaddr);
|
sockets[i] = net_udp_create(bindaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -24,13 +24,13 @@ int run(NETADDR4 dest)
|
||||||
size %= 256;
|
size %= 256;
|
||||||
socket_to_use %= NUM_SOCKETS;
|
socket_to_use %= NUM_SOCKETS;
|
||||||
io_read(io_stdin(), data, size);
|
io_read(io_stdin(), data, size);
|
||||||
net_udp4_send(sockets[socket_to_use], &dest, data, size);
|
net_udp_send(sockets[socket_to_use], &dest, data, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
NETADDR4 dest = {{127,0,0,1},8303};
|
NETADDR dest = {NETTYPE_IPV4, {127,0,0,1},8303};
|
||||||
run(dest);
|
run(dest);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue