diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-07-25 07:24:57 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-07-25 07:24:57 +0000 |
| commit | 1aecc644de9e2cb81e3f2fd6c8abc86f37debad7 (patch) | |
| tree | a2a42c9e56b52cd0b9515f89dd6d862f14df24ff /src | |
| parent | 52c987bfd7abcd8acecdc7da580b8e56be0bd625 (diff) | |
| download | zcatch-1aecc644de9e2cb81e3f2fd6c8abc86f37debad7.tar.gz zcatch-1aecc644de9e2cb81e3f2fd6c8abc86f37debad7.zip | |
fixed errors in the network code
Diffstat (limited to 'src')
| -rw-r--r-- | src/engine/client/client.cpp | 17 | ||||
| -rw-r--r-- | src/engine/network.cpp | 72 | ||||
| -rw-r--r-- | src/engine/server/server.cpp | 13 | ||||
| -rw-r--r-- | src/game/server/game_server.cpp | 8 |
4 files changed, 91 insertions, 19 deletions
diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 1d3b7d2b..dd7e895d 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -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; diff --git a/src/engine/network.cpp b/src/engine/network.cpp index c6b8207f..b8cf615d 100644 --- a/src/engine/network.cpp +++ b/src/engine/network.cpp @@ -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; } diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 1af0da3b..d66fa2ee 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -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); } } }; diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp index 9fb50d4b..31052aa5 100644 --- a/src/game/server/game_server.cpp +++ b/src/game/server/game_server.cpp @@ -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]); } |