fixed errors in the network code

This commit is contained in:
Magnus Auvinen 2007-07-25 07:24:57 +00:00
parent 52c987bfd7
commit 1aecc644de
4 changed files with 91 additions and 19 deletions

View file

@ -232,6 +232,7 @@ enum
};
static netaddr4 server_address;
static const char *server_spam_address=0;
static int state;
static int get_state() { return state; }
@ -319,6 +320,7 @@ void client::send_input()
void client::disconnect()
{
send_error("disconnected");
net.disconnect("disconnected");
set_state(STATE_OFFLINE);
map_unload();
}
@ -462,6 +464,9 @@ void client::run(const char *direct_connect_server)
// send input
if(get_state() == STATE_ONLINE)
{
if(server_spam_address)
disconnect();
if(input_is_changed || time_get() > last_input+time_freq())
{
send_input();
@ -470,6 +475,9 @@ void client::run(const char *direct_connect_server)
}
}
if(get_state() == STATE_OFFLINE && server_spam_address)
client_connect(server_spam_address);
// update input
inp_update();
@ -500,7 +508,7 @@ void client::run(const char *direct_connect_server)
break;
// be nice
//thread_sleep(1);
thread_sleep(1);
if(reporttime < time_get())
{
@ -844,6 +852,12 @@ int main(int argc, char **argv)
i++;
direct_connect_server = argv[i];
}
else if(argv[i][0] == '-' && argv[i][1] == 's' && argv[i][2] == 0 && argc - i > 1)
{
// -s SERVER:PORT
i++;
server_spam_address = argv[i];
}
else if(argv[i][0] == '-' && argv[i][1] == 'n' && argv[i][2] == 0 && argc - i > 1)
{
// -n NAME
@ -855,6 +869,7 @@ int main(int argc, char **argv)
// -w
config.fullscreen = 0;
}
else if(argv[i][0] == '-' && argv[i][1] == 'e' && argv[i][2] == 0)
{
editor = true;

View file

@ -15,7 +15,7 @@
header v2:
unsigned char flags; 1
unsigned char seq_ack[3]; 4
unsigned char crc[2]; 6
unsigned char token[2]; 6
*/
enum
@ -40,6 +40,8 @@ enum
NETWORK_PACKETFLAG_CONNLESS=0x20,
};
static int current_token = 1;
struct NETPACKETDATA
{
unsigned char ID[2];
@ -48,6 +50,7 @@ struct NETPACKETDATA
unsigned short seq;
unsigned short ack;
unsigned crc;
int token;
unsigned data_size;
int64 first_send_time;
unsigned char *data;
@ -61,8 +64,8 @@ static void send_packet(NETSOCKET socket, NETADDR4 *addr, NETPACKETDATA *packet)
buffer[1] = ((packet->seq>>4)&0xf0) | ((packet->ack>>8)&0x0f);
buffer[2] = packet->seq;
buffer[3] = packet->ack;
buffer[4] = packet->crc>>8;
buffer[5] = packet->crc&0xff;
buffer[4] = packet->token>>8;
buffer[5] = packet->token&0xff;
mem_copy(buffer+NETWORK_HEADER_SIZE, packet->data, packet->data_size);
int send_size = NETWORK_HEADER_SIZE+packet->data_size;
//dbg_msg("network", "sending packet, size=%d (%d + %d)", send_size, NETWORK_HEADER_SIZE, packet->data_size);
@ -75,6 +78,11 @@ struct NETCONNECTION
unsigned ack;
unsigned state;
int token;
int connected;
int disconnected;
ring_buffer buffer;
int64 last_recv_time;
@ -88,7 +96,6 @@ struct NETCONNECTION
struct NETSLOT
{
int online;
NETCONNECTION conn;
};
@ -117,13 +124,20 @@ static void conn_reset(NETCONNECTION *conn)
{
conn->seq = 0;
conn->ack = 0;
//dbg_msg("connection", "state = %d->%d", conn->state, NETWORK_CONNSTATE_OFFLINE);
if(conn->state == NETWORK_CONNSTATE_ONLINE)
conn->disconnected++;
conn->state = NETWORK_CONNSTATE_OFFLINE;
conn->error_string = 0;
conn->last_send_time = 0;
conn->last_recv_time = 0;
conn->token = -1;
conn->buffer.reset();
}
static const char *conn_error(NETCONNECTION *conn)
{
return conn->error_string;
@ -139,6 +153,8 @@ static void conn_init(NETCONNECTION *conn, NETSOCKET socket)
conn_reset(conn);
conn_reset_stats(conn);
conn->socket = socket;
conn->connected = 0;
conn->disconnected = 0;
}
static void conn_ack(NETCONNECTION *conn, int ack)
@ -191,6 +207,7 @@ static void conn_send(NETCONNECTION *conn, int flags, int data_size, const void
p.seq = conn->seq;
p.ack = conn->ack;
p.crc = 0;
p.token = conn->token;
p.data_size = data_size;
p.data = (unsigned char *)data;
p.first_send_time = time_get();
@ -216,30 +233,54 @@ static int conn_connect(NETCONNECTION *conn, NETADDR4 *addr)
// init connection
conn_reset(conn);
conn->peeraddr = *addr;
conn->token = current_token++;
//dbg_msg("connection", "state = %d->%d", conn->state, NETWORK_CONNSTATE_CONNECT);
conn->state = NETWORK_CONNSTATE_CONNECT;
conn_send(conn, NETWORK_PACKETFLAG_CONNECT, 0, 0);
return 0;
}
static void conn_disconnect(NETCONNECTION *conn)
{
conn_send(conn, NETWORK_PACKETFLAG_CLOSE, 0, 0);
conn_reset(conn);
}
static int conn_feed(NETCONNECTION *conn, NETPACKETDATA *p, NETADDR4 *addr)
{
conn->last_recv_time = time_get();
conn->stats.recv_packets++;
conn->stats.recv_bytes += p->data_size + NETWORK_HEADER_SIZE;
if(p->flags&NETWORK_PACKETFLAG_CLOSE)
{
conn_reset(conn);
return 0;
}
if(conn->state == NETWORK_CONNSTATE_OFFLINE)
{
if(p->flags == NETWORK_PACKETFLAG_CONNECT)
{
// send response and init connection
//dbg_msg("connection", "state = %d->%d", conn->state, NETWORK_CONNSTATE_ONLINE);
conn->state = NETWORK_CONNSTATE_ONLINE;
conn->connected++;
conn->peeraddr = *addr;
conn->token = p->token;
//dbg_msg("connection", "token set to %d", p->token);
conn_send(conn, NETWORK_PACKETFLAG_CONNECT|NETWORK_PACKETFLAG_ACCEPT, 0, 0);
dbg_msg("connection", "got connection, sending connect+accept");
}
}
else if(net_addr4_cmp(&conn->peeraddr, addr) == 0)
{
if(p->token != conn->token)
{
//dbg_msg("connection", "wrong token %d, %d", p->token, conn->token);
return 0;
}
if(conn->state == NETWORK_CONNSTATE_ONLINE)
{
// remove packages that are acked
@ -276,7 +317,9 @@ static int conn_feed(NETCONNECTION *conn, NETPACKETDATA *p, NETADDR4 *addr)
if(p->flags == (NETWORK_PACKETFLAG_CONNECT|NETWORK_PACKETFLAG_ACCEPT))
{
conn_send(conn, NETWORK_PACKETFLAG_ACCEPT, 0, 0);
//dbg_msg("connection", "state = %d->%d", conn->state, NETWORK_CONNSTATE_ONLINE);
conn->state = NETWORK_CONNSTATE_ONLINE;
conn->connected++;
dbg_msg("connection", "got connect+accept, sending accept. connection online");
}
}
@ -292,6 +335,7 @@ static int conn_feed(NETCONNECTION *conn, NETPACKETDATA *p, NETADDR4 *addr)
}*/
else
{
conn_reset(conn);
// strange packet, wrong state
}
}
@ -315,6 +359,7 @@ static void conn_update(NETCONNECTION *conn)
conn->state != NETWORK_CONNSTATE_CONNECT &&
(time_get()-conn->last_recv_time) > time_freq()*3)
{
//dbg_msg("connection", "state = %d->%d", conn->state, NETWORK_CONNSTATE_ERROR);
conn->state = NETWORK_CONNSTATE_ERROR;
conn->error_string = "timeout";
}
@ -322,6 +367,7 @@ static void conn_update(NETCONNECTION *conn)
// check for large buffer errors
if(conn->buffer.size() > 1024*64)
{
//dbg_msg("connection", "state = %d->%d", conn->state, NETWORK_CONNSTATE_ERROR);
conn->state = NETWORK_CONNSTATE_ERROR;
conn->error_string = "too weak connection (out of buffer)";
}
@ -331,6 +377,7 @@ static void conn_update(NETCONNECTION *conn)
NETPACKETDATA *resend = (NETPACKETDATA *)conn->buffer.first()->data();
if(time_get()-resend->first_send_time > time_freq()*3)
{
//dbg_msg("connection", "state = %d->%d", conn->state, NETWORK_CONNSTATE_ERROR);
conn->state = NETWORK_CONNSTATE_ERROR;
conn->error_string = "too weak connection (not acked for 3 seconds)";
}
@ -368,7 +415,8 @@ static int check_packet(unsigned char *buffer, int size, NETPACKETDATA *packet)
packet->flags = buffer[0];
packet->seq = ((buffer[1]&0xf0)<<4)|buffer[2];
packet->ack = ((buffer[1]&0x0f)<<8)|buffer[3];
packet->crc = (buffer[8]<<24)|(buffer[9]<<16)|(buffer[10]<<8)|buffer[11];
packet->crc = 0;
packet->token = (buffer[4]<<8)|buffer[5];
packet->data_size = size - NETWORK_HEADER_SIZE;
packet->data = buffer+NETWORK_HEADER_SIZE;
@ -407,9 +455,9 @@ int net_server_newclient(NETSERVER *s)
{
for(int i = 0; i < NETWORK_MAX_CLIENTS; i++)
{
if(!s->slots[i].online && s->slots[i].conn.state == NETWORK_CONNSTATE_ONLINE)
if(s->slots[i].conn.connected)
{
s->slots[i].online = 1;
s->slots[i].conn.connected = 0;
return i;
}
}
@ -421,9 +469,9 @@ int net_server_delclient(NETSERVER *s)
{
for(int i = 0; i < NETWORK_MAX_CLIENTS; i++)
{
if(s->slots[i].online && s->slots[i].conn.state != NETWORK_CONNSTATE_ONLINE)
if(s->slots[i].conn.disconnected)
{
s->slots[i].online = 0;
s->slots[i].conn.disconnected = 0;
return i;
}
}
@ -489,6 +537,7 @@ int net_server_recv(NETSERVER *s, NETPACKET *packet)
net_addr4_cmp(&s->slots[i].conn.peeraddr, &addr) == 0)
{
found = 1; // silent ignore.. we got this client already
//dbg_msg("netserver", "ignored connect request %d", i);
break;
}
}
@ -500,6 +549,7 @@ int net_server_recv(NETSERVER *s, NETPACKET *packet)
{
if(s->slots[i].conn.state == NETWORK_CONNSTATE_OFFLINE)
{
//dbg_msg("netserver", "connection started %d", i);
conn_feed(&s->slots[i].conn, &data, &addr);
found = 1;
break;
@ -507,7 +557,7 @@ int net_server_recv(NETSERVER *s, NETPACKET *packet)
}
}
if(!found)
if(found)
{
// TODO: send error
}
@ -619,7 +669,7 @@ int net_client_disconnect(NETCLIENT *c, const char *reason)
{
// TODO: do this more graceful
dbg_msg("net_client", "disconnected. reason=\"%s\"", reason);
conn_reset(&c->conn);
conn_disconnect(&c->conn);
return 0;
}

