//Disconnect the player out of the game, simple packet //packet.w AID.L WHY.B 2+4+1 = 7byte int chrif_disconnectplayer(int fd) { struct map_session_data* sd; int account_id = RFIFOL(fd, 2); sd = map_id2sd(account_id); if( sd == NULL ) { struct auth_node* auth = chrif_search(account_id); if( auth != NULL && chrif_auth_delete(account_id, auth->char_id, ST_LOGIN) ) return 0; return -1; } if (!sd->fd) { //No connection if (sd->state.autotrade) map_quit(sd); //Remove it. //Else we don't remove it because the char should have a timer to remove the player because it force-quit before, //and we don't want them kicking their previous instance before the 10 secs penalty time passes. [Skotlex] return 0; } switch(RFIFOB(fd, 6)) { case 1: clif_authfail_fd(sd->fd, 1); break; //server closed case 2: clif_authfail_fd(sd->fd, 2); break; //someone else logged in case 3: clif_authfail_fd(sd->fd, 4); break; //server overpopulated case 4: clif_authfail_fd(sd->fd, 10); break; //out of available time paid for case 5: clif_authfail_fd(sd->fd, 15); break; //forced to dc by gm } return 0; }
/*========================================== * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor] *------------------------------------------*/ int chrif_accountban(int fd) { int acc; struct map_session_data *sd; acc = RFIFOL(fd,2); if (battle_config.etc_log) ShowNotice("chrif_accountban %d.\n", acc); sd = map_id2sd(acc); if (acc < 0 || sd == NULL) { ShowError("chrif_accountban failed - player not online.\n"); return 0; } sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters if (RFIFOB(fd,6) == 0) // 0: change of statut, 1: ban { switch (RFIFOL(fd,7)) { // status or final date of a banishment case 1: clif_displaymessage(sd->fd, "Your account has 'Unregistered'."); break; case 2: clif_displaymessage(sd->fd, "Your account has an 'Incorrect Password'..."); break; case 3: clif_displaymessage(sd->fd, "Your account has expired."); break; case 4: clif_displaymessage(sd->fd, "Your account has been rejected from server."); break; case 5: clif_displaymessage(sd->fd, "Your account has been blocked by the GM Team."); break; case 6: clif_displaymessage(sd->fd, "Your Game's EXE file is not the latest version."); break; case 7: clif_displaymessage(sd->fd, "Your account has been prohibited to log in."); break; case 8: clif_displaymessage(sd->fd, "Server is jammed due to over populated."); break; case 9: clif_displaymessage(sd->fd, "Your account has not more authorised."); break; case 100: clif_displaymessage(sd->fd, "Your account has been totally erased."); break; default: clif_displaymessage(sd->fd, "Your account has not more authorised."); break; } } else if (RFIFOB(fd,6) == 1) // 0: change of statut, 1: ban { time_t timestamp; char tmpstr[2048]; timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment strcpy(tmpstr, "Your account has been banished until "); strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(×tamp)); clif_displaymessage(sd->fd, tmpstr); } set_eof(sd->fd); // forced to disconnect for the change map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X] return 0; }
// 倉庫データ送信成功 static void intif_parse_SaveStorage(int fd) { if (battle_config.save_log) PRINTF("intif_savestorage: done %d %d\n", RFIFOL(fd, 2), RFIFOB(fd, 6)); storage_storage_saved(RFIFOL(fd, 2)); }
/// fame ranking update confirmation /// R 2b22 <table>.B <index>.B <value>.L int chrif_updatefamelist_ack(int fd) { struct fame_list* list; uint8 index; switch (RFIFOB(fd,2)) { case 1: list = smith_fame_list; break; case 2: list = chemist_fame_list; break; case 3: list = taekwon_fame_list; break; default: return 0; } index = RFIFOB(fd, 3); if (index >= MAX_FAME_LIST) return 0; list[index].fame = RFIFOL(fd,4); return 1; }
// ギルド同盟/敵対通知 static int intif_parse_GuildAlliance (int fd) { guild_allianceack (RFIFOL (fd, 2), RFIFOL (fd, 6), RFIFOL (fd, 10), RFIFOL (fd, 14), RFIFOB (fd, 18), (const char *)RFIFOP (fd, 19), (const char *)RFIFOP (fd, 43)); return 0; }
/*========================================== * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor] *------------------------------------------*/ int chrif_accountban(int fd) { int acc; struct map_session_data *sd; acc = RFIFOL(fd,2); if (battle_config.etc_log) ShowNotice("chrif_accountban %d.\n", acc); sd = map_id2sd(acc); if (acc < 0 || sd == NULL) { ShowError("chrif_accountban falhou - personagem nao encontrado.\n"); return 0; } sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters if (RFIFOB(fd,6) == 0) // 0: change of statut, 1: ban { switch (RFIFOL(fd,7)) { // status or final date of a banishment case 1: clif_displaymessage(sd->fd, "Sua conta encontra-se 'N�o Registrada'."); break; case 2: clif_displaymessage(sd->fd, "Sua conta encontra-se com a 'Senha Incorreta'..."); break; case 3: clif_displaymessage(sd->fd, "Sua conta foi expirada."); break; case 4: clif_displaymessage(sd->fd, "Sua conta foi rejeitada pelo servidor."); break; case 5: clif_displaymessage(sd->fd, "Sua conta foi bloqueada pela Equipe de GMs."); break; case 6: clif_displaymessage(sd->fd, "Seu execut�vel do jogo n�o encontra-se na �ltima vers�o."); break; case 7: clif_displaymessage(sd->fd, "Sua conta est� proibida de se conectar."); break; case 8: clif_displaymessage(sd->fd, "Servidor encontra-se lotado devido ao excesso de usu�rios."); break; case 9: clif_displaymessage(sd->fd, "Sua conta n�o est� mais autorizada ao acesso."); break; case 100: clif_displaymessage(sd->fd, "Sua conta foi totalmente apagada."); break; default: clif_displaymessage(sd->fd, "Sua conta n�o est� mais autorizada ao acesso."); break; } } else if (RFIFOB(fd,6) == 1) // 0: change of statut, 1: ban { time_t timestamp; char tmpstr[2048]; timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment strcpy(tmpstr, "Sua conta foi banida at� "); strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(×tamp)); clif_displaymessage(sd->fd, tmpstr); } set_eof(sd->fd); // forced to disconnect for the change map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X] return 0; }
/*========================================== * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor] *------------------------------------------*/ int chrif_accountban(int fd) { int acc; struct map_session_data *sd; acc = RFIFOL(fd,2); if (battle_config.etc_log) ShowNotice("chrif_accountban %d.\n", acc); sd = map_id2sd(acc); if (acc < 0 || sd == NULL) { ShowError("chrif_accountban failed - player not online.\n"); return 0; } sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters if (RFIFOB(fd,6) == 0) // 0: change of statut, 1: ban { switch (RFIFOL(fd,7)) { // status or final date of a banishment case 1: clif_displaymessage(sd->fd, "Your account has 'Unregistered'."); break; case 2: clif_displaymessage(sd->fd, "Senha incorreta..."); break; case 3: clif_displaymessage(sd->fd, "Sua conta expirou."); break; case 4: clif_displaymessage(sd->fd, "Sua conta foi rejeitada pelo map-server."); break; case 5: clif_displaymessage(sd->fd, "Sua conta foi bloqueada pela staff do server."); break; case 6: clif_displaymessage(sd->fd, "Seu EXE do jogo nуo estс na њltima versуo."); break; case 7: clif_displaymessage(sd->fd, "Sua conta foi proibida de fazer login."); break; case 8: clif_displaymessage(sd->fd, "Servidor estс lotado."); break; case 9: clif_displaymessage(sd->fd, "Your account has not more authorised."); break; case 100: clif_displaymessage(sd->fd, "Sua conta foi totalmente apagada."); break; default: clif_displaymessage(sd->fd, "Your account has not more authorised."); break; } } else if (RFIFOB(fd,6) == 1) // 0: change of statut, 1: ban { time_t timestamp; char tmpstr[2048]; timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment strcpy(tmpstr, "Sua conta foi banida atщ "); strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(×tamp)); clif_displaymessage(sd->fd, tmpstr); } set_eof(sd->fd); // forced to disconnect for the change map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X] return 0; }
/* * AH 0x2743 * We received the info from login-serv, transmit it to map */ int chlogif_parse_vipack(int fd) { #ifdef VIP_ENABLE if (RFIFOREST(fd) < 20) return 0; else { uint32 aid = RFIFOL(fd,2); //aid uint32 vip_time = RFIFOL(fd,6); //vip_time uint8 isvip = RFIFOB(fd,10); //isvip uint32 groupid = RFIFOL(fd,11); //new group id uint8 isgm = RFIFOB(fd,15); //isgm int mapfd = RFIFOL(fd,16); //link to mapserv for ack RFIFOSKIP(fd,20); chmapif_vipack(mapfd,aid,vip_time,isvip,isgm,groupid); } #endif return 1; }
void dump_data(FILE *file, int fd, int packet_len) { for (int f = 0; f < packet_len; f ++) { const unsigned int data = (unsigned int)RFIFOB(fd, f); fprintf(file, "%05d 0x%02x %5u %c\n", f, data, data, (int)data); } fprintf(file, "-----------------------------------\n"); }
void mapif_parse_rodex_requestinbox(int fd) { int count; int char_id = RFIFOL(fd,2); int account_id = RFIFOL(fd, 6); int8 flag = RFIFOB(fd, 10); int8 opentype = RFIFOB(fd, 11); int64 mail_id = RFIFOQ(fd, 12); struct rodex_maillist mails = { 0 }; VECTOR_INIT(mails); if (flag == 0) count = inter_rodex->fromsql(char_id, account_id, opentype, 0, &mails); else count = inter_rodex->fromsql(char_id, account_id, opentype, mail_id, &mails); mapif->rodex_sendinbox(fd, char_id, opentype, flag, count, mail_id, &mails); VECTOR_CLEAR(mails); }
// Communication from the map server //-Analysis that only one packet // Data packet length is set to inter.c that you // Do NOT go and check the packet length, RFIFOSKIP is done by the caller // Return : // 0 : error // 1 : ok int inter_party_parse_frommap(int fd) { RFIFOHEAD(fd); switch(RFIFOW(fd,0)) { case 0x3020: mapif->parse_CreateParty(fd, (char*)RFIFOP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member*)RFIFOP(fd,30)); break; case 0x3021: mapif->parse_PartyInfo(fd, RFIFOL(fd,2), RFIFOL(fd,6)); break; case 0x3022: mapif->parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break; case 0x3023: mapif->parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break; case 0x3024: mapif->parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break; case 0x3025: mapif->parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOW(fd,14), RFIFOB(fd,16), RFIFOW(fd,17)); break; case 0x3026: mapif->parse_BreakParty(fd, RFIFOL(fd,2)); break; case 0x3027: mapif->parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), (char*)RFIFOP(fd,12), RFIFOW(fd,2)-12); break; case 0x3029: mapif->parse_PartyLeaderChange(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break; default: return 0; } return 1; }
// パーティ作成可否 static int intif_parse_PartyCreated (int fd) { if (battle_config.etc_log) printf ("intif: party created\n"); party_created (RFIFOL (fd, 2), RFIFOB (fd, 6), RFIFOL (fd, 7), (const char *)RFIFOP (fd, 11)); return 0; }
// 倉庫データ送信成功 static int intif_parse_SaveStorage (int fd) { if (battle_config.save_log) printf ("intif_savestorage: done %d %d\n", RFIFOL (fd, 2), RFIFOB (fd, 6)); storage_storage_saved (RFIFOL (fd, 2)); return 0; }
// パーティ移動通知 static int intif_parse_PartyMove (int fd) { // if(battle_config.etc_log) // printf("intif: party move %d %d %s %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27)); party_recv_movemap (RFIFOL (fd, 2), RFIFOL (fd, 6), (const char *)RFIFOP (fd, 10), RFIFOB (fd, 26), RFIFOW (fd, 27)); return 0; }
// ギルドメンバオンライン状態/Lv変更通知 static int intif_parse_GuildMemberInfoShort (int fd) { guild_recv_memberinfoshort (RFIFOL (fd, 2), RFIFOL (fd, 6), RFIFOL (fd, 10), RFIFOB (fd, 14), RFIFOW (fd, 15), RFIFOW (fd, 17)); return 0; }
/*========================================== * Client Inbox Request *------------------------------------------*/ void mapif_parse_mail_requestinbox(int fd) { int char_id = RFIFOL(fd,2); unsigned char flag = RFIFOB(fd,6); struct mail_data md; memset(&md, 0, sizeof(md)); inter_mail->fromsql(char_id, &md); mapif->mail_sendinbox(fd, char_id, flag, &md); }
/** * Receive account data from login-server * AH 0x2717 <aid>.L <email>.40B <expiration_time>.L <group_id>.B <birthdate>.11B <pincode>.5B <pincode_change>.L <isvip>.B <char_vip>.B <char_billing>.B **/ int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){ int u_fd; //user fd if (RFIFOREST(fd) < 75) return 0; // find the authenticated session with this account id ARR_FIND( 0, fd_max, u_fd, session[u_fd] && (sd = (struct char_session_data*)session[u_fd]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) ); if( u_fd < fd_max ) { int server_id; memcpy(sd->email, RFIFOP(fd,6), 40); sd->expiration_time = (time_t)RFIFOL(fd,46); sd->group_id = RFIFOB(fd,50); sd->char_slots = RFIFOB(fd,51); if( sd->char_slots > MAX_CHARS ) { ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.hpp! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots); sd->char_slots = MAX_CHARS;/* cap to maximum */ } else if ( !sd->char_slots )/* no value aka 0 in sql */ sd->char_slots = MIN_CHARS;/* cap to minimum */ safestrncpy(sd->birthdate, RFIFOCP(fd,52), sizeof(sd->birthdate)); safestrncpy(sd->pincode, RFIFOCP(fd,63), sizeof(sd->pincode)); sd->pincode_change = (time_t)RFIFOL(fd,68); sd->isvip = RFIFOB(fd,72); sd->chars_vip = RFIFOB(fd,73); sd->chars_billing = RFIFOB(fd,74); ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, map_server[server_id].fd > 0 && map_server[server_id].map[0] ); // continued from char_auth_ok... if( server_id == ARRAYLENGTH(map_server) || //server not online, bugreport:2359 (((charserv_config.max_connect_user == 0 || charserv_config.char_maintenance == 1) || (charserv_config.max_connect_user > 0 && char_count_users() >= charserv_config.max_connect_user)) && sd->group_id < charserv_config.gm_allow_group)) { // refuse connection (over populated) chclif_reject(u_fd,0); } else { // send characters to player chclif_mmo_char_send(u_fd, sd); #if PACKETVER_SUPPORTS_PINCODE chlogif_pincode_start(u_fd,sd); #endif } } RFIFOSKIP(fd,75); return 1; }
/** * Receive a account_info request from map-serv * @author : [Dekamaster/Nightroad] * @param fd : map-serv link */ void mapif_parse_accinfo(int fd) { int u_fd = RFIFOL(fd,2), u_aid = RFIFOL(fd,6), u_group = RFIFOL(fd,10); char type= RFIFOB(fd,14); char query[NAME_LENGTH], query_esq[NAME_LENGTH*2+1]; uint32 account_id = 0; char *data; safestrncpy(query, RFIFOCP(fd,15), NAME_LENGTH); Sql_EscapeString(sql_handle, query_esq, query); account_id = atoi(query); if (account_id < START_ACCOUNT_NUM) { // is string if ( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", schema_config.char_db, query_esq) || Sql_NumRows(sql_handle) == 0 ) { if( Sql_NumRows(sql_handle) == 0 ) { inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(212) ,query); } else { Sql_ShowDebug(sql_handle); inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(213)); } Sql_FreeResult(sql_handle); return; } else { if( Sql_NumRows(sql_handle) == 1 ) {//we found a perfect match Sql_NextRow(sql_handle); Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data); Sql_FreeResult(sql_handle); } else {// more than one, listing... [Dekamaster/Nightroad] inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(214),(int)Sql_NumRows(sql_handle)); while ( SQL_SUCCESS == Sql_NextRow(sql_handle) ) { int class_; short base_level, job_level, online; char name[NAME_LENGTH]; Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data); Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name)); Sql_GetData(sql_handle, 2, &data, NULL); class_ = atoi(data); Sql_GetData(sql_handle, 3, &data, NULL); base_level = atoi(data); Sql_GetData(sql_handle, 4, &data, NULL); job_level = atoi(data); Sql_GetData(sql_handle, 5, &data, NULL); online = atoi(data); inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(215), account_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline"); } Sql_FreeResult(sql_handle); return; } } } /* it will only get here if we have a single match then ask login-server to fetch the `login` record */ if (!account_id || chlogif_req_accinfo(fd, u_fd, u_aid, u_group, account_id, type) != 1) { inter_to_fd(fd, u_fd, u_aid, (char *)msg_txt(213)); } return; }
// パーティ移動通知 static void intif_parse_PartyMove(int fd) { int party_id = RFIFOL(fd, 2); int account_id = RFIFOL(fd, 6); MapName map = stringish<MapName>(RFIFO_STRING<16>(fd, 10)); uint8_t online = RFIFOB(fd, 26); uint16_t lv = RFIFOW(fd, 27); party_recv_movemap(party_id, account_id, map, online, lv); }
/*========================================== * *------------------------------------------*/ int chrif_sendmapack(int fd) { if (RFIFOB(fd,2)) { ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2)); exit(EXIT_FAILURE); } memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH); ShowStatus("Map sending complete. Map Server is now online.\n"); chrif_state = 2; //If there are players online, send them to the char-server. [Skotlex] send_users_tochar(); //Re-save any storages that were modified in the disconnection time. [Skotlex] auth_db->foreach(auth_db,chrif_reconnect); do_reconnect_storage(); return 0; }
static int intif_parse_SaveGuildStorage (int fd) { if (battle_config.save_log) { printf ("intif_save_guild_storage: done %d %d %d\n", RFIFOL (fd, 2), RFIFOL (fd, 6), RFIFOB (fd, 10)); } storage_guild_storagesaved ( /*RFIFOL(fd,2), */ RFIFOL (fd, 6)); return 0; }
// パーティ作成可否 static void intif_parse_PartyCreated(int fd) { if (battle_config.etc_log) PRINTF("intif: party created\n"); int account_id = RFIFOL(fd, 2); int fail = RFIFOB(fd, 6); int party_id = RFIFOL(fd, 7); PartyName name = stringish<PartyName>(RFIFO_STRING<24>(fd, 11)); party_created(account_id, fail, party_id, name); }
/** * 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; }
/** * Request from char-server to authenticate an account. * @param fd: fd to parse from (char-serv) * @param id: id of char-serv * @param ip: char-serv ip (used for info) * @return 0 not enough info transmitted, 1 success */ int logchrif_parse_reqauth(int fd, int id,char* ip){ if( RFIFOREST(fd) < 23 ) return 0; else{ struct auth_node* node; uint32 account_id = RFIFOL(fd,2); uint32 login_id1 = RFIFOL(fd,6); uint32 login_id2 = RFIFOL(fd,10); uint8 sex = RFIFOB(fd,14); //uint32 ip_ = ntohl(RFIFOL(fd,15)); int request_id = RFIFOL(fd,19); RFIFOSKIP(fd,23); node = (struct auth_node*)idb_get(auth_db, account_id); if( runflag == LOGINSERVER_ST_RUNNING && node != NULL && node->account_id == account_id && node->login_id1 == login_id1 && node->login_id2 == login_id2 && node->sex == sex_num2str(sex) /*&& node->ip == ip_*/ ){// found //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip); // send ack WFIFOHEAD(fd,21); WFIFOW(fd,0) = 0x2713; WFIFOL(fd,2) = account_id; WFIFOL(fd,6) = login_id1; WFIFOL(fd,10) = login_id2; WFIFOB(fd,14) = sex; WFIFOB(fd,15) = 0;// ok WFIFOL(fd,16) = request_id; WFIFOB(fd,20) = node->clienttype; WFIFOSET(fd,21); // each auth entry can only be used once idb_remove(auth_db, account_id); }else{// authentication not found ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", ch_server[id].name, account_id, ip); WFIFOHEAD(fd,21); WFIFOW(fd,0) = 0x2713; WFIFOL(fd,2) = account_id; WFIFOL(fd,6) = login_id1; WFIFOL(fd,10) = login_id2; WFIFOB(fd,14) = sex; WFIFOB(fd,15) = 1;// auth failed WFIFOL(fd,16) = request_id; WFIFOB(fd,20) = 0; WFIFOSET(fd,21); } } return 1; }
/*========================================== * *------------------------------------------*/ int chrif_connectack(int fd) { if (RFIFOB(fd,2)) { ShowFatalError("Connection to char-server failed %d.\n", RFIFOB(fd,2)); exit(1); } ShowStatus("Successfully logged on to Char Server (Connection: '"CL_WHITE"%d"CL_RESET"').\n",fd); chrif_state = 1; chrif_connected=1; chrif_sendmap(fd); ShowStatus("Event '"CL_WHITE"OnCharIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnCharIfInit")); ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInit")); if(!char_init_done) { char_init_done = 1; ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInitOnce")); } return 0; }
int chlogif_parse_ackaccreq(int fd, struct char_session_data* sd){ if (RFIFOREST(fd) < 25) return 0; { int account_id = RFIFOL(fd,2); uint32 login_id1 = RFIFOL(fd,6); uint32 login_id2 = RFIFOL(fd,10); uint8 sex = RFIFOB(fd,14); uint8 result = RFIFOB(fd,15); int request_id = RFIFOL(fd,16); uint32 version = RFIFOL(fd,20); uint8 clienttype = RFIFOB(fd,24); RFIFOSKIP(fd,25); if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) && !sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex ) { int client_fd = request_id; sd->version = version; sd->clienttype = clienttype; if(sd->version != date2version(PACKETVER)) ShowWarning("s aid=%d has an incorect version=%d in clientinfo. Server compiled for %d\n", sd->account_id,sd->version,date2version(PACKETVER)); switch( result ) { case 0:// ok char_auth_ok(client_fd, sd); break; case 1:// auth failed WFIFOHEAD(client_fd,3); WFIFOW(client_fd,0) = 0x6c; WFIFOB(client_fd,2) = 0;// rejected from server WFIFOSET(client_fd,3); break; } } } 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; }
/* * Received the banking data from login and transmit it to all map-serv * AH 0x2741<aid>L <bank_vault>L <not_fw>B * HZ 0x2b29 <aid>L <bank_vault>L */ int chlogif_parse_BankingAck(int fd){ if (RFIFOREST(fd) < 11) return 0; else { uint32 aid = RFIFOL(fd,2); int32 bank_vault = RFIFOL(fd,6); char not_fw = RFIFOB(fd,10); RFIFOSKIP(fd,11); if(not_fw==0) chmapif_BankingAck(aid, bank_vault); } return 1; }
/*========================================== * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor] *------------------------------------------*/ int chrif_accountban(int fd) { int acc; struct map_session_data *sd; acc = RFIFOL(fd,2); if ( battle_config.etc_log ) ShowNotice("chrif_accountban %d.\n", acc); sd = map_id2sd(acc); if ( acc < 0 || sd == NULL ) { ShowError("chrif_accountban failed - player not online.\n"); return 0; } sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters if (RFIFOB(fd,6) == 0) { // 0: change of statut, 1: ban int ret_status = RFIFOL(fd,7); // status or final date of a banishment if(0<ret_status && ret_status<=9) clif->message(sd->fd, msg_txt(411+ret_status)); else if(ret_status==100) clif->message(sd->fd, msg_txt(421)); else clif->message(sd->fd, msg_txt(420)); //"Your account has not more authorised." } else if (RFIFOB(fd,6) == 1) { // 0: change of statut, 1: ban time_t timestamp; char tmpstr[2048]; timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment strcpy(tmpstr, msg_txt(423)); //"Your account has been banished until " strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(×tamp)); clif->message(sd->fd, tmpstr); } set_eof(sd->fd); // forced to disconnect for the change map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X] return 0; }
// Wisp/page transmission result int mapif_parse_WisReply(int fd) { int id = RFIFOL(fd,2), flag = RFIFOB(fd,6); struct WisData *wd = idb_get(wis_db, id); if (wd == NULL) return 0; // This wisp was probably suppress before, because it was timeout of because of target was found on another map-server if ((--wd->count) <= 0 || flag != 1) { mapif_wis_end(wd, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target idb_remove(wis_db, id); } return 0; }