static int proto_server_pickup_handler(Proto_Session *s){ int id,rc,ret; Proto_Msg_Hdr sh; Proto_Msg_Hdr rh; Player* p; Proto_Session *us; bzero(&sh, sizeof(sh)); bzero(&rh, sizeof(rh)); sh.type = proto_session_hdr_unmarshall_type(s); sh.type += PROTO_MT_REP_BASE_RESERVED_FIRST; proto_session_hdr_unmarshall(s, &rh); id = rh.pstate.v0.raw; p = gamestate_get_player(Server_Gamestate,id); ret = player_obj_pickup(p,Server_ObjectMap,Server_Gamestate); sh.pstate.v0.raw = id;//same header for both reply and update sh.pstate.v1.raw = ret; //sending back the actual thing picked up proto_session_hdr_marshall(s, &sh); rc = proto_session_send_msg(s,1); if(ret >= 0){ us = proto_server_event_session(); sh.type = PROTO_MT_EVENT_BASE_MOVE; proto_session_hdr_marshall(us,&sh); proto_server_post_event(); } return rc; }
extern void get_hdr(Proto_Client_Handle ch, Proto_Msg_Hdr * hdr) { Proto_Session *s; Proto_Client *c = ch; s = &(c->rpc_session); proto_session_hdr_unmarshall(s,hdr); }
static int do_cinfo_rpc(Proto_Client_Handle ch, int x, int y, Proto_Msg_Types mt){ int rc=0; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr *hdr = malloc(sizeof(Proto_Msg_Hdr)); s = &(c->rpc_session); bzero(hdr, sizeof(Proto_Msg_Hdr)); hdr->pstate.v0.raw=x; hdr->pstate.v1.raw=y; hdr->type = mt; proto_session_hdr_marshall(s,hdr); proto_dump_msghdr(&(s->shdr)); rc = proto_session_rpc(s); if(rc==1){ proto_session_hdr_unmarshall(s,&s->rhdr); proto_dump_msghdr(&(s->rhdr)); } else c->session_lost_handler(s); return rc; }
static int do_goodbye_rpc(Proto_Client_Handle ch, Player *p, Proto_Msg_Types mt){ int rc=0; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr hdr; s = &(c->rpc_session); bzero(&hdr, sizeof(Proto_Msg_Hdr)); hdr.type = mt; proto_session_hdr_marshall(s,&hdr); proto_session_body_marshall_player(s,p); rc = proto_session_rpc(s); if(rc==1){ proto_session_hdr_unmarshall(s,&s->rhdr); // proto_dump_msghdr(&(s->rhdr)); } else c->session_lost_handler(s); return rc; }
/* Broadcast Message Format Version 1 header: game_ver, game_state, count_cellinfo, count_playerinfo, count_iteminfo, extra? uint long short short short int 4 + 8 + 2 + 2 + 1 = 22 bytes 4 + 5 bytes = 10 bytes items: type, x, y char char char 3 bytes */ static int proto_client_event_update_handler(Proto_Session *s) { unsigned long long temp_version; Proto_Msg_Hdr h; if (proto_debug()) fprintf(stderr, "proto_client_event_update_handler: invoked for session:\n"); bzero(&h, sizeof(h)); proto_session_hdr_unmarshall(s, &h); if (proto_debug()) fprintf(stderr, "@proto_client_event_update_handler: server game_version = %llu\n, " "local game_version = %llu\n, trs=%llu, server game_state = %d\n", h.sver.raw, gamedata.game_version, h.gstate.v1.raw, h.gstate.v0.raw); for(;;) { pthread_mutex_lock(&client_data_mutex); // check that client recieved rpc join reply if ( gamedata.game_version == 0 ) { pthread_mutex_unlock(&client_data_mutex); continue; } else if (h.sver.raw > gamedata.game_version) { // update all the maze if (proto_client_event_msg_unmarshall_v1(s, h.blen, h.sver.raw, 0) < 0) fprintf(stderr, "proto_client_event_update_handler: ERROR " "proto_client_event_msg_unmarshall_v1 failed\n"); gamedata.game_version++; // = h.sver.raw; } else if (h.sver.raw <= gamedata.game_version) { // update the outdated maze cells if (proto_client_event_msg_unmarshall_v1( s, h.blen, h.sver.raw, 1 ) < 0) fprintf(stderr, "proto_client_event_update_handler: ERROR " "proto_client_event_msg_unmarshall_v1 failed\n"); } if (proto_debug()) fprintf(stderr, "new client (local) game_version = %llu\n", gamedata.game_version); // TODO: possible recieve an out of order end game. think of how to deal with that gamedata.game_state = h.gstate.v0.raw; logMaze( themaze.maze, themaze.rows*themaze.columns, h.sver.raw ); pthread_mutex_unlock(&client_data_mutex); break; } return 1; }
static int do_item_action_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt, char item, char action) { int rc; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr h; // prepare message s = &(c->rpc_session); bzero(&h, sizeof(h)); h.type = mt; proto_session_hdr_marshall(s, &h); if (proto_debug()) fprintf(stderr, "do_item_action: pId: %d, item: #%c#, action = #%c#\n", playerdata.id, item, action); if (proto_session_body_marshall_int(s, playerdata.id) < 0) fprintf(stderr, "do_item_action_rpc: proto_session_body_marshall_int failed. " "Not enough available sbufer space\n"); if (proto_session_body_marshall_char(s, item) < 0) fprintf(stderr, "do_item_action: proto_session_body_marshall_char failed. " "Not enough available sbufer space\n"); if (proto_session_body_marshall_char(s, action) < 0) fprintf(stderr, "do_item_action: proto_session_body_marshall_char failed. " "Not enough available sbufer space\n"); rc = proto_session_rpc(s); // process response if (rc == 1) { proto_session_hdr_unmarshall(s, &h); wait_for_event(h.sver.raw); if (proto_session_body_unmarshall_int(s, 0, &rc) < 0) fprintf(stderr, "do_item_action: proto_session_body_unmarshall_int failed\n"); if (proto_debug()) fprintf(stderr, "do_item_action: unmarshalled response rc = %d, game version = %llu, game state = %d \n", rc, h.sver.raw, h.gstate.v0.raw); } else { c->session_lost_handler(s); close(s->fd); } return rc; }
static int do_move_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt, char data) { int rc, temp_version; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr h; // prepare message: pID, move_command s = &(c->rpc_session); bzero(&h, sizeof(h)); h.type = mt; proto_session_hdr_marshall(s, &h); if (proto_debug()) fprintf(stderr, "do_move_rpc:\n pId: %d\n move: #%c#\n", playerdata.id, data); if (proto_session_body_marshall_int(s, playerdata.id) < 0) fprintf(stderr, "do_move_rpc: proto_session_body_marshall_int failed. " "Not enough available sbufer space\n"); if (proto_session_body_marshall_char(s, data) < 0) fprintf(stderr, "do_move_rpc: proto_session_body_marshall_char failed. " "Not enough available sbufer space\n"); rc = proto_session_rpc(s); // process reply if (rc == 1) { proto_session_hdr_unmarshall(s, &h); // wait until we have recieved the envent update wait_for_event(h.sver.raw); if (proto_session_body_unmarshall_int(s, 0, &rc) < 0) fprintf(stderr, "do_move_rpc: proto_session_body_unmarshall_int failed\n"); if (proto_debug()) fprintf(stderr, "do_move_rpc: unmarshalled response rc = %d, game version = %llu, game state = %d \n", rc, h.sver.raw, h.gstate.v0.raw); } else { c->session_lost_handler(s); close(s->fd); } return rc; }
static int do_generic_dummy_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt){ int rc; Proto_Session *s; Proto_Client *c = ch; s = &(c->rpc_session); marshall_mtonly(s, mt); rc = proto_session_rpc(s); if (rc==1) { if(mt == PROTO_MT_REQ_BASE_HELLO){ proto_session_hdr_unmarshall(s,&s->rhdr); } else proto_session_body_unmarshall_int(s, 0, &rc); } else { c->session_lost_handler(s); } return rc; }
static int do_leave_game_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt) { int rc; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr h; if (proto_debug()) fprintf(stderr, "do_leave_rpc\n"); s = &(c->rpc_session); bzero(&h, sizeof(h)); marshall_mtonly(s, mt); rc = proto_session_rpc(s); if (rc == 1) { proto_session_hdr_unmarshall(s, &h); wait_for_event(h.sver.raw); // i dont think I need it here if (proto_session_body_unmarshall_int(s, 0, &rc) < 0) fprintf(stderr, "do_leave_game: proto_session_body_unmarshall_int failed\n"); if (proto_debug()) fprintf(stderr, "do_leave_game: unmarshalled response rc = %d, game version = %llu, game state = %d \n", rc, h.sver.raw, h.gstate.v0.raw); } else { c->session_lost_handler(s); close(s->fd); } return rc; }
static int do_join_game_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt) { int rc, X, Y, ii, size; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr h; if (proto_debug()) fprintf(stderr, "do_join_game_rpc started.\n"); // prepare msessage s = &(c->rpc_session); bzero(&h, sizeof(h)); h.type = mt; proto_session_hdr_marshall(s, &h); if (proto_debug()) fprintf(stderr, "do_move_rpc:\n pId: %d\n", playerdata.id); if (proto_session_body_marshall_int(s, playerdata.id) < 0) fprintf(stderr, "do_join_game_rpc: proto_session_body_marshall_int failed. " "Not enough available sbufer space\n"); // sned message rc = proto_session_rpc(s); // process reply: pID, xdim, ydim, maze if (rc == 1) { proto_session_hdr_unmarshall(s, &h); if (proto_session_body_unmarshall_int(s, 0, &rc) < 0) fprintf(stderr, "do_join_game_rpc: proto_session_body_unmarshall_int failed\n"); if (rc < 0) { if (proto_debug()) fprintf(stderr, "do_join_game_rpc: returned player id = %d\n", rc); return rc; } if (proto_session_body_unmarshall_int(s, sizeof(int), &X) < 0) fprintf(stderr, "do_join_game_rpc: proto_session_body_unmarshall_int failed\n"); if (proto_session_body_unmarshall_int(s, 2*sizeof(int), &Y) < 0) fprintf(stderr, "do_join_game_rpc: proto_session_body_unmarshall_int failed\n"); pthread_mutex_lock(&client_data_mutex); if ( gamedata.game_version == 0 ) { // initialize game version and state playerdata.id = rc; gamedata.game_state = h.gstate.v0.raw; gamedata.game_version = h.sver.raw; themaze.rows = Y; themaze.columns = X; size = X*Y; themaze.maze = (char*) malloc( size*sizeof(char) + 1 ); themaze.cell_version = (unsigned long long*) malloc(size*sizeof(unsigned long long)); if (proto_session_body_unmarshall_bytes(s, 3*sizeof(int), size, themaze.maze) < 0) fprintf(stderr, "do_join_game_rpc: proto_session_body_unmarshall_bytes failed\n"); for (ii = 0; ii < size; ii++) themaze.cell_version[ii] = h.sver.raw; themaze.maze[X*Y] = 0; if (proto_debug()) fprintf(stderr, "do_join_game_rpc: unmarshalled response\n" " game version = %llu\n trs=%llu\n game state = %d\n player id = %d\n" " dimx = %d\n dimy = %d\n", h.sver.raw, h.gstate.v1.raw, h.gstate.v0.raw, rc, X, Y); } else fprintf(stderr, "do_join_game_rpc: WARNING: gamedata had been initialized before\n"); pthread_mutex_unlock(&client_data_mutex); } else { c->session_lost_handler(s); close(s->fd); } return rc; }
static int proto_server_move_handler(Proto_Session *s){ int i,rx,ry,id,rc, winner; dir_t dir; Cell *cell = malloc(sizeof(Cell)); Proto_Msg_Hdr sh; Proto_Msg_Hdr rh; Player* p; Proto_Session *us; int valid; int flagindex; object_t flag = -1; Proto_Session *fs; bzero(&sh, sizeof(sh)); bzero(&rh, sizeof(rh)); sh.type = proto_session_hdr_unmarshall_type(s); sh.type += PROTO_MT_REP_BASE_RESERVED_FIRST; proto_session_hdr_unmarshall(s, &rh); id = rh.pstate.v0.raw; dir = rh.pstate.v1.raw; p = gamestate_get_player(Server_Gamestate,id); valid = 0; flagindex = -1; valid = player_move(dir,p,Server_ObjectMap, Server_Gamestate); // printf("Valid bit%d\n", valid); if (valid>0) { sh.pstate.v3.raw = 1; printf("Player %d is moving to (%d,%d)\n",id,p->pcell->x,p->pcell->y); if(!DEBUG_MAP){ flagindex = objectmap_flag_visible(p,Server_ObjectMap); if(flagindex>=0) flag = Server_ObjectMap->objects[flagindex]->obj; if(flag == FLAG1){ if(!flag1found) flag1found = 1; else flagindex = -1; } if(flag == FLAG2){ if(!flag2found) flag2found = 1; else flagindex = -1; } } } else { sh.pstate.v3.raw = 0; printf("Player %d attemped an invalid move\n",id); } sh.pstate.v0.raw = p->id; sh.pstate.v1.raw = p->pcell->x; sh.pstate.v2.raw = p->pcell->y; proto_session_hdr_marshall(s, &sh); rc = proto_session_send_msg(s,1); if(valid){ us = proto_server_event_session(); sh.type = PROTO_MT_EVENT_BASE_MOVE; proto_session_hdr_marshall(us,&sh); proto_server_post_event(); } bzero(&sh, sizeof(sh)); if(flagindex>=0){ fs = proto_server_event_session(); sh.type = PROTO_MT_EVENT_BASE_FLAG; //gstate.v0 holds the flag itself //gstate.v1 holds the index in the objectmap where that flag is located sh.gstate.v0.raw = Server_ObjectMap->objects[flagindex]->obj; sh.gstate.v1.raw = flagindex; proto_session_hdr_marshall(fs,&sh); proto_server_post_event(); } bzero(&sh, sizeof(sh)); if((winner = gamestate_team_wins()) >= 0){ sh.type = PROTO_MT_EVENT_BASE_WIN; sh.gstate.v0.raw = winner; proto_session_hdr_marshall(fs,&sh); proto_server_post_event(); } return rc; }