diff options
Diffstat (limited to 'src/game/client')
| -rw-r--r-- | src/game/client/gc_client.cpp | 183 | ||||
| -rw-r--r-- | src/game/client/gc_client.h | 32 | ||||
| -rw-r--r-- | src/game/client/gc_hooks.cpp | 112 | ||||
| -rw-r--r-- | src/game/client/gc_menu.cpp | 16 | ||||
| -rw-r--r-- | src/game/client/gc_render.cpp | 30 | ||||
| -rw-r--r-- | src/game/client/gc_render.h | 12 | ||||
| -rw-r--r-- | src/game/client/gc_render_obj.cpp | 57 |
7 files changed, 258 insertions, 184 deletions
diff --git a/src/game/client/gc_client.cpp b/src/game/client/gc_client.cpp index 20d1df7c..8446d729 100644 --- a/src/game/client/gc_client.cpp +++ b/src/game/client/gc_client.cpp @@ -27,7 +27,7 @@ extern "C" { struct data_container *data = 0; int64 debug_firedelay = 0; -player_input input_data = {0}; +NETOBJ_PLAYER_INPUT input_data = {0}; int input_target_lock = 0; int chat_mode = CHATMODE_NONE; @@ -40,11 +40,16 @@ tuning_params tuning; vec2 mouse_pos; vec2 local_character_pos; vec2 local_target_pos; -const obj_player_character *local_character = 0; -const obj_player_character *local_prev_character = 0; -const obj_player_info *local_info = 0; -const obj_flag *flags[2] = {0,0}; -const obj_game *gameobj = 0; + +/* +const NETOBJ_PLAYER_CHARACTER *local_character = 0; +const NETOBJ_PLAYER_CHARACTER *local_prev_character = 0; +const NETOBJ_PLAYER_INFO *local_info = 0; +const NETOBJ_FLAG *flags[2] = {0,0}; +const NETOBJ_GAME *gameobj = 0; +*/ + +snapstate netobjects; int picked_up_weapon = -1; @@ -54,7 +59,7 @@ void client_data::update_render_info() render_info = skin_info; // force team colors - if(gameobj && gameobj->gametype != GAMETYPE_DM) + if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM) { const int team_colors[2] = {65387, 10223467}; if(team >= 0 || team <= 1) @@ -232,7 +237,7 @@ void chat_add_line(int client_id, int team, const char *line) if(client_datas[client_id].team == -1) chat_lines[chat_current_line].name_color = -1; - if(gameobj && gameobj->gametype != GAMETYPE_DM) + if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM) { if(client_datas[client_id].team == 0) chat_lines[chat_current_line].name_color = 0; @@ -261,41 +266,40 @@ void process_events(int snaptype) SNAP_ITEM item; const void *data = snap_get_item(snaptype, index, &item); - if(item.type == EVENT_DAMAGEINDICATION) + if(item.type == NETEVENTTYPE_DAMAGEIND) { - ev_damageind *ev = (ev_damageind *)data; + NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)data; effect_damage_indicator(vec2(ev->x, ev->y), get_direction(ev->angle)); } - else if(item.type == EVENT_AIR_JUMP) + else if(item.type == NETEVENTTYPE_AIR_JUMP) { - ev_common *ev = (ev_common *)data; + NETEVENT_COMMON *ev = (NETEVENT_COMMON *)data; effect_air_jump(vec2(ev->x, ev->y)); } - else if(item.type == EVENT_EXPLOSION) + else if(item.type == NETEVENTTYPE_EXPLOSION) { - ev_explosion *ev = (ev_explosion *)data; + NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)data; effect_explosion(vec2(ev->x, ev->y)); } - else if(item.type == EVENT_SMOKE) + /*else if(item.type == EVENT_SMOKE) { - ev_explosion *ev = (ev_explosion *)data; + EV_EXPLOSION *ev = (EV_EXPLOSION *)data; vec2 p(ev->x, ev->y); - } - else if(item.type == EVENT_PLAYERSPAWN) + }*/ + else if(item.type == NETEVENTTYPE_SPAWN) { - ev_explosion *ev = (ev_explosion *)data; + NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)data; effect_playerspawn(vec2(ev->x, ev->y)); } - else if(item.type == EVENT_DEATH) + else if(item.type == NETEVENTTYPE_DEATH) { - ev_explosion *ev = (ev_explosion *)data; + NETEVENT_DEATH *ev = (NETEVENT_DEATH *)data; effect_playerdeath(vec2(ev->x, ev->y)); } - else if(item.type == EVENT_SOUND_WORLD) + else if(item.type == NETEVENTTYPE_SOUND_WORLD) { - ev_sound *ev = (ev_sound *)data; - if(ev->sound >= 0 && ev->sound < NUM_SOUNDS) - snd_play_random(CHN_WORLD, ev->sound, 1.0f, vec2(ev->x, ev->y)); + NETEVENT_SOUND_WORLD *ev = (NETEVENT_SOUND_WORLD *)data; + snd_play_random(CHN_WORLD, ev->soundid, 1.0f, vec2(ev->x, ev->y)); } } } @@ -303,12 +307,7 @@ void process_events(int snaptype) void clear_object_pointers() { // clear out the invalid pointers - local_character = 0; - local_prev_character = 0; - local_info = 0; - flags[0] = 0; - flags[1] = 0; - gameobj = 0; + mem_zero(&netobjects, sizeof(netobjects)); } void send_info(bool start) @@ -526,16 +525,16 @@ void render_goals(float x, float y, float w) // render goals //y = ystart+h-54; - if(gameobj && gameobj->time_limit) + if(netobjects.gameobj && netobjects.gameobj->time_limit) { char buf[64]; - str_format(buf, sizeof(buf), "Time Limit: %d min", gameobj->time_limit); + str_format(buf, sizeof(buf), "Time Limit: %d min", netobjects.gameobj->time_limit); gfx_text(0, x+w/2, y, 24.0f, buf, -1); } - if(gameobj && gameobj->score_limit) + if(netobjects.gameobj && netobjects.gameobj->score_limit) { char buf[64]; - str_format(buf, sizeof(buf), "Score Limit: %d", gameobj->score_limit); + str_format(buf, sizeof(buf), "Score Limit: %d", netobjects.gameobj->score_limit); gfx_text(0, x+40, y, 24.0f, buf, -1); } } @@ -560,14 +559,14 @@ void render_spectators(float x, float y, float w) SNAP_ITEM item; const void *data = snap_get_item(SNAP_CURRENT, i, &item); - if(item.type == OBJTYPE_PLAYER_INFO) + if(item.type == NETOBJTYPE_PLAYER_INFO) { - const obj_player_info *info = (const obj_player_info *)data; + const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data; if(info->team == -1) { if(count) strcat(buffer, ", "); - strcat(buffer, client_datas[info->clientid].name); + strcat(buffer, client_datas[info->cid].name); count++; } } @@ -595,7 +594,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) // render title if(!title) { - if(gameobj->game_over) + if(netobjects.gameobj->game_over) title = "Game Over"; else title = "Score Board"; @@ -611,10 +610,11 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) { gfx_text(0, x+10, y, 48, title, -1); - if(gameobj) + if(netobjects.gameobj) { char buf[128]; - str_format(buf, sizeof(buf), "%d", gameobj->teamscore[team&1]); + int score = team ? netobjects.gameobj->teamscore_blue : netobjects.gameobj->teamscore_red; + str_format(buf, sizeof(buf), "%d", score); tw = gfx_text_width(0, 48, buf, -1); gfx_text(0, x+w-tw-30, y, 48, buf, -1); } @@ -623,16 +623,16 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) y += 54.0f; // find players - const obj_player_info *players[MAX_CLIENTS] = {0}; + const NETOBJ_PLAYER_INFO *players[MAX_CLIENTS] = {0}; int num_players = 0; for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++) { SNAP_ITEM item; const void *data = snap_get_item(SNAP_CURRENT, i, &item); - if(item.type == OBJTYPE_PLAYER_INFO) + if(item.type == NETOBJTYPE_PLAYER_INFO) { - players[num_players] = (const obj_player_info *)data; + players[num_players] = (const NETOBJ_PLAYER_INFO *)data; num_players++; } } @@ -644,7 +644,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) { if(players[i]->score < players[i+1]->score) { - const obj_player_info *tmp = players[i]; + const NETOBJ_PLAYER_INFO *tmp = players[i]; players[i] = players[i+1]; players[i+1] = tmp; } @@ -660,7 +660,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) // render player scores for(int i = 0; i < num_players; i++) { - const obj_player_info *info = players[i]; + const NETOBJ_PLAYER_INFO *info = players[i]; // make sure that we render the correct team if(team == -1 || info->team != team) @@ -683,18 +683,19 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) if(config.cl_show_player_ids) { - str_format(buf, sizeof(buf), "%d | %s", info->clientid, client_datas[info->clientid].name); + str_format(buf, sizeof(buf), "%d | %s", info->cid, client_datas[info->cid].name); gfx_text(0, x+128, y, font_size, buf, -1); } else - gfx_text(0, x+128, y, font_size, client_datas[info->clientid].name, -1); + gfx_text(0, x+128, y, font_size, client_datas[info->cid].name, -1); str_format(buf, sizeof(buf), "%4d", info->latency); float tw = gfx_text_width(0, font_size, buf, -1); gfx_text(0, x+w-tw-35, y, font_size, buf, -1); // render avatar - if((flags[0] && flags[0]->carried_by == info->clientid) || (flags[1] && flags[1]->carried_by == info->clientid)) + if((netobjects.flags[0] && netobjects.flags[0]->carried_by == info->cid) || + (netobjects.flags[1] && netobjects.flags[1]->carried_by == info->cid)) { gfx_blend_normal(); gfx_texture_set(data->images[IMAGE_GAME].id); @@ -708,7 +709,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) gfx_quads_end(); } - render_tee(&idlestate, &client_datas[info->clientid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28)); + render_tee(&idlestate, &client_datas[info->cid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28)); y += 50.0f; @@ -739,21 +740,21 @@ void render_game() if(config.cl_predict) { - if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over)) + if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over)) { // don't use predicted } else local_character_pos = mix(predicted_prev_player.pos, predicted_player.pos, client_predintratick()); } - else if(local_character && local_prev_character) + else if(netobjects.local_character && netobjects.local_prev_character) { local_character_pos = mix( - vec2(local_prev_character->x, local_prev_character->y), - vec2(local_character->x, local_character->y), client_intratick()); + vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y), + vec2(netobjects.local_character->x, netobjects.local_character->y), client_intratick()); } - if(local_info && local_info->team == -1) + if(netobjects.local_info && netobjects.local_info->team == -1) spectate = true; animstate idlestate; @@ -1089,7 +1090,7 @@ void render_game() gfx_quads_end(); }*/ - if(local_character && !spectate && !(gameobj && gameobj->game_over)) + if(netobjects.local_character && !spectate && !(netobjects.gameobj && netobjects.gameobj->game_over)) { gfx_texture_set(data->images[IMAGE_GAME].id); gfx_quads_begin(); @@ -1097,7 +1098,7 @@ void render_game() // render cursor if (!menu_active && !emoticon_selector_active) { - select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_cursor); + select_sprite(data->weapons[netobjects.local_character->weapon%data->num_weapons].sprite_cursor); float cursorsize = 64; draw_sprite(local_target_pos.x, local_target_pos.y, cursorsize); } @@ -1113,10 +1114,10 @@ void render_game() // if weaponstage is active, put a "glow" around the stage ammo select_sprite(SPRITE_TEE_BODY); - for (int i = 0; i < local_character->weaponstage; i++) - gfx_quads_drawTL(x+local_character->ammocount * 12 -i*12, y+22, 11, 11); - select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_proj); - for (int i = 0; i < min(local_character->ammocount, 10); i++) + for (int i = 0; i < netobjects.local_character->weaponstage; i++) + gfx_quads_drawTL(x+netobjects.local_character->ammocount * 12 -i*12, y+22, 11, 11); + select_sprite(data->weapons[netobjects.local_character->weapon%data->num_weapons].sprite_proj); + for (int i = 0; i < min(netobjects.local_character->ammocount, 10); i++) gfx_quads_drawTL(x+i*12,y+24,10,10); gfx_quads_end(); @@ -1127,7 +1128,7 @@ void render_game() // render health select_sprite(SPRITE_HEALTH_FULL); - for(; h < local_character->health; h++) + for(; h < netobjects.local_character->health; h++) gfx_quads_drawTL(x+h*12,y,10,10); select_sprite(SPRITE_HEALTH_EMPTY); @@ -1137,7 +1138,7 @@ void render_game() // render armor meter h = 0; select_sprite(SPRITE_ARMOR_FULL); - for(; h < local_character->armor; h++) + for(; h < netobjects.local_character->armor; h++) gfx_quads_drawTL(x+h*12,y+12,10,10); select_sprite(SPRITE_ARMOR_EMPTY); @@ -1172,7 +1173,7 @@ void render_game() // render victim tee x -= 24.0f; - if(gameobj && gameobj->gametype == GAMETYPE_CTF) + if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF) { if(killmsgs[r].mode_special&1) { @@ -1206,7 +1207,7 @@ void render_game() if(killmsgs[r].victim != killmsgs[r].killer) { - if(gameobj && gameobj->gametype == GAMETYPE_CTF) + if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF) { if(killmsgs[r].mode_special&2) { @@ -1305,34 +1306,34 @@ void render_game() } // render goals - if(gameobj) + if(netobjects.gameobj) { - int gametype = gameobj->gametype; + int gametype = netobjects.gameobj->gametype; float whole = 300*gfx_screenaspect(); float half = whole/2.0f; gfx_mapscreen(0,0,300*gfx_screenaspect(),300); - if(!gameobj->sudden_death) + if(!netobjects.gameobj->sudden_death) { char buf[32]; int time = 0; - if(gameobj->time_limit) + if(netobjects.gameobj->time_limit) { - time = gameobj->time_limit*60 - ((client_tick()-gameobj->round_start_tick)/client_tickspeed()); + time = netobjects.gameobj->time_limit*60 - ((client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed()); - if(gameobj->game_over) + if(netobjects.gameobj->game_over) time = 0; } else - time = (client_tick()-gameobj->round_start_tick)/client_tickspeed(); + time = (client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed(); str_format(buf, sizeof(buf), "%d:%02d", time /60, time %60); float w = gfx_text_width(0, 16, buf, -1); gfx_text(0, half-w/2, 2, 16, buf, -1); } - if(gameobj->sudden_death) + if(netobjects.gameobj->sudden_death) { const char *text = "Sudden Death"; float w = gfx_text_width(0, 16, text, -1); @@ -1340,7 +1341,7 @@ void render_game() } // render small score hud - if(!(gameobj && gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF)) + if(!(netobjects.gameobj && netobjects.gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF)) { for(int t = 0; t < 2; t++) { @@ -1355,15 +1356,15 @@ void render_game() gfx_quads_end(); char buf[32]; - str_format(buf, sizeof(buf), "%d", gameobj->teamscore[t]); + str_format(buf, sizeof(buf), "%d", t?netobjects.gameobj->teamscore_blue:netobjects.gameobj->teamscore_red); float w = gfx_text_width(0, 14, buf, -1); if(gametype == GAMETYPE_CTF) { gfx_text(0, whole-20-w/2+5, 300-40-15+t*20+2, 14, buf, -1); - if(flags[t]) + if(netobjects.flags[t]) { - if(flags[t]->carried_by == -2 || (flags[t]->carried_by == -1 && ((client_tick()/10)&1))) + if(netobjects.flags[t]->carried_by == -2 || (netobjects.flags[t]->carried_by == -1 && ((client_tick()/10)&1))) { gfx_blend_normal(); gfx_texture_set(data->images[IMAGE_GAME].id); @@ -1376,9 +1377,9 @@ void render_game() gfx_quads_drawTL(whole-40+5, 300-40-15+t*20+1, size/2, size); gfx_quads_end(); } - else if(flags[t]->carried_by >= 0) + else if(netobjects.flags[t]->carried_by >= 0) { - int id = flags[t]->carried_by%MAX_CLIENTS; + int id = netobjects.flags[t]->carried_by%MAX_CLIENTS; const char *name = client_datas[id].name; float w = gfx_text_width(0, 10, name, -1); gfx_text(0, whole-40-5-w, 300-40-15+t*20+2, 10, name, -1); @@ -1396,15 +1397,15 @@ void render_game() } // render warmup timer - if(gameobj->warmup) + if(netobjects.gameobj->warmup) { char buf[256]; float w = gfx_text_width(0, 24, "Warmup", -1); gfx_text(0, 150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1); - int seconds = gameobj->warmup/SERVER_TICK_SPEED; + int seconds = netobjects.gameobj->warmup/SERVER_TICK_SPEED; if(seconds < 5) - str_format(buf, sizeof(buf), "%d.%d", seconds, (gameobj->warmup*10/SERVER_TICK_SPEED)%10); + str_format(buf, sizeof(buf), "%d.%d", seconds, (netobjects.gameobj->warmup*10/SERVER_TICK_SPEED)%10); else str_format(buf, sizeof(buf), "%d", seconds); w = gfx_text_width(0, 24, buf, -1); @@ -1439,12 +1440,12 @@ void render_game() } } - if(config.debug && local_character && local_prev_character) + if(config.debug && netobjects.local_character && netobjects.local_prev_character) { gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300); - float speed = distance(vec2(local_prev_character->x, local_prev_character->y), - vec2(local_character->x, local_character->y)); + float speed = distance(vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y), + vec2(netobjects.local_character->x, netobjects.local_character->y)); char buf[512]; str_format(buf, sizeof(buf), "%.2f", speed/2); @@ -1453,15 +1454,15 @@ void render_game() // render score board if(inp_key_pressed(KEY_TAB) || // user requested - (!spectate && (!local_character || local_character->health < 0)) || // not spectating and is dead - (gameobj && gameobj->game_over) // game over + (!spectate && (!netobjects.local_character || netobjects.local_character->health < 0)) || // not spectating and is dead + (netobjects.gameobj && netobjects.gameobj->game_over) // game over ) { gfx_mapscreen(0, 0, width, height); float w = 650.0f; - if (gameobj && gameobj->gametype == GAMETYPE_DM) + if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_DM) { render_scoreboard(width/2-w/2, 150.0f, w, 0, 0); //render_scoreboard(gameobj, 0, 0, -1, 0); @@ -1469,12 +1470,12 @@ void render_game() else { - if(gameobj && gameobj->game_over) + if(netobjects.gameobj && netobjects.gameobj->game_over) { const char *text = "DRAW!"; - if(gameobj->teamscore[0] > gameobj->teamscore[1]) + if(netobjects.gameobj->teamscore_red > netobjects.gameobj->teamscore_blue) text = "Red Team Wins!"; - else if(gameobj->teamscore[1] > gameobj->teamscore[0]) + else if(netobjects.gameobj->teamscore_blue > netobjects.gameobj->teamscore_red) text = "Blue Team Wins!"; float w = gfx_text_width(0, 92.0f, text, -1); diff --git a/src/game/client/gc_client.h b/src/game/client/gc_client.h index 857a9088..93a90a86 100644 --- a/src/game/client/gc_client.h +++ b/src/game/client/gc_client.h @@ -20,11 +20,29 @@ extern vec2 local_character_pos; extern vec2 local_target_pos; // snap pointers -extern const obj_player_character *local_character; -extern const obj_player_character *local_prev_character; -extern const obj_player_info *local_info; -extern const obj_flag *flags[2]; -extern const obj_game *gameobj; +struct snapstate +{ + const NETOBJ_PLAYER_CHARACTER *local_character; + const NETOBJ_PLAYER_CHARACTER *local_prev_character; + const NETOBJ_PLAYER_INFO *local_info; + const NETOBJ_FLAG *flags[2]; + const NETOBJ_GAME *gameobj; + + const NETOBJ_PLAYER_INFO *player_infos[MAX_CLIENTS]; + const NETOBJ_PLAYER_INFO *info_by_score[MAX_CLIENTS]; + int num_players; +}; + +extern snapstate netobjects; + +/* +extern const NETOBJ_PLAYER_CHARACTER *local_character; +extern const NETOBJ_PLAYER_CHARACTER *local_prev_character; +extern const NETOBJ_PLAYER_INFO *local_info; +extern const NETOBJ_FLAG *flags[2]; +extern const NETOBJ_GAME *gameobj; +* */ + extern tuning_params tuning; // predicted players @@ -33,7 +51,7 @@ extern player_core predicted_player; // input extern int picked_up_weapon; -extern player_input input_data; +extern NETOBJ_PLAYER_INPUT input_data; extern int input_target_lock; // debug @@ -45,7 +63,7 @@ enum MAX_EXTRA_PROJECTILES=32, }; -extern obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES]; +extern NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES]; extern int extraproj_num; void extraproj_reset(); diff --git a/src/game/client/gc_hooks.cpp b/src/game/client/gc_hooks.cpp index a6391007..9292d08c 100644 --- a/src/game/client/gc_hooks.cpp +++ b/src/game/client/gc_hooks.cpp @@ -120,17 +120,17 @@ extern "C" void modc_predict() const void *data = snap_get_item(SNAP_CURRENT, i, &item); int client_id = item.id; - if(item.type == OBJTYPE_PLAYER_CHARACTER) + if(item.type == NETOBJTYPE_PLAYER_CHARACTER) { - const obj_player_character *character = (const obj_player_character *)data; + const NETOBJ_PLAYER_CHARACTER *character = (const NETOBJ_PLAYER_CHARACTER *)data; client_datas[client_id].predicted.world = &world; world.players[client_id] = &client_datas[client_id].predicted; client_datas[client_id].predicted.read(character); } - else if(item.type == OBJTYPE_PLAYER_INFO) + else if(item.type == NETOBJTYPE_PLAYER_INFO) { - const obj_player_info *info = (const obj_player_info *)data; + const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data; if(info->local) local_cid = client_id; } @@ -155,7 +155,7 @@ extern "C" void modc_predict() // apply player input int *input = client_get_input(tick); if(input) - world.players[c]->input = *((player_input*)input); + world.players[c]->input = *((NETOBJ_PLAYER_INPUT*)input); } world.players[c]->tick(); @@ -230,6 +230,23 @@ extern "C" void modc_newsnapshot() static int snapshot_count = 0; snapshot_count++; + // secure snapshot + { + int num = snap_num_items(SNAP_CURRENT); + for(int index = 0; index < num; index++) + { + SNAP_ITEM item; + void *data = snap_get_item(SNAP_CURRENT, index, &item); + if(netobj_secure(item.type, data, item.datasize) != 0) + { + if(config.debug) + dbg_msg("game", "invalidated %d %d (%s) %d", index, item.type, netobj_get_name(item.type), item.id); + snap_invalidate_item(SNAP_CURRENT, index); + } + } + } + + process_events(SNAP_CURRENT); if(config.dbg_stress) @@ -256,32 +273,32 @@ extern "C" void modc_newsnapshot() SNAP_ITEM item; const void *data = snap_get_item(SNAP_CURRENT, i, &item); - if(item.type == OBJTYPE_PLAYER_INFO) + if(item.type == NETOBJTYPE_PLAYER_INFO) { - const obj_player_info *info = (const obj_player_info *)data; + const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data; - client_datas[info->clientid].team = info->team; + client_datas[info->cid].team = info->team; if(info->local) { - local_info = info; - const void *data = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_CHARACTER, item.id); + netobjects.local_info = info; + const void *data = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_CHARACTER, item.id); if(data) { - local_character = (const obj_player_character *)data; - local_character_pos = vec2(local_character->x, local_character->y); + netobjects.local_character = (const NETOBJ_PLAYER_CHARACTER *)data; + local_character_pos = vec2(netobjects.local_character->x, netobjects.local_character->y); - const void *p = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_CHARACTER, item.id); + const void *p = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_CHARACTER, item.id); if(p) - local_prev_character = (obj_player_character *)p; + netobjects.local_prev_character = (NETOBJ_PLAYER_CHARACTER *)p; } } } - else if(item.type == OBJTYPE_GAME) - gameobj = (obj_game *)data; - else if(item.type == OBJTYPE_FLAG) + else if(item.type == NETOBJTYPE_GAME) + netobjects.gameobj = (NETOBJ_GAME *)data; + else if(item.type == NETOBJTYPE_FLAG) { - flags[item.id%2] = (const obj_flag *)data; + netobjects.flags[item.id%2] = (const NETOBJ_FLAG *)data; } } } @@ -394,7 +411,7 @@ extern "C" void modc_statechange(int state, int old) } } -obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES]; +NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES]; int extraproj_num; void extraproj_reset() @@ -409,6 +426,11 @@ extern "C" void modc_message(int msg) int cid = msg_unpack_int(); int team = msg_unpack_int(); const char *message = msg_unpack_string(); + + /* check for errors and invalid inputs */ + if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS) + return; + dbg_msg("message", "chat cid=%d team=%d msg='%s'", cid, team, message); chat_add_line(cid, team, message); @@ -423,10 +445,13 @@ extern "C" void modc_message(int msg) for(int k = 0; k < num; k++) { - obj_projectile proj; - for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++) + NETOBJ_PROJECTILE proj; + for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++) ((int *)&proj)[i] = msg_unpack_int(); + if(msg_unpack_error()) + return; + if(extraproj_num != MAX_EXTRA_PROJECTILES) { extraproj_projectiles[extraproj_num] = proj; @@ -440,6 +465,10 @@ extern "C" void modc_message(int msg) const char *name = msg_unpack_string(); const char *skinname = msg_unpack_string(); + /* check for errors and invalid inputs */ + if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS) + return; + strncpy(client_datas[cid].name, name, 64); strncpy(client_datas[cid].skin_name, skinname, 64); @@ -466,13 +495,24 @@ extern "C" void modc_message(int msg) } else if(msg == MSG_TUNE_PARAMS) { - int *params = (int *)&tuning; + // unpack the new tuning + tuning_params new_tuning; + int *params = (int *)&new_tuning; for(unsigned i = 0; i < sizeof(tuning_params)/sizeof(int); i++) params[i] = msg_unpack_int(); + + // check for unpacking errors + if(msg_unpack_error()) + return; + + // apply new tuning + tuning = new_tuning; } else if(msg == MSG_WEAPON_PICKUP) { int weapon = msg_unpack_int(); + if(msg_unpack_error()) + return; picked_up_weapon = weapon+1; } else if(msg == MSG_READY_TO_ENTER) @@ -481,23 +521,41 @@ extern "C" void modc_message(int msg) } else if(msg == MSG_KILLMSG) { + // unpack messages + killmsg msg; + msg.killer = msg_unpack_int(); + msg.victim = msg_unpack_int(); + msg.weapon = msg_unpack_int(); + msg.mode_special = msg_unpack_int(); + msg.tick = client_tick(); + + // check for unpacking errors + if(msg_unpack_error() || msg.killer >= MAX_CLIENTS || msg.victim >= MAX_CLIENTS || msg.weapon >= NUM_WEAPONS) + return; + + // add the message killmsg_current = (killmsg_current+1)%killmsg_max; - killmsgs[killmsg_current].killer = msg_unpack_int(); - killmsgs[killmsg_current].victim = msg_unpack_int(); - killmsgs[killmsg_current].weapon = msg_unpack_int(); - killmsgs[killmsg_current].mode_special = msg_unpack_int(); - killmsgs[killmsg_current].tick = client_tick(); + killmsgs[killmsg_current] = msg; } else if (msg == MSG_EMOTICON) { + // unpack int cid = msg_unpack_int(); int emoticon = msg_unpack_int(); + + // check for errors + if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS) + return; + + // apply client_datas[cid].emoticon = emoticon; client_datas[cid].emoticon_start = client_tick(); } else if(msg == MSG_SOUND_GLOBAL) { int soundid = msg_unpack_int(); + if(msg_unpack_error() || soundid < 0) + return; snd_play_random(CHN_GLOBAL, soundid, 1.0f, vec2(0,0)); } } diff --git a/src/game/client/gc_menu.cpp b/src/game/client/gc_menu.cpp index 51333288..ec2cc2fe 100644 --- a/src/game/client/gc_menu.cpp +++ b/src/game/client/gc_menu.cpp @@ -27,10 +27,6 @@ extern "C" { extern data_container *data; -// abit uglyness -extern const obj_player_info *local_info; -extern const obj_game *gameobj; - extern bool menu_active; extern bool menu_game_active; @@ -1614,9 +1610,9 @@ static void menu2_render_game(RECT main_view) if(ui_do_button(&disconnect_button, "Disconnect", 0, &button, ui_draw_menu_button, 0)) client_disconnect(); - if(local_info && gameobj) + if(netobjects.local_info && netobjects.gameobj) { - if(local_info->team != -1) + if(netobjects.local_info->team != -1) { ui_vsplit_l(&main_view, 10.0f, &button, &main_view); ui_vsplit_l(&main_view, 120.0f, &button, &main_view); @@ -1628,9 +1624,9 @@ static void menu2_render_game(RECT main_view) } } - if(gameobj->gametype == GAMETYPE_DM) + if(netobjects.gameobj->gametype == GAMETYPE_DM) { - if(local_info->team != 0) + if(netobjects.local_info->team != 0) { ui_vsplit_l(&main_view, 10.0f, &button, &main_view); ui_vsplit_l(&main_view, 120.0f, &button, &main_view); @@ -1644,7 +1640,7 @@ static void menu2_render_game(RECT main_view) } else { - if(local_info->team != 0) + if(netobjects.local_info->team != 0) { ui_vsplit_l(&main_view, 10.0f, &button, &main_view); ui_vsplit_l(&main_view, 120.0f, &button, &main_view); @@ -1656,7 +1652,7 @@ static void menu2_render_game(RECT main_view) } } - if(local_info->team != 1) + if(netobjects.local_info->team != 1) { ui_vsplit_l(&main_view, 10.0f, &button, &main_view); ui_vsplit_l(&main_view, 120.0f, &button, &main_view); diff --git a/src/game/client/gc_render.cpp b/src/game/client/gc_render.cpp index 1d276ec3..6e001bd1 100644 --- a/src/game/client/gc_render.cpp +++ b/src/game/client/gc_render.cpp @@ -349,25 +349,25 @@ static void render_items() SNAP_ITEM item; const void *data = snap_get_item(SNAP_CURRENT, i, &item); - if(item.type == OBJTYPE_PROJECTILE) + if(item.type == NETOBJTYPE_PROJECTILE) { - render_projectile((const obj_projectile *)data, item.id); + render_projectile((const NETOBJ_PROJECTILE *)data, item.id); } - else if(item.type == OBJTYPE_POWERUP) + else if(item.type == NETOBJTYPE_POWERUP) { const void *prev = snap_find_item(SNAP_PREV, item.type, item.id); if(prev) - render_powerup((const obj_powerup *)prev, (const obj_powerup *)data); + render_powerup((const NETOBJ_POWERUP *)prev, (const NETOBJ_POWERUP *)data); } - else if(item.type == OBJTYPE_LASER) + else if(item.type == NETOBJTYPE_LASER) { - render_laser((const obj_laser *)data); + render_laser((const NETOBJ_LASER *)data); } - else if(item.type == OBJTYPE_FLAG) + else if(item.type == NETOBJTYPE_FLAG) { const void *prev = snap_find_item(SNAP_PREV, item.type, item.id); if (prev) - render_flag((const obj_flag *)prev, (const obj_flag *)data); + render_flag((const NETOBJ_FLAG *)prev, (const NETOBJ_FLAG *)data); } } @@ -393,19 +393,19 @@ static void render_players() SNAP_ITEM item; const void *data = snap_get_item(SNAP_CURRENT, i, &item); - if(item.type == OBJTYPE_PLAYER_CHARACTER) + if(item.type == NETOBJTYPE_PLAYER_CHARACTER) { const void *prev = snap_find_item(SNAP_PREV, item.type, item.id); - const void *prev_info = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_INFO, item.id); - const void *info = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_INFO, item.id); + const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, item.id); + const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, item.id); if(prev && prev_info && info) { render_player( - (const obj_player_character *)prev, - (const obj_player_character *)data, - (const obj_player_info *)prev_info, - (const obj_player_info *)info + (const NETOBJ_PLAYER_CHARACTER *)prev, + (const NETOBJ_PLAYER_CHARACTER *)data, + (const NETOBJ_PLAYER_INFO *)prev_info, + (const NETOBJ_PLAYER_INFO *)info ); } } diff --git a/src/game/client/gc_render.h b/src/game/client/gc_render.h index b62206f7..a6f57b7b 100644 --- a/src/game/client/gc_render.h +++ b/src/game/client/gc_render.h @@ -54,13 +54,13 @@ void render_particles(); // object render methods (gc_render_obj.cpp) void render_tee(class animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos); -void render_flag(const struct obj_flag *prev, const struct obj_flag *current); -void render_powerup(const struct obj_powerup *prev, const struct obj_powerup *current); -void render_projectile(const struct obj_projectile *current, int itemid); -void render_laser(const struct obj_laser *current); +void render_flag(const struct NETOBJ_FLAG *prev, const struct NETOBJ_FLAG *current); +void render_powerup(const struct NETOBJ_POWERUP *prev, const struct NETOBJ_POWERUP *current); +void render_projectile(const struct NETOBJ_PROJECTILE *current, int itemid); +void render_laser(const struct NETOBJ_LASER *current); void render_player( - const struct obj_player_character *prev_char, const struct obj_player_character *player_char, - const struct obj_player_info *prev_info, const struct obj_player_info *player_info); + const struct NETOBJ_PLAYER_CHARACTER *prev_char, const struct NETOBJ_PLAYER_CHARACTER *player_char, + const struct NETOBJ_PLAYER_INFO *prev_info, const struct NETOBJ_PLAYER_INFO *player_info); // map render methods (gc_render_map.cpp) void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result); diff --git a/src/game/client/gc_render_obj.cpp b/src/game/client/gc_render_obj.cpp index cedfc129..995994ed 100644 --- a/src/game/client/gc_render_obj.cpp +++ b/src/game/client/gc_render_obj.cpp @@ -11,7 +11,7 @@ #include "gc_client.h" -void render_projectile(const obj_projectile *current, int itemid) +void render_projectile(const NETOBJ_PROJECTILE *current, int itemid) { if(debug_firedelay) { @@ -34,7 +34,7 @@ void render_projectile(const obj_projectile *current, int itemid) vec2 pos = calc_pos(startpos, startvel, gravity, ct); vec2 prevpos = calc_pos(startpos, startvel, gravity, ct-0.001f); - select_sprite(data->weapons[current->type%data->num_weapons].sprite_proj); + select_sprite(data->weapons[clamp(current->type, 0, NUM_WEAPONS-1)].sprite_proj); vec2 vel = pos-prevpos; //vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick()); @@ -63,7 +63,7 @@ void render_projectile(const obj_projectile *current, int itemid) gfx_quads_end(); } -void render_powerup(const obj_powerup *prev, const obj_powerup *current) +void render_powerup(const NETOBJ_POWERUP *prev, const NETOBJ_POWERUP *current) { gfx_texture_set(data->images[IMAGE_GAME].id); gfx_quads_begin(); @@ -73,8 +73,8 @@ void render_powerup(const obj_powerup *prev, const obj_powerup *current) if (current->type == POWERUP_WEAPON) { angle = 0; //-pi/6;//-0.25f * pi * 2.0f; - select_sprite(data->weapons[current->subtype%data->num_weapons].sprite_body); - size = data->weapons[current->subtype%data->num_weapons].visual_size; + select_sprite(data->weapons[clamp(current->subtype, 0, NUM_WEAPONS-1)].sprite_body); + size = data->weapons[clamp(current->subtype, 0, NUM_WEAPONS-1)].visual_size; } else { @@ -107,7 +107,7 @@ void render_powerup(const obj_powerup *prev, const obj_powerup *current) gfx_quads_end(); } -void render_flag(const obj_flag *prev, const obj_flag *current) +void render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current) { float angle = 0.0f; float size = 42.0f; @@ -125,7 +125,7 @@ void render_flag(const obj_flag *prev, const obj_flag *current) vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick()); - if(local_info && current->carried_by == local_info->clientid) + if(netobjects.local_info && current->carried_by == netobjects.local_info->cid) pos = local_character_pos; //gfx_setcolor(current->team ? 0 : 1,0,current->team ? 1 : 0,1); @@ -135,7 +135,7 @@ void render_flag(const obj_flag *prev, const obj_flag *current) } -void render_laser(const struct obj_laser *current) +void render_laser(const struct NETOBJ_LASER *current) { vec2 pos = vec2(current->x, current->y); @@ -245,19 +245,19 @@ static void render_hand(tee_render_info *info, vec2 center_pos, vec2 dir, float } void render_player( - const obj_player_character *prev_char, - const obj_player_character *player_char, - const obj_player_info *prev_info, - const obj_player_info *player_info + const NETOBJ_PLAYER_CHARACTER *prev_char, + const NETOBJ_PLAYER_CHARACTER *player_char, + const NETOBJ_PLAYER_INFO *prev_info, + const NETOBJ_PLAYER_INFO *player_info ) { - obj_player_character prev; - obj_player_character player; + NETOBJ_PLAYER_CHARACTER prev; + NETOBJ_PLAYER_CHARACTER player; prev = *prev_char; player = *player_char; - obj_player_info info = *player_info; - tee_render_info render_info = client_datas[info.clientid].render_info; + NETOBJ_PLAYER_INFO info = *player_info; + tee_render_info render_info = client_datas[info.cid].render_info; float intratick = client_intratick(); float ticktime = client_ticktime(); @@ -267,7 +267,7 @@ void render_player( if(info.local && config.cl_predict) { - if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over)) + if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over)) { } else @@ -329,7 +329,7 @@ void render_player( if(player_char->hooked_player != -1) { - if(local_info && player_char->hooked_player == local_info->clientid) + 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), vec2(predicted_player.pos.x, predicted_player.pos.y), client_predintratick()); @@ -351,7 +351,8 @@ void render_player( // render chain select_sprite(SPRITE_HOOK_CHAIN); - for(float f = 24; f < d; f += 24) + int i = 0; + for(float f = 24; f < d && i < 1024; f += 24, i++) { vec2 p = hook_pos + dir*f; gfx_quads_draw(p.x, p.y,24,16); @@ -360,7 +361,7 @@ void render_player( gfx_quads_setrotation(0); gfx_quads_end(); - render_hand(&client_datas[info.clientid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0)); + render_hand(&client_datas[info.cid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0)); } // draw gun @@ -478,9 +479,9 @@ void render_player( switch (player.weapon) { - case WEAPON_GUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break; - case WEAPON_SHOTGUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-5, 4)); break; - case WEAPON_GRENADE: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-4, 7)); break; + case WEAPON_GUN: render_hand(&client_datas[info.cid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break; + case WEAPON_SHOTGUN: render_hand(&client_datas[info.cid].render_info, p, direction, -pi/2, vec2(-5, 4)); break; + case WEAPON_GRENADE: render_hand(&client_datas[info.cid].render_info, p, direction, -pi/2, vec2(-4, 7)); break; } } @@ -507,13 +508,13 @@ void render_player( gfx_quads_end(); } - if (client_datas[info.clientid].emoticon_start != -1 && client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() > client_tick()) + if (client_datas[info.cid].emoticon_start != -1 && client_datas[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick()) { gfx_texture_set(data->images[IMAGE_EMOTICONS].id); gfx_quads_begin(); - int since_start = client_tick() - client_datas[info.clientid].emoticon_start; - int from_end = client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() - client_tick(); + int since_start = client_tick() - client_datas[info.cid].emoticon_start; + int from_end = client_datas[info.cid].emoticon_start + 2 * client_tickspeed() - client_tick(); float a = 1; @@ -534,7 +535,7 @@ void render_player( gfx_setcolor(1.0f,1.0f,1.0f,a); // client_datas::emoticon is an offset from the first emoticon - select_sprite(SPRITE_OOP + client_datas[info.clientid].emoticon); + select_sprite(SPRITE_OOP + client_datas[info.cid].emoticon); gfx_quads_draw(position.x, position.y - 23 - 32*h, 64, 64*h); gfx_quads_end(); } @@ -547,7 +548,7 @@ void render_player( if(config.cl_nameplates_always == 0) a = clamp(1-powf(distance(local_target_pos, position)/200.0f,16.0f), 0.0f, 1.0f); - const char *name = client_datas[info.clientid].name; + const char *name = client_datas[info.cid].name; float tw = gfx_text_width(0, 28.0f, name, -1); gfx_text_color(1,1,1,a); gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1); |