View file

@ -410,9 +410,12 @@ public:
}
else if(msg == NETMSG_ENTERGAME)
{
dbg_msg("game", "player as entered the game. cid=%x", cid);
clients[cid].state = client::STATE_INGAME;
mods_client_enter(cid);
if(clients[cid].state != client::STATE_INGAME)
{
dbg_msg("game", "player as entered the game. cid=%x", cid);
clients[cid].state = client::STATE_INGAME;
mods_client_enter(cid);
}
}
else if(msg == NETMSG_INPUT)
{
@ -532,8 +535,6 @@ public:
clients[cid].snapshots.purge_all();
mods_client_drop(cid);
dbg_msg("server", "del client %d", cid);
}
// check for new clients
@ -548,8 +549,6 @@ public:
clients[cid].clan[0] = 0;
clients[cid].snapshots.purge_all();
clients[cid].last_acked_snapshot = -1;
dbg_msg("server", "new client %d", cid);
}
}
};

View file

@ -242,6 +242,13 @@ int game_world::find_entities(vec2 pos, float radius, entity **ents, int max, co
void game_world::insert_entity(entity *ent)
{
entity *cur = first_entity;
while(cur)
{
dbg_assert(cur != ent, "err");
cur = cur->next_entity;
}
// insert it
if(first_entity)
first_entity->prev_entity = ent;
@ -1629,6 +1636,7 @@ void mods_client_enter(int client_id)
void mods_client_drop(int client_id)
{
dbg_msg("mods", "client drop %d", client_id);
players[client_id].client_id = -1;
world.remove_entity(&players[client_id]);
}