static void do_set_pos(context_t * ctx,const char * map, int x, int y, bool change_map) { context_set_map(ctx,map); context_set_pos_tx(ctx,x); context_set_pos_ty(ctx,y); entry_write_string(CHARACTER_TABLE,ctx->id,map,CHARACTER_KEY_MAP,NULL); entry_write_int(CHARACTER_TABLE,ctx->id,x,CHARACTER_KEY_POS_X,NULL); entry_write_int(CHARACTER_TABLE,ctx->id,y,CHARACTER_KEY_POS_Y,NULL); context_spread(ctx); if( change_map == true ) { context_request_other_context(ctx); } }
/***************************** Kick a character out of the game It does not disconnect it. An NPC could re pop from an out of game state. A player can go back in game after choosing a new character id return -1 if fails *****************************/ int character_out_of_game( const char * id) { context_t * ctx; werr(LOGDEBUG,"Kicking %s out of the game",id); ctx = context_find(id); context_set_in_game(ctx,false); context_spread(ctx); if( context_is_npc(ctx) == true ) { /* Wake up NPC */ if( SDL_TryLockMutex (ctx->cond_mutex) == 0 ) { SDL_CondSignal (ctx->cond); SDL_UnlockMutex (ctx->cond_mutex); } } return 0; }
/***************************** Disconnect a character. This kill a NPC AI thread return -1 if fails *****************************/ int character_disconnect(const char * id) { context_t * ctx; werr(LOGDEVELOPER, "Disconnecting %s", id); ctx = context_find(id); context_set_in_game(ctx, false); context_set_connected(ctx, false); context_spread(ctx); if (context_is_npc(ctx) == true) { /* Wake up NPC */ if (SDL_TryLockMutex(ctx->cond_mutex) == 0) { SDL_CondSignal(ctx->cond); SDL_UnlockMutex(ctx->cond_mutex); } } return 0; }
/************************************** Return RET_NOK on error **************************************/ ret_code_t parse_incoming_data(context_t * context, Uint32 command, Uint32 command_size, char * data) { char * value = NULL; char * fullname; char * elements[512]; char * cksum; int i; char * user_name; char * password; if( !context_get_connected(context) && ( command != CMD_REQ_LOGIN && command != CMD_REQ_FILE) ) { werr(LOGUSER,"Request from not authenticated client, close connection"); return RET_NOK; } switch(command) { case CMD_REQ_LOGIN: wlog(LOGDEBUG,"Received CMD_REQ_LOGIN"); user_name = _strsep(&data,NETWORK_DELIMITER); password = _strsep(&data,NETWORK_DELIMITER); if(entry_read_string(PASSWD_TABLE, user_name, &value, PASSWD_KEY_PASSWORD,NULL) == RET_NOK) { return RET_NOK; } if( strcmp(value, password) != 0) { free(value); werr(LOGUSER,"Wrong login for %s",user_name); // send answer network_send_command(context, CMD_SEND_LOGIN_NOK, 0, NULL, false); // force client disconnection return RET_NOK; } else { free(value); if( context_set_username(context, user_name) == RET_NOK ) { return RET_NOK; } context_set_connected(context, true); // send answer network_send_command(context, CMD_SEND_LOGIN_OK, 0, NULL, false); wlog(LOGUSER,"Login successful for user %s",context->user_name); } break; case CMD_REQ_CHARACTER_LIST : wlog(LOGDEBUG,"Received CMD_REQ_CHARACTER_LIST"); character_send_list(context); wlog(LOGDEBUG,"character list sent"); break; case CMD_REQ_FILE : i = 0; elements[i] = _strsep(&data,NETWORK_DELIMITER); while(elements[i]) { i++; elements[i] = _strsep(&data,NETWORK_DELIMITER); } if(elements[0]==NULL || elements[1]==NULL) { werr(LOGDEV,"Received erroneous CMD_REQ_FILE"); break; } wlog(LOGDEBUG,"Received CMD_REQ_FILE for %s",elements[0]); /* compare checksum */ fullname = strconcat(base_directory,"/",elements[0],NULL); cksum = checksum_file(fullname); free(fullname); if( cksum == NULL) { werr(LOGUSER,"Required file %s doesn't exists",elements[0]); break; } if( strcmp(elements[1],cksum) == 0 ) { wlog(LOGDEBUG,"Client has already newest %s file",elements[0]); free(cksum); break; } free(cksum); network_send_file(context,elements[0]); wlog(LOGDEBUG,"File %s sent",elements[0]); break; case CMD_REQ_USER_CHARACTER_LIST : wlog(LOGDEBUG,"Received CMD_REQ_USER_CHARACTER_LIST"); character_user_send_list(context); wlog(LOGDEBUG,"user %s's character list sent",context->user_name); break; case CMD_REQ_START : if( context->in_game == false ) { context->id = strdup(data); context->in_game = true; context_update_from_file(context); context_spread(context); context_request_other_context(context); } wlog(LOGDEBUG,"Received CMD_REQ_START for %s /%s",context->user_name,context->id); break; case CMD_REQ_STOP : wlog(LOGDEBUG,"Received CMD_REQ_STOP for %s /%s",context->user_name,context->id); if( context->in_game == true ) { context->in_game = false; if( context->map ) { free(context->map); } context->map = NULL; if( context->prev_map ) { free(context->prev_map); } context->prev_map = NULL; if( context->id ) { free(context->id); } context->id = NULL; context_spread(context); } break; case CMD_REQ_ACTION : i = 0; elements[i] = NULL; elements[i] = _strsep(&data,NETWORK_DELIMITER); while(elements[i]) { i++; elements[i] = _strsep(&data,NETWORK_DELIMITER); } elements[i+1] = NULL; wlog(LOGDEBUG,"Received CMD_REQ_ACTION %s from %s /%s",elements[0],context->user_name,context->character_name); action_execute(context,elements[0],&elements[1]); break; default: werr(LOGDEV,"Unknown request %d from client",command); return RET_NOK; } return RET_OK; }