static int proto_server_mt_numfloor_handler(Proto_Session *s) { int numfloor, rc; Proto_Msg_Hdr h; if (proto_debug()) { fprintf(stderr, "proto_server_mt_numfloor_handler: invoked for session:\n"); //proto_session_dump(s); } numfloor = findNumFloor();//numfloor = 12345; // call mze.c numjail(teamNo) func if (proto_debug()) fprintf(stderr, "proto_server_mt_numfloor_handler: maze.c::func returned = %d\n", numfloor); // create replay message bzero(&h, sizeof(h)); h.type = proto_session_hdr_unmarshall_type(s); h.type += PROTO_MT_REP_BASE_RESERVED_FIRST; proto_session_hdr_marshall(s, &h); if (proto_session_body_marshall_int(s, numfloor) < 0 ) fprintf(stderr, "proto_server_mt_numfloor_handler: " "proto_session_body_marshall_bytes failed\n"); rc = proto_session_send_msg(s, 1); // TODO: return failed if an error occours return rc; }
static int proto_server_mt_leave_game_handler(Proto_Session *s) { Proto_Msg_Hdr h; int rc; int dummy_reply = 1; if (proto_debug()) fprintf(stderr, "proto_server_mt_leave_game_handler: invoked for session:\n"); //proto_session_dump(s); // Call game logic: remove player from game // TODO: update game version if necesary // pthread_mutex_lock(&server_data_mutex); // pthread_mutex_unlock(&server_data_mutex); if (proto_debug()) fprintf(stderr, "proto_server_mt_leave_game_handler: remove player reply:%d\n", 1); bzero(&h, sizeof(h)); h.type = proto_session_hdr_unmarshall_type(s); h.type += PROTO_MT_REP_BASE_RESERVED_FIRST; h.sver.raw = server_gameData.version; h.gstate.v0.raw = server_gameData.state; proto_session_hdr_marshall(s, &h); proto_session_body_marshall_int(s, dummy_reply); rc = proto_session_send_msg(s, 1); // TODO: update subscribers // doUpdateClientsGame(0); return rc; }
// Assigment 3 rpc static int do_numhome_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt, int data) { int rc; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr h; if (proto_debug()) fprintf(stderr, "do_numhome_rpc (team = %d)\n", data); s = &(c->rpc_session); bzero(&h, sizeof(h)); h.type = mt; proto_session_hdr_marshall(s, &h); if (proto_session_body_marshall_int(s, data) < 0) fprintf(stderr, "get_numHome_rpc: proto_session_body_marshall_char failed. " "Not enough available sbufer space\n"); rc = proto_session_rpc(s); if (rc == 1) { if(proto_session_body_unmarshall_int(s, 0, &rc) < 0) fprintf(stderr, "do_numhome_rpc: proto_session_body_unmarshall_bytes failed\n"); if (proto_debug()) fprintf(stderr, "do_numhome_rpc: unmarshalled response rc = %d \n", rc); } else { c->session_lost_handler(s); close(s->fd); } return rc; }
static int do_numwall_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_numwall_rpc\n"); s = &(c->rpc_session); bzero(&h, sizeof(h)); h.type = mt; proto_session_hdr_marshall(s, &h); rc = proto_session_rpc(s); if (rc == 1) { if(proto_session_body_unmarshall_int(s, 0, &rc) < 0) fprintf(stderr, "get_numwall_rpc: proto_session_body_unmarshall_bytes failed\n"); if (proto_debug()) fprintf(stderr, "do_numwall_rpc: unmarshalled response rc = %d \n", rc); } else { c->session_lost_handler(s); close(s->fd); } return rc; }
static int proto_server_mt_numhome_handler(Proto_Session *s) { int numhome, rc, teamNo; Proto_Msg_Hdr h; if (proto_debug()) { fprintf(stderr, "proto_server_mt_move_handler: invoked for session:\n"); //proto_session_dump(s); } proto_session_body_unmarshall_int(s, 0, &teamNo); if (proto_debug()) fprintf(stderr, "proto_server_mt_numhome_handler: requested teamNo = %d\n", teamNo); numhome = findNumHome(teamNo); //numhome = 5; //pthread_mutex_lock(&game_mutex); //pthread_mutex_unlock(&game_mutex); if (proto_debug()) fprintf(stderr, "proto_server_mt_numhome_handler: maze.c func returned = %d\n", numhome); // create replay message bzero(&h, sizeof(h)); h.type = proto_session_hdr_unmarshall_type(s); h.type += PROTO_MT_REP_BASE_RESERVED_FIRST; proto_session_hdr_marshall(s, &h); if (proto_session_body_marshall_int(s, numhome) < 0 ) fprintf(stderr, "proto_server_mt_numhome_handler: " "proto_session_body_marshall_bytes failed\n"); rc = proto_session_send_msg(s, 1); // TODO: return failed if an error occours return rc; }
static int do_cinfo_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt, int x, int y) { int rc; char cell, team, occupied; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr h; s = &(c->rpc_session); bzero(&h, sizeof(h)); h.type = mt; proto_session_hdr_marshall(s, &h); if (proto_debug()) fprintf(stderr, "do_cinfo_rpc: cinfo(%d, %d) \n", x, y); if (proto_session_body_marshall_int(s, x) < 0) fprintf(stderr, "do_cinfo_rpc: proto_session_body_marshall_char failed. " "Not enough available sbufer space\n"); if (proto_session_body_marshall_int(s, y) < 0) fprintf(stderr, "do_cinfo_rpc: proto_session_body_marshall_char failed. " "Not enough available sbufer space\n"); rc = proto_session_rpc(s); if (rc == 1) { // unmarshall if (proto_session_body_unmarshall_char(s, 0, &cell) < 0) fprintf(stderr, "do_cinfo_rpc: proto_session_body_unmarshall_bytes failed\n"); if (proto_session_body_unmarshall_char(s, 1, &team) < 0) fprintf(stderr, "do_cinfo_rpc: proto_session_body_unmarshall_bytes failed\n"); if (proto_session_body_unmarshall_char(s, 2, &occupied) < 0) fprintf(stderr, "do_cinfo_rpc: proto_session_body_unmarshall_bytes failed\n"); if (proto_debug()) fprintf(stderr, "do_cinfo_rpc: unmarshalled response cell = %X, %c \n", cell & 0xFF, cell); if (proto_debug()) fprintf(stderr, "do_cinfo_rpc: unmarshalled response team = %X, %c \n", team & 0xFF, team); if (proto_debug()) fprintf(stderr, "do_cinfo_rpc: unmarshalled response occupied = %X, %c \n", occupied & 0xFF, occupied); rc = 0; rc =((cell & 0xFF)<<8) | ((team & 0xFF)<<16) | ((occupied & 0xFF)<<24); if (proto_debug()) fprintf(stderr, "do_cinfo_rpc: return value = %X \n", rc); } else { c->session_lost_handler(s); close(s->fd); } 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 proto_server_mt_cinfo_handler(Proto_Session *s) { int in_x, in_y, rc; char cell, team, occupied; Proto_Msg_Hdr h; if (proto_debug()) { fprintf(stderr, "proto_server_mt_cinfo_handler: invoked for session:\n"); //proto_session_dump(s); } // read msg here proto_session_body_unmarshall_int(s, 0, &in_x); proto_session_body_unmarshall_int(s, sizeof(int), &in_y); if (proto_debug()) fprintf(stderr, "proto_server_mt_numjail_handler: requested cellinfo( %d, %d )\n", in_x, in_y); //cell = '#';//cell = (char)0xCC; // call mze.c numjail(teamNo) func //team = '1';//team = (char)0xDD; //occupied = 'Y';//occupied = (char)0xEE; cell = get_cell_type( in_x, in_y ); team = get_cell_team( in_x, in_y ); occupied = is_cell_occupied( in_x, in_y ); //findCInfo(in_x, in_y); if (proto_debug()) fprintf(stderr, "proto_server_mt_numjail_handler: maze.c::func returned\n" " cell='%c', team='%c', occupied='%c'\n", cell, team, occupied); // create replay message bzero(&h, sizeof(h)); h.type = proto_session_hdr_unmarshall_type(s); h.type += PROTO_MT_REP_BASE_RESERVED_FIRST; proto_session_hdr_marshall(s, &h); if (proto_session_body_marshall_char(s, cell) < 0 ) fprintf(stderr, "proto_server_mt_cinfo_handler: " "proto_session_body_marshall_bytes failed\n"); if (proto_session_body_marshall_char(s, team) < 0 ) fprintf(stderr, "proto_server_mt_cinfo_handler: " "proto_session_body_marshall_bytes failed\n"); if (proto_session_body_marshall_char(s, occupied) < 0 ) fprintf(stderr, "proto_server_mt_cinfo_handler: " "proto_session_body_marshall_bytes failed\n"); rc = proto_session_send_msg(s, 1); // TODO: return failed if an error occours return rc; }
/* * This is a callback for security_connect. After the security layer * has initiated a connection to the given host, this will be called * with a security_handle_t. * * On error, the security_status_t arg will reflect errors which can * be had via security_geterror on the handle. */ static void connect_callback( void *cookie) { proto_t *p = cookie; assert(p != NULL); if (p->event_handle) { event_release(p->event_handle); p->event_handle = 0; } proto_debug(1, _("protocol: connect_callback: p %p\n"), p); switch (p->status) { case S_OK: state_machine(p, PA_START, NULL); break; case S_TIMEOUT: security_seterror(p->security_handle, _("timeout during connect")); /* FALLTHROUGH */ case S_ERROR: /* * For timeouts or errors, retry a few times, waiting CONNECT_WAIT * seconds between each attempt. If they all fail, just return * an error back to the caller. */ if (--p->connecttries == 0) { state_machine(p, PA_ABORT, NULL); } else { proto_debug(1, _("protocol: connect_callback: p %p: retrying %s\n"), p, p->hostname); security_close(p->security_handle); /* XXX overload p->security handle to hold the event handle */ p->security_handle = (security_handle_t *)event_create(CONNECT_WAIT, EV_TIME, connect_wait_callback, p); event_activate((event_handle_t *) p->security_handle); } break; default: assert(0); break; } }
// Broadcasts changes in the game to Subscribers int doUpdateClientsGame(int updateMapVersion) { Proto_Session *s; Proto_Msg_Hdr hdr; if (proto_debug()) fprintf(stderr, "doUpdateClientsGame called\n"); bzero(&hdr, sizeof(hdr)); s = proto_server_event_session(); // set sver if nescesary hdr.type = PROTO_MT_EVENT_BASE_UPDATE; // pthread_spin_lock(&server_data_spinlock); hdr.sver.raw = server_gameData.version; hdr.gstate.v0.raw = server_gameData.state; // pthread_spin_unlock(&server_data_spinlock); proto_session_hdr_marshall(s, &hdr); // test proto_server_test_msg(s); proto_server_post_event(); return 1; }
static int proto_server_mt_dump_handler(Proto_Session *s) { int rc; Proto_Msg_Hdr h; if (proto_debug()) { fprintf(stderr, "proto_server_mt_dump_handler: invoked for session:\n"); //proto_session_dump(s); } dumpMap(); // create replay message bzero(&h, sizeof(h)); h.type = proto_session_hdr_unmarshall_type(s); h.type += PROTO_MT_REP_BASE_RESERVED_FIRST; proto_session_hdr_marshall(s, &h); rc = 1; if (proto_session_body_marshall_int(s, rc) < 0 ) fprintf(stderr, "proto_server_mt_dump_handler: " "proto_session_body_marshall_bytes failed\n"); rc = proto_session_send_msg(s, 1); // TODO: return failed if an error occours return rc; }
static int do_dump_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt) { int rc; Proto_Session *s; Proto_Client *c = ch; if (proto_debug()) fprintf(stderr, "do_dump_rpc \n"); s = &(c->rpc_session); marshall_mtonly(s, mt); rc = proto_session_rpc(s); if (rc == 1) { proto_session_body_unmarshall_int(s, 0, &rc); } else { c->session_lost_handler(s); close(s->fd); } return rc; }
extern int proto_session_rcv_msg(Proto_Session *s) { proto_session_reset_receive(s); int ret = net_readn(s->fd, &(s->rhdr), sizeof(Proto_Msg_Hdr)); if (ret == -1) { return -1; } int newblen = ntohl(s->rhdr.blen); printf("newblen = %d\n", newblen); if (newblen != 0) { if (net_readn(s->fd, &(s->rbuf), newblen) == -1) { printf("Failed to read from buffer.\n"); return -1; } s->rlen = newblen; } proto_session_dump(s); if (proto_debug()) { fprintf(stderr, "%p: proto_session_rcv_msg: RCVED:\n", pthread_self()); proto_session_dump(s); } return 1; }
/* update_walls Takes game compress array and decompresses each element and adds broken wall information to the Maze. parameter: num_elements the number of elements in the player compress array parameter: game_compress pointer to the array that contains game compresses parameter: maze pointer to client version of the maze return: void */ void update_walls(int num_elements,int* game_compress, Maze* maze, PixelUpdate *pu) { Pos pos; int ii,x,y; for(ii = 0; ii < num_elements; ii++) { if(!decompress_is_ignoreable(&game_compress[ii])) { decompress_broken_wall(&pos,&game_compress[ii]); x = pos.x; y = pos.y; maze->get[x][y].type = CELL_FLOOR; pu->older.x = x; pu->older.y = y; pu->newer.x = x; pu->newer.y = y; pu->valid =1; if(proto_debug()) { fprintf(stderr,"Broken Wall Update x:%d y:%d\n",x,y); } } } }
// rc < 0 on comm failures // rc == 1 indicates comm success extern int proto_session_send_msg(Proto_Session *s, int reset) { s->shdr.blen = htonl(s->slen); // write request if (net_writen(s->fd, &(s->shdr), sizeof(s->shdr)) != sizeof(s->shdr)) return -1; if (s->slen) { if (net_writen(s->fd, s->sbuf, s->slen) != s->slen) { return -2; } } if (proto_debug()) { fprintf(stderr, "%p: proto_session_send_msg: SENT:\n", pthread_self()); proto_session_dump(s); } // communication was successfull if (reset) proto_session_reset_send(s); 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 proto_server_mt_item_action_handler(Proto_Session *s) { int rc, player_id; char item, action; int dummy_reply = 1; Proto_Msg_Hdr h; if (proto_debug()) fprintf(stderr, "proto_server_mt_item_action_handler: invoked for session:\n"); // proto_session_dump(s); // Read rpc message: pID, item, action proto_session_body_unmarshall_int(s, 0, &player_id); proto_session_body_unmarshall_char(s, sizeof(int), &item); proto_session_body_unmarshall_char(s, sizeof(int)+sizeof(char), &action); if (proto_debug()) fprintf(stderr, "proto_server_mt_move_handler: Recieved:\n" " pId: %d\n item #%c#\n action #%c#\n", player_id, item, action); // TODO: call game logic // TODO: update game version if necesary // pthread_mutex_lock(&server_data_mutex); // pthread_mutex_unlock(&server_data_mutex); if (proto_debug()) fprintf(stderr, "proto_server_mt_move_handler: Send: game logic_reply: %d\n", dummy_reply); // rpc reply bzero(&h, sizeof(h)); h.type = proto_session_hdr_unmarshall_type(s); h.type += PROTO_MT_REP_BASE_RESERVED_FIRST; h.sver.raw = server_gameData.version; h.gstate.v0.raw = server_gameData.state; proto_session_hdr_marshall(s, &h); proto_session_body_marshall_int(s, dummy_reply); rc = proto_session_send_msg(s, 1); // TODO: update subscribers // doUpdateClientsGame(0); return rc; }
static int do_dim_rpc(Proto_Client_Handle ch, Proto_Msg_Types mt) { int rc, x, y; Proto_Session *s; Proto_Client *c = ch; Proto_Msg_Hdr h; if (proto_debug()) fprintf(stderr, "do_dim_rpc\n"); s = &(c->rpc_session); bzero(&h, sizeof(h)); h.type = mt; proto_session_hdr_marshall(s, &h); rc = proto_session_rpc(s); if (rc == 1) { if (proto_session_body_unmarshall_int(s, 0, &x) < 0) fprintf(stderr, "do_dim_rpc: proto_session_body_unmarshall_bytes failed\n"); if (proto_session_body_unmarshall_int(s, sizeof(int), &y) < 0) fprintf(stderr, "do_dim_rpc: proto_session_body_unmarshall_bytes failed\n"); if (proto_debug()) fprintf(stderr, "do_dim_rpc: unmarshalled response x = %X \n", x); if (proto_debug()) fprintf(stderr, "do_dim_rpc: unmarshalled response y = %X \n", y); rc = (x << 16) | y; if (proto_debug()) fprintf(stderr, "do_dim_rpc: return value = %X \n", rc); } else { c->session_lost_handler(s); close(s->fd); } return rc; }
/* doRPCCmd Based on the request type (set by one of the init function) send an RPC to the server parameter: request pointer to request data structure that was already initialized return: int 1 or -1 for success or failure respectively */ int doRPCCmd(Request* request) { int rc=-1; long double clk = tick(); // Unpack the request Client *C; Proto_Msg_Hdr hdr; bzero(&hdr,sizeof(Proto_Msg_Hdr)); C = request->client; switch (request->type) { case PROTO_MT_REQ_HELLO: if(proto_debug()) fprintf(stderr,"HELLO COMMAND ISSUED"); hdr.type = request->type; rc = do_no_body_rpc(C->ph,&hdr); if (proto_debug()) fprintf(stderr,"hello: rc=%x\n", rc); if (rc < 0) fprintf(stderr, "Unable to connect"); break; case PROTO_MT_REQ_ACTION: if(proto_debug()) fprintf(stderr,"Action COMMAND ISSUED"); hdr.type = request->type; hdr.gstate.v1.raw = request->action_type; hdr.pstate.v1.raw = request->team; hdr.pstate.v0.raw = C->my_player->id; rc = do_action_request_rpc(C->ph,&hdr,request->current,request->next); break; case PROTO_MT_REQ_SYNC: if (proto_debug() ) fprintf(stderr,"Sync COMMAND ISSUED"); hdr.type = request->type; rc = do_no_body_rpc(C->ph,&hdr); break; case PROTO_MT_REQ_GOODBYE: if (proto_debug() ) fprintf(stderr,"Goodbye COMMAND ISSUED"); hdr.type = request->type; rc = do_no_body_rpc(C->ph,&hdr); /*rc = proto_client_goodbye(C->ph);*/ /*printf("Game Over - You Quit");*/ break; default: fprintf(stderr,"%s: unknown command %d\n", __func__, request->type); } c_log(request->type,request->action_type,rc,clk); // NULL MT OVERRIDE ;-) if(proto_debug()) fprintf(stderr,"%s: rc=0x%x\n", __func__, rc); if (rc == 0xdeadbeef) rc=1; if (proto_debug()) printf("rc=1\n"); return rc; }
static int proto_server_mt_join_game_handler(Proto_Session *s) { int rc, player, dimy, dimx; Proto_Msg_Hdr h; player = 1; char dummy_maze[] = {'1','2','3','4','5','6','7','8','9'}; if (proto_debug()) fprintf(stderr, "proto_server_mt_join_game_handler: invoked for session:\n"); //proto_session_dump(s); // prepare reply message bzero(&h, sizeof(s)); h.type = proto_session_hdr_unmarshall_type(s); h.type += PROTO_MT_REP_BASE_RESERVED_FIRST; // send to client the current state and version h.sver.raw = server_gameData.version; h.gstate.v0.raw = server_gameData.state; proto_session_hdr_marshall(s, &h); // TODO: call game logic dimx = 3;//dimx = get_maze_dimx(); dimy = 3;//dimy = get_maze_dimy(); // TODO: update game version and state if necesary // pthread_mutex_lock(&server_data_mutex); // pthread_mutex_unlock(&server_data_mutex); // relpy: pID, xdim, ydim, maze if (proto_session_body_marshall_int(s, player) < 0) fprintf(stderr, "proto_server_mt_join_game_handler: " "proto_session_body_marshall_int failed\n"); if (proto_session_body_marshall_int(s, dimx) < 0 ) fprintf(stderr, "proto_server_mt_join_game_handler: " "proto_session_body_marshall_int failed\n"); if (proto_session_body_marshall_int(s, dimy) < 0 ) fprintf(stderr, "proto_server_mt_join_game_handler: " "proto_session_body_marshall_int failed\n"); if (proto_session_body_marshall_bytes(s, dimx*dimy, &dummy_maze[0]) < 0) fprintf(stderr, "proto_server_mt_join_game_handler: " "proto_session_body_marshall_bytes failed\n"); rc = proto_session_send_msg(s,1); // TODO: update subscribers doUpdateClientsGame(0); return rc; }
//Assuming that the calling function is responsible for unmarshalling //session passed to us is empty, need to fill it out, return < 0 when //nothing read/to read extern int proto_session_rcv_msg(Proto_Session *s){ proto_session_reset_receive(s); if(net_readn(s->fd, &(s->rhdr), sizeof(Proto_Msg_Hdr)) < 0) return -1; net_readn(s->fd, s->rbuf, ntohl(s->rhdr.blen)); if (proto_debug()){ fprintf(stderr, "%p: proto_session_rcv_msg: RCVED:\n", pthread_self()); proto_session_dump(s); } return 1; }
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 proto_server_mt_dim_handler(Proto_Session *s) { int dimx, dimy, rc; Proto_Msg_Hdr h; if (proto_debug()) { fprintf(stderr, "proto_server_mt_dim_handler: invoked for session:\n"); //proto_session_dump(s); } //dimx = 1;//dimx = 0x0000AAAA; // call mze.c numjail(teamNo) func //dimy = 2;//dimy = 0x0000BBBB; // call mze.c numjail(teamNo) func dimx = get_maze_dimx(); dimy = get_maze_dimy(); if (proto_debug()) fprintf(stderr, "proto_server_mt_dim_handler: maze.c::func returned x=%d, y=%d\n", dimx, dimy); // create replay message bzero(&h, sizeof(h)); h.type = proto_session_hdr_unmarshall_type(s); h.type += PROTO_MT_REP_BASE_RESERVED_FIRST; proto_session_hdr_marshall(s, &h); if (proto_session_body_marshall_int(s, dimx) < 0 ) fprintf(stderr, "proto_server_mt_dim_handler: " "proto_session_body_marshall_bytes failed\n"); if (proto_session_body_marshall_int(s, dimy) < 0 ) fprintf(stderr, "proto_server_mt_dim_handler: " "proto_session_body_marshall_bytes failed\n"); rc = proto_session_send_msg(s, 1); // TODO: return failed if an error occours return rc; }
extern int proto_session_rcv_msg(Proto_Session *s) { proto_session_reset_receive(s); // read reply ADD CODE if (proto_debug()) { fprintf(stderr, "%p: proto_session_rcv_msg: RCVED:\n", pthread_self()); proto_session_dump(s); } return 1; }
// rc < 0 on comm failures // rc == 1 indicates comm success // session passed to us contains header and body information, // need to send that information to fd extern int proto_session_send_msg(Proto_Session *s, int reset){ s->shdr.blen = htonl(s->slen); if(net_writen(s->fd, &(s->shdr), sizeof(Proto_Msg_Hdr)) < 0) return -1; net_writen(s->fd, s->sbuf, s->slen); if (proto_debug()) { fprintf(stderr, "%p: proto_session_send_msg: SENT:\n", pthread_self()); proto_session_dump(s); } if (reset) proto_session_reset_send(s); return 1; }
extern int proto_session_rcv_msg(Proto_Session *s) { proto_session_reset_receive(s); // read reply ////////// ADD CODE ////////// if (PROTO_PRINT_DUMPS==1) fprintf(stderr, "Waiting to receive message\n"); int bytesRead = net_readn(s->fd, &s->rhdr, sizeof(Proto_Msg_Hdr)); // Read the reply header from received message if (PROTO_PRINT_DUMPS==1) fprintf(stderr, "Received %d bytes\n", bytesRead); // Make sure we read the # of bytes we expect if (bytesRead<(int)sizeof(Proto_Msg_Hdr)) { fprintf(stderr, "%s: ERROR failed to read len: %d!=%d" " ... closing connection\n", __func__, bytesRead, (int)sizeof(Proto_Msg_Hdr)); close(s->fd); return -1; } // Get the number of extra bytes in the blen field proto_session_hdr_unmarshall_blen(s); if (PROTO_PRINT_DUMPS==1) fprintf(stderr, "Number of bytes read: %d extraBytes=%d\n", bytesRead, s-> rhdr.blen); // Now read the read into the reply buffer bytesRead = net_readn(s->fd, &s->rbuf, s->rhdr.blen); if ( bytesRead != s->rhdr.blen) { fprintf(stderr, "%s: ERROR failed to read msg: %d!=%d" " .. closing connection\n" , __func__, bytesRead, s->rhdr.blen); close(s->fd); return -1; } ///////////////////// if (proto_debug()) { if(PROTO_PRINT_DUMPS==1) fprintf(stderr, "%p: proto_session_rcv_msg: RCVED:\n", pthread_self()); proto_session_dump(s); } if (PROTO_PRINT_DUMPS==1) fprintf(stderr, "Successfully received message\n" ); return 1; }
extern int proto_session_rcv_msg(Proto_Session *s) { proto_session_reset_receive(s); // read reply // ADD CODE s->rhdr.blen = sizeof (s->sbuf); s->rlen = sizeof (s->rhdr); net_readn(s->fd, &(s->rhdr), s->rlen); net_readn(s->fd, &(s->rbuf), s->rhdr.blen); if (proto_debug()) { fprintf(stderr, "%p: proto_session_rcv_msg: RCVED:\n", pthread_self()); proto_session_dump(s); } return 1; }
// rc < 0 on comm failures // rc == 1 indicates comm success extern int proto_session_send_msg(Proto_Session *s, int reset) { s->shdr.blen = htonl(s->slen); // write request ADD CODE if (proto_debug()) { fprintf(stderr, "%p: proto_session_send_msg: SENT:\n", pthread_self()); proto_session_dump(s); } // communication was successfull if (reset) proto_session_reset_send(s); return 1; }
// rc < 0 on comm failures // rc == 1 indicates comm success extern int proto_session_send_msg(Proto_Session *s, int reset) { s->shdr.blen = htonl(s->slen); // write request // ADD CODE net_writen(s->fd, &s->shdr, (int)sizeof(Proto_Msg_Hdr)); if (s->slen>0) { net_writen(s->fd, &s->sbuf, (int)s->slen); if (PROTO_PRINT_DUMPS==1) fprintf(stderr, "Sending extra bytes: %d\n", s->slen); } if (proto_debug()) { fprintf(stderr, "%p: proto_session_send_msg: SENT:\n", pthread_self()); proto_session_dump(s); } if (PROTO_PRINT_DUMPS==1) fprintf(stderr, "Sent message...\n"); // //////////// // struct sockaddr_in sinadd; // socklen_t len = sizeof(sinadd); // if (getsockname(s->fd, (struct sockaddr *)&sinadd, &len) == -1) // perror("getsockname"); // else // printf("port number %d\n", ntohs(sinadd.sin_port)); // char hostname[128]; // gethostname(hostname, sizeof hostname); // printf("My hostname: %s\n", hostname); // //////////// // communication was successfull if (reset) proto_session_reset_send(s); return 1; }