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; }
/** * Map-serv request to save mmo_char_status in sql * Receive character data from map-server for saving * @param fd: wich fd to parse from * @param id: wich map_serv id * @return : 0 not enough data received, 1 success */ int chmapif_parse_reqsavechar(int fd, int id){ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) return 0; { int aid = RFIFOL(fd,4), cid = RFIFOL(fd,8), size = RFIFOW(fd,2); struct online_char_data* character; DBMap* online_char_db = char_get_onlinedb(); if (size - 13 != sizeof(struct mmo_charstatus)) { ShowError("parse_from_map (save-char): Size mismatch! %d != %d\n", size-13, sizeof(struct mmo_charstatus)); RFIFOSKIP(fd,size); return 1; } //Check account only if this ain't final save. Final-save goes through because of the char-map reconnect if (RFIFOB(fd,12) || RFIFOB(fd,13) || ( (character = (struct online_char_data*)idb_get(online_char_db, aid)) != NULL && character->char_id == cid)) { struct mmo_charstatus char_dat; memcpy(&char_dat, RFIFOP(fd,13), sizeof(struct mmo_charstatus)); char_mmo_char_tosql(cid, &char_dat); } else { //This may be valid on char-server reconnection, when re-sending characters that already logged off. ShowError("parse_from_map (save-char): Received data for non-existant/offline character (%d:%d).\n", aid, cid); char_set_char_online(id, cid, aid); } if (RFIFOB(fd,12)) { //Flag, set character offline after saving. [Skotlex] char_set_char_offline(cid, aid); WFIFOHEAD(fd,10); WFIFOW(fd,0) = 0x2b21; //Save ack only needed on final save. WFIFOL(fd,2) = aid; WFIFOL(fd,6) = cid; WFIFOSET(fd,10); } RFIFOSKIP(fd,size); } return 1; }