diff --git a/src/crapnet/crapnet.cpp b/src/crapnet/crapnet.cpp index b441a3504..f87803b5f 100644 --- a/src/crapnet/crapnet.cpp +++ b/src/crapnet/crapnet.cpp @@ -96,12 +96,12 @@ int run(int port, netaddr4 dest) } // send and remove packet - if((rand()%10) != 0) // heavy packetloss - socket.send(&p->send_to, p->data, p->data_size); + //if((rand()%10) != 0) // heavy packetloss + socket.send(&p->send_to, p->data, p->data_size); // update lag double flux = rand()/(double)RAND_MAX; - int ms_spike = 250; + int ms_spike = 0; int ms_flux = 100; int ms_ping = 50; current_latency = ((time_freq()*ms_ping)/1000) + (int64)(((time_freq()*ms_flux)/1000)*flux); // 50ms diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 8d7fb1e28..7fb9413e7 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -167,6 +167,7 @@ static struct netaddr4 addresses[MAX_SERVERS]; int num; } servers; +static int serverlist_lan = 1; static netaddr4 master_server; @@ -176,19 +177,50 @@ int client_serverbrowse_getlist(server_info **serverlist) return servers.num; } +void client_serverbrowse_init() +{ + servers.num = 0; +} + +void client_serverbrowse_use_lan(int use) +{ + serverlist_lan = use; +} + void client_serverbrowse_refresh() { - dbg_msg("client", "requesting server list"); - NETPACKET packet; - packet.client_id = -1; - packet.address = master_server; - packet.flags = PACKETFLAG_CONNLESS; - packet.data_size = sizeof(SERVERBROWSE_GETLIST); - packet.data = SERVERBROWSE_GETLIST; - net.send(&packet); - - // reset the list - servers.num = 0; + if(serverlist_lan) + { + dbg_msg("client", "broadcasting for servers"); + NETPACKET packet; + packet.client_id = -1; + packet.address.ip[0] = 0; + packet.address.ip[1] = 0; + packet.address.ip[2] = 0; + packet.address.ip[3] = 0; + packet.address.port = 8303; + packet.flags = PACKETFLAG_CONNLESS; + packet.data_size = sizeof(SERVERBROWSE_GETINFO); + packet.data = SERVERBROWSE_GETINFO; + net.send(&packet); + + // reset the list + servers.num = 0; + } + else + { + dbg_msg("client", "requesting server list"); + NETPACKET packet; + packet.client_id = -1; + packet.address = master_server; + packet.flags = PACKETFLAG_CONNLESS; + packet.data_size = sizeof(SERVERBROWSE_GETLIST); + packet.data = SERVERBROWSE_GETLIST; + net.send(&packet); + + // reset the list + servers.num = 0; + } } enum @@ -214,6 +246,7 @@ static void set_state(int s) void client_connect(const char *server_address_str) { + dbg_msg("client", "connecting to '%s'", server_address_str); char buf[512]; strncpy(buf, server_address_str, 512); @@ -394,6 +427,8 @@ public: info_request_begin = 0; info_request_end = 0; + client_serverbrowse_init(); + // init graphics and sound if(!gfx_init()) return; @@ -589,17 +624,40 @@ public: data_unpacker unpacker; unpacker.reset((unsigned char*)packet->data+sizeof(SERVERBROWSE_INFO), packet->data_size-sizeof(SERVERBROWSE_INFO)); - for(int i = 0; i < servers.num; i++) + if(serverlist_lan) { - if(net_addr4_cmp(&servers.addresses[i], &packet->address) == 0) + if(servers.num != MAX_SERVERS) { + int i = servers.num; strncpy(servers.infos[i].name, unpacker.get_string(), 128); strncpy(servers.infos[i].map, unpacker.get_string(), 128); servers.infos[i].max_players = unpacker.get_int(); servers.infos[i].num_players = unpacker.get_int(); - servers.infos[i].latency = ((time_get() - servers.request_times[i])*1000)/time_freq(); + servers.infos[i].latency = 0; + + sprintf(servers.infos[i].address, "%d.%d.%d.%d:%d", + packet->address.ip[0], packet->address.ip[1], packet->address.ip[2], + packet->address.ip[3], packet->address.port); + dbg_msg("client", "got server info"); - break; + servers.num++; + + } + } + else + { + for(int i = 0; i < servers.num; i++) + { + if(net_addr4_cmp(&servers.addresses[i], &packet->address) == 0) + { + strncpy(servers.infos[i].name, unpacker.get_string(), 128); + strncpy(servers.infos[i].map, unpacker.get_string(), 128); + servers.infos[i].max_players = unpacker.get_int(); + servers.infos[i].num_players = unpacker.get_int(); + servers.infos[i].latency = ((time_get() - servers.request_times[i])*1000)/time_freq(); + dbg_msg("client", "got server info"); + break; + } } } } @@ -688,7 +746,7 @@ public: if(delta_tick >= 0) { void *delta_data; - deltashot_size = snapshots_new.get(delta_tick, &delta_data); + deltashot_size = snapshots_new.get(delta_tick, 0, &delta_data); if(deltashot_size >= 0) { deltashot = (snapshot *)delta_data; @@ -708,7 +766,7 @@ public: snapshots_new.purge_until(game_tick-50); // TODO: change this to server tickrate // add new - snapshots_new.add(game_tick, snapsize, snapshots[SNAP_CURRENT]); + snapshots_new.add(game_tick, time_get(), snapsize, snapshots[SNAP_CURRENT]); // apply snapshot, cycle pointers recived_snapshots++; diff --git a/src/engine/client/gfx.cpp b/src/engine/client/gfx.cpp index 8248d3a54..e7ec3b37f 100644 --- a/src/engine/client/gfx.cpp +++ b/src/engine/client/gfx.cpp @@ -185,6 +185,8 @@ void gfx_blend_additive() glBlendFunc(GL_SRC_ALPHA, GL_ONE); } +int DEBUGTEST_MAPIMAGE = 0; + int gfx_load_texture_raw(int w, int h, int format, const void *data) { // grab texture @@ -195,14 +197,29 @@ int gfx_load_texture_raw(int w, int h, int format, const void *data) // set data and return // TODO: should be RGBA, not BGRA dbg_msg("gfx", "%d = %dx%d", tex, w, h); - if(format == IMG_RGB) - textures[tex].tex.data2d(w, h, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data); - else if(format == IMG_RGBA) - textures[tex].tex.data2d(w, h, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, data); - else if(format == IMG_BGR) - textures[tex].tex.data2d(w, h, GL_RGB, GL_BGR, GL_UNSIGNED_BYTE, data); - else if(format == IMG_BGRA) - textures[tex].tex.data2d(w, h, GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE, data); + if(DEBUGTEST_MAPIMAGE) + { + if(format == IMG_RGB) + textures[tex].tex.data2d_nomip(w, h, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data); + else if(format == IMG_RGBA) + textures[tex].tex.data2d_nomip(w, h, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, data); + else if(format == IMG_BGR) + textures[tex].tex.data2d_nomip(w, h, GL_RGB, GL_BGR, GL_UNSIGNED_BYTE, data); + else if(format == IMG_BGRA) + textures[tex].tex.data2d_nomip(w, h, GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE, data); + } + else + { + if(format == IMG_RGB) + textures[tex].tex.data2d(w, h, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data); + else if(format == IMG_RGBA) + textures[tex].tex.data2d(w, h, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, data); + else if(format == IMG_BGR) + textures[tex].tex.data2d(w, h, GL_RGB, GL_BGR, GL_UNSIGNED_BYTE, data); + else if(format == IMG_BGRA) + textures[tex].tex.data2d(w, h, GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE, data); + } + return tex; } diff --git a/src/engine/interface.h b/src/engine/interface.h index 4cadb9969..33bfc95e6 100644 --- a/src/engine/interface.h +++ b/src/engine/interface.h @@ -766,5 +766,6 @@ void client_connect(const char *address); void client_serverbrowse_refresh(); int client_serverbrowse_getlist(server_info **servers); +void client_serverbrowse_use_lan(int use); #endif diff --git a/src/engine/packet.h b/src/engine/packet.h index 6c92bf312..485dee426 100644 --- a/src/engine/packet.h +++ b/src/engine/packet.h @@ -43,6 +43,7 @@ class snapshot_storage { struct holder { + int64 tagtime; int tick; int data_size; int *data() { return (int *)(this+1); } @@ -71,15 +72,16 @@ public: buffer.reset(); } - void add(int tick, int data_size, void *data) + void add(int tick, int64 tagtime, int data_size, void *data) { holder *h = (holder *)buffer.alloc(sizeof(holder)+data_size); h->tick = tick; h->data_size = data_size; + h->tagtime = tagtime; mem_copy(h->data(), data, data_size); } - int get(int tick, void **data) + int get(int tick, int64 *tagtime, void **data) { ring_buffer::item *i = buffer.first(); while(i) @@ -87,7 +89,10 @@ public: holder *h = (holder *)i->data(); if(h->tick == tick) { - *data = h->data(); + if(data) + *data = h->data(); + if(tagtime) + *tagtime = h->tagtime; return h->data_size; } diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 32be58ac8..71fb9b942 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -40,8 +40,15 @@ public: STATE_INGAME = 2, }; + struct stored_snapshot + { + int64 send_time; + snapshot snap; + }; + // connection state info int state; + int latency; int last_acked_snapshot; snapshot_storage snapshots; @@ -91,7 +98,7 @@ int server_getclientinfo(int client_id, client_info *info) if(clients[client_id].is_ingame()) { info->name = clients[client_id].name; - info->latency = 0; + info->latency = clients[client_id].latency; return 1; } return 0; @@ -280,7 +287,7 @@ public: clients[i].snapshots.purge_until(current_tick-SERVER_TICK_SPEED); // save it the snapshot - clients[i].snapshots.add(current_tick, snapshot_size, data); + clients[i].snapshots.add(current_tick, time_get(), snapshot_size, data); // find snapshot that we can preform delta against static snapshot emptysnap; @@ -292,7 +299,7 @@ public: int delta_tick = -1; { void *delta_data; - deltashot_size = clients[i].snapshots.get(clients[i].last_acked_snapshot, (void **)&delta_data); + deltashot_size = clients[i].snapshots.get(clients[i].last_acked_snapshot, 0, (void **)&delta_data); if(deltashot_size >= 0) { delta_tick = clients[i].last_acked_snapshot; @@ -418,6 +425,9 @@ public: else if(msg == NETMSG_SNAPACK) { clients[cid].last_acked_snapshot = msg_unpack_int(); + int64 tagtime; + if(clients[cid].snapshots.get(clients[cid].last_acked_snapshot, &tagtime, 0) >= 0) + clients[cid].latency = (int)(((time_get()-tagtime)*1000)/time_freq()); } else { @@ -442,7 +452,6 @@ public: void send_serverinfo(NETADDR4 *addr) { - dbg_msg("server", "sending heartbeat"); NETPACKET packet; data_packer packer; @@ -488,7 +497,6 @@ public: if(packet.data_size == sizeof(SERVERBROWSE_GETINFO) && memcmp(packet.data, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)) == 0) { - dbg_msg("server", "info requested"); send_serverinfo(&packet.address); } else if(packet.data_size == sizeof(SERVERBROWSE_FWCHECK) && @@ -504,7 +512,9 @@ public: else if(packet.data_size == sizeof(SERVERBROWSE_FWERROR) && memcmp(packet.data, SERVERBROWSE_FWERROR, sizeof(SERVERBROWSE_FWERROR)) == 0) { - dbg_msg("server", "ERROR: clients can not connect due to FIREWALL/NAT"); + dbg_msg("server", "ERROR: the master server reports that clients can not to the"); + dbg_msg("server", "ERROR: server due to connect due to firewall/nat. configure"); + dbg_msg("server", "ERROR: your firewall/nat to let trough udp on port %d.", 8303); } } else @@ -550,8 +560,6 @@ int main(int argc, char **argv) { dbg_msg("server", "starting..."); - dbg_msg("server", "%d %d", sizeof(snapshot), sizeof(snapshot::item)); - config_reset(); config_load("server.cfg"); diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp index c101b2917..9ed43d1a4 100644 --- a/src/game/client/game_client.cpp +++ b/src/game/client/game_client.cpp @@ -1108,6 +1108,8 @@ void modc_render() // pseudo format float zoom = 3.0f; + if(inp_key_pressed('I')) + zoom = 1.0f; float width = 400*zoom; float height = 300*zoom; @@ -1343,7 +1345,8 @@ void modc_render() { // Normal deathmatch - float x = 50.0f; + float w = 550.0f; + float x = width-w-50.0f; float y = 150.0f; gfx_blend_normal(); @@ -1351,7 +1354,7 @@ void modc_render() gfx_texture_set(-1); gfx_quads_begin(); gfx_quads_setcolor(0,0,0,0.5f); - gfx_quads_drawTL(x-10.f, y-10.f, 400.0f, 600.0f); + gfx_quads_drawTL(x-10.f, y-10.f, w, 600.0f); gfx_quads_end(); gfx_pretty_text(x, y, 64, "Score Board"); @@ -1386,6 +1389,9 @@ void modc_render() sprintf(buf, "%4d", player->score); gfx_pretty_text(x+60-gfx_pretty_text_width(48,buf), y, 48, buf); gfx_pretty_text(x+128, y, 48, client_datas[player->clientid].name); + sprintf(buf, "%4d", player->latency); + float tw = gfx_pretty_text_width(48.0f, buf); + gfx_pretty_text(x+w-tw-20, y, 48, buf); render_tee(&idlestate, player->clientid, vec2(1,0), vec2(x+90, y+24)); y += 58.0f; diff --git a/src/game/client/mapres_image.cpp b/src/game/client/mapres_image.cpp index 8d286b850..eca7882fd 100644 --- a/src/game/client/mapres_image.cpp +++ b/src/game/client/mapres_image.cpp @@ -6,6 +6,8 @@ static int map_textures[64] = {0}; static int count = 0; +extern int DEBUGTEST_MAPIMAGE; + int img_init() { int start, count; diff --git a/src/game/client/mapres_tilemap.cpp b/src/game/client/mapres_tilemap.cpp index 52f2a9b1c..6476f26d5 100644 --- a/src/game/client/mapres_tilemap.cpp +++ b/src/game/client/mapres_tilemap.cpp @@ -3,6 +3,8 @@ #include "mapres_image.h" #include "../mapres.h" +#include + int tilemap_init() { return 0; @@ -17,6 +19,12 @@ void tilemap_render(float scale, int fg) int start, num; map_get_type(MAPRES_TILEMAP, &start, &num); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + + // render tilemaps int passed_main = 0; for(int t = 0; t < num; t++) @@ -34,6 +42,8 @@ void tilemap_render(float scale, int fg) int c = 0; float frac = (1.0f/1024.0f);//2.0f; //2.0f; + float texsize = 1024.0f; + float nudge = 0.5f/texsize; const float s = 1.0f; for(int y = 0; y < tmap->height; y++) for(int x = 0; x < tmap->width; x++, c++) @@ -41,11 +51,25 @@ void tilemap_render(float scale, int fg) unsigned char d = data[c*2]; if(d) { + /* gfx_quads_setsubset( (d%16)/16.0f*s+frac, (d/16)/16.0f*s+frac, ((d%16)/16.0f+1.0f/16.0f)*s-frac, ((d/16)/16.0f+1.0f/16.0f)*s-frac); + */ + int tx = d%16; + int ty = d/16; + int px0 = tx*(1024/16); + int py0 = ty*(1024/16); + int px1 = (tx+1)*(1024/16)-1; + int py1 = (ty+1)*(1024/16)-1; + gfx_quads_setsubset( + nudge + px0/texsize+frac, + nudge + py0/texsize+frac, + nudge + px1/texsize-frac, + nudge + py1/texsize-frac); + gfx_quads_drawTL(x*scale, y*scale, scale, scale); } } @@ -53,4 +77,8 @@ void tilemap_render(float scale, int fg) gfx_quads_end(); } } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } diff --git a/src/game/game.h b/src/game/game.h index 00df52bcf..c9010aa0f 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -147,6 +147,7 @@ struct obj_player int attacktick; // num attack ticks left of current attack int score; + int latency; int emote; int hook_active; diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp index ecb577167..af705e196 100644 --- a/src/game/server/game_server.cpp +++ b/src/game/server/game_server.cpp @@ -343,7 +343,7 @@ game_world world; gameobject::gameobject() : entity(OBJTYPE_GAME) { - gametype = GAMETYPE_TDM; + gametype = GAMETYPE_DM; game_over_tick = -1; sudden_death = 0; round_start_tick = server_tick(); @@ -1032,6 +1032,9 @@ void player::tick() if(hook_state == HOOK_GRABBED) { + if(hooked_player) + hook_pos = hooked_player->pos; + /*if(hooked_player) hook_pos = hooked_player->pos; @@ -1043,24 +1046,29 @@ void player::tick() vel.x = saturated_add(-hook_drag_speed, hook_drag_speed, vel.x, -accel*dir.x*0.75f); vel.y = saturated_add(-hook_drag_speed, hook_drag_speed, vel.y, -accel*dir.y); }*/ + // Old version feels much better (to me atleast) - vec2 hookvel = normalize(hook_pos-pos)*hook_drag_accel; - // the hook as more power to drag you up then down. - // this makes it easier to get on top of an platform - if(hookvel.y > 0) - hookvel.y *= 0.3f; - - // the hook will boost it's power if the player wants to move - // in that direction. otherwise it will dampen everything abit - if((hookvel.x < 0 && input.left) || (hookvel.x > 0 && input.right)) - hookvel.x *= 0.95f; - else - hookvel.x *= 0.75f; - vec2 new_vel = vel+hookvel; - - // check if we are under the legal limit for the hook - if(length(new_vel) < hook_drag_speed || length(new_vel) < length(vel)) - vel = new_vel; // no problem. apply + if(distance(hook_pos, pos) > 46.0f) + { + vec2 hookvel = normalize(hook_pos-pos)*hook_drag_accel; + // the hook as more power to drag you up then down. + // this makes it easier to get on top of an platform + if(hookvel.y > 0) + hookvel.y *= 0.3f; + + // the hook will boost it's power if the player wants to move + // in that direction. otherwise it will dampen everything abit + if((hookvel.x < 0 && input.left) || (hookvel.x > 0 && input.right)) + hookvel.x *= 0.95f; + else + hookvel.x *= 0.75f; + + vec2 new_vel = vel+hookvel; + + // check if we are under the legal limit for the hook + if(length(new_vel) < hook_drag_speed || length(new_vel) < length(vel)) + vel = new_vel; // no problem. apply + } } // fix influence of other players, collision + hook @@ -1205,6 +1213,12 @@ void player::snap(int snaping_client) player->vy = (int)vel.y; player->emote = EMOTE_NORMAL; + player->latency = 0; + client_info info; + if(server_getclientinfo(client_id, &info)) + player->latency = info.latency; + + player->ammocount = weapons[active_weapon].ammo; player->health = 0; player->armor = 0;