/********************************************************************* Player sends an action to server *********************************************************************/ void network_send_action(context_t * context, const char * script, ...) { va_list ap; char * parameter = nullptr; if (script == nullptr) { return; } NetworkFrame l_Frame; l_Frame.push(script); std::vector<std::string> l_Param; va_start(ap, script); while ((parameter = va_arg(ap, char*)) != nullptr) { l_Param.push_back(parameter); } va_end(ap); l_Frame.push(l_Param); wlog(LOGDEVELOPER, "Send CMD_REQ_ACTION :%s", l_Frame.getFrame()); network_send_command(context, CMD_REQ_ACTION, l_Frame, false); }
void network_request_start(context_t * p_pContext, const char * p_pId) { NetworkFrame l_Frame; l_Frame.push(p_pId); wlog(LOGDEVELOPER, "Send CMD_REQ_START"); network_send_command(p_pContext, CMD_REQ_START, l_Frame, false); }
/********************************************************************* request a specific user's characters list *********************************************************************/ void network_request_user_character_list(context_t * context) { wlog(LOGDEVELOPER, "Send CMD_REQ_USER_CHARACTER_LIST"); NetworkFrame l_Frame; l_Frame.push(context->user_name); network_send_command(context, CMD_REQ_USER_CHARACTER_LIST, l_Frame, false); }
/********************************************************************* request a character's creation *********************************************************************/ void network_request_character_creation(context_t * context, const char * id, const char * name) { NetworkFrame l_Frame; l_Frame.push(id); l_Frame.push(name); wlog(LOGDEVELOPER, "Send CMD_REQ_CREATE"); network_send_command(context, CMD_REQ_CREATE, l_Frame, false); }
/********************************************************************* sends a login request, the answer is asynchronously read by async_recv **********************************************************************/ void network_login(context_t * context, const char * user_name, const char * password) { NetworkFrame l_Frame; l_Frame.push(user_name); l_Frame.push(password); wlog(LOGDEVELOPER, "Send CMD_REQ_LOGIN"); network_send_command(context, CMD_REQ_LOGIN, l_Frame, false); }
/********************************************* Send playable character templates *********************************************/ void character_send_list(context_t * context) { //TODO #if 0 char ** character_list; int i = 0; if(entry_read_list(USERS_TABLE, context->user_name,&character_list,USERS_CHARACTER_LIST,NULL) == RET_NOK) { return; } while( character_list[i] != NULL ) { network_send_command(context, CMD_SEND_CHARACTER, strlen(character_list[i])+1, character_list[i],false); i++; } deep_free(character_list); #endif }
/************************************** 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; }
/********************************************* Send playable character templates *********************************************/ void character_playable_send_list(context_t * context) { char * marquee; DIR * dir; char * dirname; struct dirent * ent; // Read all files in character template directory dirname = strconcat(base_directory, "/", CHARACTER_TEMPLATE_TABLE, nullptr); dir = opendir(dirname); if (dir == nullptr) { return; } free(dirname); std::vector<std::string> l_Array; while ((ent = readdir(dir)) != nullptr) { // skip hidden file if (ent->d_name[0] == '.') { continue; } if (entry_read_string(CHARACTER_TEMPLATE_TABLE, ent->d_name, &marquee, CHARACTER_KEY_MARQUEE, nullptr) == RET_OK) { if (marquee[0] == '\0') { free(marquee); continue; } free(marquee); } else { char ** marquee_list = nullptr; if (entry_read_list(CHARACTER_TEMPLATE_TABLE, ent->d_name, &marquee_list, CHARACTER_KEY_MARQUEE, nullptr) == RET_NOK) { wlog(LOGDESIGNER, "%s has no marquee", ent->d_name); continue; } if (marquee_list[0][0] == '\0') { deep_free(marquee_list); continue; } deep_free(marquee_list); } // add file name to network frame l_Array.push_back(std::string(ent->d_name)); } closedir(dir); NetworkFrame l_Frame; l_Frame.push(l_Array); network_send_command(context, CMD_SEND_PLAYABLE_CHARACTER, l_Frame, false); }
void character_user_send_list(context_t * context) { char * data = NULL; Uint32 data_size = 0; Uint32 string_size = 0; char ** character_list; char * type; char * name; int i; if(entry_read_list(USERS_TABLE, context->user_name,&character_list,USERS_CHARACTER_LIST,NULL) == RET_NOK ) { return; } i = 0; data = strdup(""); while( character_list[i] != NULL ) { if(entry_read_string(CHARACTER_TABLE, character_list[i], &type, CHARACTER_KEY_TYPE,NULL) == RET_NOK ) { i++; continue; } if(entry_read_string(CHARACTER_TABLE, character_list[i], &name, CHARACTER_KEY_NAME,NULL) == RET_NOK ) { free(type); i++; continue; } // add the name of the character to the network frame string_size = strlen(character_list[i])+1; data = (char*)realloc(data, data_size + string_size); memcpy(data+data_size,character_list[i], string_size); data_size += string_size; // add the type of the character to the network frame string_size = strlen(type)+1; data = (char*)realloc(data, data_size + string_size); memcpy(data+data_size,type, string_size); data_size += string_size; // add the type of the character to the network frame string_size = strlen(name)+1; data = (char*)realloc(data, data_size + string_size); memcpy(data+data_size,name, string_size); data_size += string_size; free(type); free(name); i++; } deep_free(character_list); // Mark the end of the list data = (char*)realloc(data, data_size + 1); data[data_size] = 0; data_size ++; network_send_command(context, CMD_SEND_USER_CHARACTER, data_size, data,false); free(data); }