/** * Send map-servers fames ranking lists * Defaut fame list are 32B, (id+point+names) * S <len>.W <len bs + alchi>.W <len bs>.W <smith_rank>?B <alchi_rank>?B <taek_rank>?B * @param fd: fd to send packet too (map-serv) if -1 send to all * @return : 0 success */ int chmapif_send_fame_list(int fd){ int i, len = 8; unsigned char buf[32000]; WBUFW(buf,0) = 0x2b1b; for(i = 0; i < fame_list_size_smith && smith_fame_list[i].id; i++) { memcpy(WBUFP(buf, len), &smith_fame_list[i], sizeof(struct fame_list)); len += sizeof(struct fame_list); } // add blacksmith's block length WBUFW(buf, 6) = len; for(i = 0; i < fame_list_size_chemist && chemist_fame_list[i].id; i++) { memcpy(WBUFP(buf, len), &chemist_fame_list[i], sizeof(struct fame_list)); len += sizeof(struct fame_list); } // add alchemist's block length WBUFW(buf, 4) = len; for(i = 0; i < fame_list_size_taekwon && taekwon_fame_list[i].id; i++) { memcpy(WBUFP(buf, len), &taekwon_fame_list[i], sizeof(struct fame_list)); len += sizeof(struct fame_list); } // add total packet length WBUFW(buf, 2) = len; if (fd != -1) chmapif_send(fd, buf, len); else chmapif_sendall(buf, len); return 0; }
int chlogif_broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data) { uint8 buf[6]; int users = char_count_users(); // only send an update when needed static int prev_users = 0; if( prev_users == users ) return 0; prev_users = users; if( chlogif_isconnected() ) { // send number of user to login server WFIFOHEAD(login_fd,6); WFIFOW(login_fd,0) = 0x2714; WFIFOL(login_fd,2) = users; WFIFOSET(login_fd,6); } // send number of players to all map-servers WBUFW(buf,0) = 0x2b00; WBUFL(buf,2) = users; chmapif_sendall(buf,6); return 0; }
int chlogif_parse_updip(int fd, struct char_session_data* sd){ unsigned char buf[2]; uint32 new_ip = 0; /** * !CHECKME: This is intended? Just tell if there's IP sync request * without sending current char IP (if changed) to map-server? **/ WBUFW(buf,0) = 0x2b1e; chmapif_sendall(buf, 2); new_ip = host2ip(charserv_config.login_ip_str); if (new_ip && new_ip != charserv_config.login_ip) charserv_config.login_ip = new_ip; //Update login ip, too. new_ip = host2ip(charserv_config.char_ip_str); if (new_ip && new_ip != charserv_config.char_ip) { // Char-server IP is updated. charserv_config.char_ip = new_ip; ShowInfo("Updating IP for [%s].\n", charserv_config.char_ip_str); // notify login server about the change WFIFOHEAD(fd,6); WFIFOW(fd,0) = 0x2736; WFIFOL(fd,2) = htonl(charserv_config.char_ip); WFIFOSET(fd,6); } RFIFOSKIP(fd,2); return 1; }
/** * Send to map-servers the users count on this char-serv, (meaning the total of all mapserv) * @param users: number of players on this char-serv */ void chmapif_sendall_playercount(int users){ uint8 buf[6]; // send number of players to all map-servers WBUFW(buf,0) = 0x2b00; WBUFL(buf,2) = users; chmapif_sendall(buf,6); }
int chlogif_parse_updip(int fd, struct char_session_data* sd){ unsigned char buf[2]; uint32 new_ip = 0; WBUFW(buf,0) = 0x2b1e; chmapif_sendall(buf, 2); new_ip = host2ip(charserv_config.login_ip_str); if (new_ip && new_ip != charserv_config.login_ip) charserv_config.login_ip = new_ip; //Update login ip, too. new_ip = host2ip(charserv_config.char_ip_str); if (new_ip && new_ip != charserv_config.char_ip) { //Update ip. charserv_config.char_ip = new_ip; ShowInfo("Updating IP for [%s].\n", charserv_config.char_ip_str); // notify login server about the change WFIFOHEAD(fd,6); WFIFOW(fd,0) = 0x2736; WFIFOL(fd,2) = htonl(charserv_config.char_ip); WFIFOSET(fd,6); } RFIFOSKIP(fd,2); return 1; }
/** * Send to map-servers the updated fame ranking lists * We actually just send this one when we only need to update rankpoint but pos didn't change * @param type: ranking type * @param index: position in the ranking * @param fame: number of points */ void chmapif_update_fame_list(int type, int index, int fame) { unsigned char buf[8]; WBUFW(buf,0) = 0x2b22; WBUFB(buf,2) = type; WBUFB(buf,3) = index; WBUFL(buf,4) = fame; chmapif_sendall(buf, 8); }
static void mapif_Auction_message(int char_id, unsigned char result) { unsigned char buf[74]; WBUFW(buf,0) = 0x3854; WBUFL(buf,2) = char_id; WBUFL(buf,6) = result; chmapif_sendall(buf,7); }
//Dissolution party notification int mapif_party_broken(int party_id,int flag) { unsigned char buf[16]; WBUFW(buf,0)=0x3826; WBUFL(buf,2)=party_id; WBUFB(buf,6)=flag; chmapif_sendall(buf,7); //printf("int_party: broken %d\n",party_id); return 0; }
int chlogif_parse_ack_global_accreg(int fd, struct char_session_data* sd){ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) return 0; else { //Receive account_reg2 registry, forward to map servers. RFIFOW(fd,0) = 0x3804; chmapif_sendall(RFIFOP(fd,0), RFIFOW(fd,2)); RFIFOSKIP(fd, RFIFOW(fd,2)); } return 1; }
//Withdrawal notification party int mapif_party_withdraw(int party_id,uint32 account_id, uint32 char_id) { unsigned char buf[16]; WBUFW(buf,0) = 0x3824; WBUFL(buf,2) = party_id; WBUFL(buf,6) = account_id; WBUFL(buf,10) = char_id; chmapif_sendall(buf, 14); return 0; }
// Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers) int mapif_parse_WisToGM(int fd) { unsigned char buf[2048]; // 0x3003/0x3803 <packet_len>.w <wispname>.24B <permission>.L <message>.?B memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2)); WBUFW(buf, 0) = 0x3803; chmapif_sendall(buf, RFIFOW(fd,2)); return 0; }
//Withdrawal notification party int mapif_party_withdraw(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type) { unsigned char buf[15+NAME_LENGTH]; WBUFW(buf,0) = 0x3824; WBUFL(buf,2) = party_id; WBUFL(buf,6) = account_id; WBUFL(buf,10) = char_id; memcpy(WBUFP(buf,14), name, NAME_LENGTH); WBUFB(buf,14+NAME_LENGTH) = type; chmapif_sendall(buf,15+NAME_LENGTH); return 0; }
//Digest party information static void mapif_party_info(int fd, struct party* p, uint32 char_id) { unsigned char buf[8 + sizeof(struct party)]; WBUFW(buf,0) = 0x3821; WBUFW(buf,2) = 8 + sizeof(struct party); WBUFL(buf,4) = char_id; memcpy(WBUFP(buf,8), p, sizeof(struct party)); if(fd<0) chmapif_sendall(buf,WBUFW(buf,2)); else chmapif_send(fd,buf,WBUFW(buf,2)); }
int chlogif_parse_ackacc2req(int fd, struct char_session_data* sd){ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) return 0; { //Receive account_reg2 registry, forward to map servers. unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)]; memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2)); WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex] chmapif_sendall(buf, WBUFW(buf,2)); RFIFOSKIP(fd, RFIFOW(fd,2)); } return 1; }
//Party map update notification int mapif_party_membermoved(struct party *p,int idx) { unsigned char buf[20]; WBUFW(buf,0) = 0x3825; WBUFL(buf,2) = p->party_id; WBUFL(buf,6) = p->member[idx].account_id; WBUFL(buf,10) = p->member[idx].char_id; WBUFW(buf,14) = p->member[idx].map; WBUFB(buf,16) = p->member[idx].online; WBUFW(buf,17) = p->member[idx].lv; chmapif_sendall(buf, 19); return 0; }
// Wis sending int mapif_wis_message(struct WisData *wd) { unsigned char buf[2048]; if (wd->len > 2047-56) wd->len = 2047-56; //Force it to fit to avoid crashes. [Skotlex] WBUFW(buf, 0) = 0x3801; WBUFW(buf, 2) = 56 +wd->len; WBUFL(buf, 4) = wd->id; memcpy(WBUFP(buf, 8), wd->src, NAME_LENGTH); memcpy(WBUFP(buf,32), wd->dst, NAME_LENGTH); memcpy(WBUFP(buf,56), wd->msg, wd->len); wd->count = chmapif_sendall(buf,WBUFW(buf,2)); return 0; }
// Party setting change notification int mapif_party_optionchanged(int fd,struct party *p,uint32 account_id,int flag) { unsigned char buf[16]; WBUFW(buf,0)=0x3823; WBUFL(buf,2)=p->party_id; WBUFL(buf,6)=account_id; WBUFW(buf,10)=p->exp; WBUFW(buf,12)=p->item; WBUFB(buf,14)=flag; if(flag==0) chmapif_sendall(buf,15); else chmapif_send(fd,buf,15); return 0; }
/*========================================== * Report New Mail to Map Server *------------------------------------------*/ void mapif_Mail_new(struct mail_message *msg) { unsigned char buf[75]; if( !msg || !msg->id ) return; WBUFW(buf,0) = 0x3849; WBUFL(buf,2) = msg->dest_id; WBUFL(buf,6) = msg->id; memcpy(WBUFP(buf,10), msg->send_name, NAME_LENGTH); memcpy(WBUFP(buf,34), msg->title, MAIL_TITLE_LENGTH); WBUFB(buf,74) = msg->type; chmapif_sendall(buf, 75); }
int chlogif_parse_accbannotification(int fd, struct char_session_data* sd){ if (RFIFOREST(fd) < 11) return 0; else { // send to all map-servers to disconnect the player unsigned char buf[11]; WBUFW(buf,0) = 0x2b14; WBUFL(buf,2) = RFIFOL(fd,2); WBUFB(buf,6) = RFIFOB(fd,6); // 0: change of statut, 1: ban WBUFL(buf,7) = RFIFOL(fd,7); // status or final date of a banishment chmapif_sendall(buf, 11); } // disconnect player if online on char-server char_disconnect_player(RFIFOL(fd,2)); RFIFOSKIP(fd,11); 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; }
/** * Changes a character's sex. * The information is updated on database, and the character is kicked if it * currently is online. * * @param char_id The character's ID. * @param sex The new sex. * @retval 0 in case of success. * @retval 1 in case of failure. */ int chlogif_parse_ackchangecharsex(int char_id, int sex) { int class_ = 0, guild_id = 0, account_id = 0; unsigned char buf[7]; char *data; // get character data if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`class`,`guild_id` FROM `%s` WHERE `char_id` = '%d'", schema_config.char_db, char_id)) { Sql_ShowDebug(sql_handle); return 1; } if (Sql_NumRows(sql_handle) != 1 || SQL_ERROR == Sql_NextRow(sql_handle)) { Sql_FreeResult(sql_handle); return 1; } Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data); Sql_GetData(sql_handle, 1, &data, NULL); class_ = atoi(data); Sql_GetData(sql_handle, 2, &data, NULL); guild_id = atoi(data); Sql_FreeResult(sql_handle); if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `sex` = '%c' WHERE `char_id` = '%d'", schema_config.char_db, sex == SEX_MALE ? 'M' : 'F', char_id)) { Sql_ShowDebug(sql_handle); return 1; } chlogif_parse_change_sex_sub(sex, account_id, char_id, class_, guild_id); // disconnect player if online on char-server char_disconnect_player(account_id); // notify all mapservers about this change WBUFW(buf,0) = 0x2b0d; WBUFL(buf,2) = account_id; WBUFB(buf,6) = sex; chmapif_sendall(buf, 7); return 0; }
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; }