int chlogif_parse_askkick(int fd, struct char_session_data* sd){ if (RFIFOREST(fd) < 6) return 0; else { DBMap* online_char_db = char_get_onlinedb(); DBMap* auth_db = char_get_authdb(); int aid = RFIFOL(fd,2); struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, aid); RFIFOSKIP(fd,6); if( character != NULL ) {// account is already marked as online! if( character->server > -1 ) { //Kick it from the map server it is on. mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2); if (character->waiting_disconnect == INVALID_TIMER) character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, char_chardb_waiting_disconnect, character->account_id, 0); } else {// Manual kick from char server. struct char_session_data *tsd; int i; ARR_FIND( 0, fd_max, i, session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid ); if( i < fd_max ) { chclif_send_auth_result(i,2); //Send "Someone has already logged in with this id" set_eof(i); } else // still moving to the map-server char_set_char_offline(-1, aid); } } idb_remove(auth_db, aid);// reject auth attempts from map-server } return 1; }
/** * Player requesting to change map-serv * @param fd: wich fd to parse from * @return : 0 not enough data received, 1 success */ int chmapif_parse_reqchangemapserv(int fd){ if (RFIFOREST(fd) < 39) return 0; { int map_id, map_fd = -1; struct mmo_charstatus* char_data; struct mmo_charstatus char_dat; DBMap* char_db_ = char_get_chardb(); map_id = char_search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port. if (map_id >= 0) map_fd = map_server[map_id].fd; //Char should just had been saved before this packet, so this should be safe. [Skotlex] char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14)); if (char_data == NULL) { //Really shouldn't happen. char_mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true); char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14)); } if( runflag == CHARSERVER_ST_RUNNING && session_isActive(map_fd) && char_data ) { //Send the map server the auth of this player. struct online_char_data* data; struct auth_node* node; DBMap* auth_db = char_get_authdb(); DBMap* online_char_db = char_get_onlinedb(); int aid = RFIFOL(fd,2); //Update the "last map" as this is where the player must be spawned on the new map server. char_data->last_point.map = RFIFOW(fd,18); char_data->last_point.x = RFIFOW(fd,20); char_data->last_point.y = RFIFOW(fd,22); char_data->sex = RFIFOB(fd,30); // create temporary auth entry CREATE(node, struct auth_node, 1); node->account_id = aid; node->char_id = RFIFOL(fd,14); node->login_id1 = RFIFOL(fd,6); node->login_id2 = RFIFOL(fd,10); node->sex = RFIFOB(fd,30); node->expiration_time = 0; // FIXME (this thing isn't really supported we could as well purge it instead of fixing) node->ip = ntohl(RFIFOL(fd,31)); node->group_id = RFIFOL(fd,35); node->changing_mapservers = 1; idb_put(auth_db, aid, node); data = idb_ensure(online_char_db, aid, char_create_online_data); data->char_id = char_data->char_id; data->server = map_id; //Update server where char is. //Reply with an ack. chmapif_changemapserv_ack(fd,0); } else { //Reply with nak chmapif_changemapserv_ack(fd,1); } RFIFOSKIP(fd,39); }
/** * Player Requesting char-select from map_serv * @param fd: wich fd to parse from * @return : 0 not enough data received, 1 success */ int chmapif_parse_authok(int fd){ if( RFIFOREST(fd) < 19 ) return 0; else{ uint32 account_id = RFIFOL(fd,2); uint32 login_id1 = RFIFOL(fd,6); uint32 login_id2 = RFIFOL(fd,10); uint32 ip = RFIFOL(fd,14); int version = RFIFOB(fd,18); RFIFOSKIP(fd,19); if( runflag != CHARSERVER_ST_RUNNING ){ WFIFOHEAD(fd,7); WFIFOW(fd,0) = 0x2b03; WFIFOL(fd,2) = account_id; WFIFOB(fd,6) = 0;// not ok WFIFOSET(fd,7); }else{ struct auth_node* node; DBMap* auth_db = char_get_authdb(); DBMap* online_char_db = char_get_onlinedb(); // create temporary auth entry CREATE(node, struct auth_node, 1); node->account_id = account_id; node->char_id = 0; node->login_id1 = login_id1; node->login_id2 = login_id2; //node->sex = 0; node->ip = ntohl(ip); node->version = version; //upd version for mapserv //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server) //node->gmlevel = 0; idb_put(auth_db, account_id, node); //Set char to "@ char select" in online db [Kevin] char_set_charselect(account_id); { struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, account_id); if( character != NULL ){ character->pincode_success = true; } } WFIFOHEAD(fd,7); WFIFOW(fd,0) = 0x2b03; WFIFOL(fd,2) = account_id; WFIFOB(fd,6) = 1;// ok WFIFOSET(fd,7); } } return 1; }
int chlogif_parse_ackchangesex(int fd, struct char_session_data* sd) { if (RFIFOREST(fd) < 7) return 0; else { unsigned char buf[7]; int acc = RFIFOL(fd,2); int sex = RFIFOB(fd,6); RFIFOSKIP(fd,7); if (acc > 0) { // TODO: Is this even possible? unsigned char i; int char_id = 0, class_ = 0, guild_id = 0; DBMap* auth_db = char_get_authdb(); struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc); SqlStmt *stmt; if (node != NULL) node->sex = sex; // get characters stmt = SqlStmt_Malloc(sql_handle); if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `char_id`, `class`, `guild_id` FROM `%s` WHERE `account_id` = '%d'", schema_config.char_db, acc) || SqlStmt_Execute(stmt)) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); } SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &char_id, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &class_, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 2, SQLDT_INT, &guild_id, 0, NULL, NULL); for (i = 0; i < MAX_CHARS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i) { chlogif_parse_change_sex_sub(sex, acc, char_id, class_, guild_id); } SqlStmt_Free(stmt); } // notify all mapservers about this change WBUFW(buf,0) = 0x2b0d; WBUFL(buf,2) = acc; WBUFB(buf,6) = sex; chmapif_sendall(buf, 7); } return 1; }
int chlogif_parse_ackchangesex(int fd, struct char_session_data* sd){ if (RFIFOREST(fd) < 7) return 0; { unsigned char buf[7]; int acc = RFIFOL(fd,2); int sex = RFIFOB(fd,6); RFIFOSKIP(fd,7); if( acc > 0 ) {// TODO: Is this even possible? uint32 char_id[MAX_CHARS]; int class_[MAX_CHARS]; int guild_id[MAX_CHARS]; unsigned char num, i; char* data; DBMap* auth_db = char_get_authdb(); struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc); if( node != NULL ) node->sex = sex; // get characters if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", schema_config.char_db, acc) ) Sql_ShowDebug(sql_handle); for( i = 0; i < MAX_CHARS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i ) { Sql_GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data); Sql_GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data); Sql_GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data); } num = i; for( i = 0; i < num; ++i ) { if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER || class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY || class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER || class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER || class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T || class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER || class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO ) { // job modification if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ) class_[i] = (sex ? JOB_BARD : JOB_DANCER); else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ) class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY); else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ) class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER); else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ) class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER); else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ) class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T); else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ) class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER); else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO ) class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO); } if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", schema_config.char_db, class_[i], char_id[i]) ) Sql_ShowDebug(sql_handle); if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex] inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex); } Sql_FreeResult(sql_handle); // disconnect player if online on char-server char_disconnect_player(acc); } // notify all mapservers about this change WBUFW(buf,0) = 0x2b0d; WBUFL(buf,2) = acc; WBUFB(buf,6) = sex; chmapif_sendall(buf, 7); } return 1; }