diff options
Diffstat (limited to 'src/char')
-rw-r--r-- | src/char/char.c | 252 | ||||
-rw-r--r-- | src/char/char.h | 3 | ||||
-rw-r--r-- | src/char/int_auction.c | 235 | ||||
-rw-r--r-- | src/char/int_clan.c | 26 | ||||
-rw-r--r-- | src/char/int_elemental.c | 69 | ||||
-rw-r--r-- | src/char/int_elemental.h | 6 | ||||
-rw-r--r-- | src/char/int_guild.c | 553 | ||||
-rw-r--r-- | src/char/int_guild.h | 16 | ||||
-rw-r--r-- | src/char/int_homun.c | 113 | ||||
-rw-r--r-- | src/char/int_homun.h | 7 | ||||
-rw-r--r-- | src/char/int_mail.c | 236 | ||||
-rw-r--r-- | src/char/int_mail.h | 5 | ||||
-rw-r--r-- | src/char/int_mercenary.c | 72 | ||||
-rw-r--r-- | src/char/int_mercenary.h | 6 | ||||
-rw-r--r-- | src/char/int_party.c | 260 | ||||
-rw-r--r-- | src/char/int_party.h | 8 | ||||
-rw-r--r-- | src/char/int_pet.c | 149 | ||||
-rw-r--r-- | src/char/int_pet.h | 4 | ||||
-rw-r--r-- | src/char/int_quest.c | 90 | ||||
-rw-r--r-- | src/char/int_quest.h | 6 | ||||
-rw-r--r-- | src/char/int_rodex.c | 173 | ||||
-rw-r--r-- | src/char/int_rodex.h | 1 | ||||
-rw-r--r-- | src/char/int_storage.c | 248 | ||||
-rw-r--r-- | src/char/int_storage.h | 3 | ||||
-rw-r--r-- | src/char/inter.c | 351 | ||||
-rw-r--r-- | src/char/inter.h | 13 | ||||
-rw-r--r-- | src/char/mapif.c | 2508 | ||||
-rw-r--r-- | src/char/mapif.h | 43 |
28 files changed, 2805 insertions, 2651 deletions
diff --git a/src/char/char.c b/src/char/char.c index 6e0193780..04db83eb9 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1534,12 +1534,56 @@ int char_rename_char_sql(struct char_session_data *sd, int char_id) return 0; } -int char_check_char_name(char * name, char * esc_name) +/** + * Checks if the given name exists in the database. + * + * @param name The name to check. + * @param esc_name Escaped version of the name, optional for faster processing. + * @retval true if the character name already exists. + */ +bool char_name_exists(const char *name, const char *esc_name) +{ + char esc_name2[NAME_LENGTH * 2 + 1]; + + nullpo_retr(true, name); + + if (esc_name == NULL) { + SQL->EscapeStringLen(inter->sql_handle, esc_name2, name, strnlen(name, NAME_LENGTH)); + esc_name = esc_name2; + } + + if (name_ignoring_case) { + if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", char_db, esc_name)) { + Sql_ShowDebug(inter->sql_handle); + return true; + } + } else { + if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT 1 FROM `%s` WHERE `name` = '%s' LIMIT 1", char_db, esc_name)) { + Sql_ShowDebug(inter->sql_handle); + return true; + } + } + if (SQL->NumRows(inter->sql_handle) > 0) + return true; + + return false; +} + +/** + * Checks if the given name is valid for a new character. + * + * @param name The name to check. + * @param esc_name Escaped version of the name, optional for faster processing. + * @retval 0 if the name is valid. + * @retval -1 if the name already exists or is reserved + * @retval -2 if the name is too short or contains special characters. + * @retval -5 if the name contains forbidden characters. + */ +int char_check_char_name(const char *name, const char *esc_name) { int i; nullpo_retr(-2, name); - nullpo_retr(-2, esc_name); // check length of character name if (name[0] == '\0') @@ -1550,9 +1594,16 @@ int char_check_char_name(char * name, char * esc_name) **/ if( strlen( name ) < 4 ) return -2; - // check content of character name - if( remove_control_chars(name) ) - return -2; // control chars in name + + { + // check content of character name + char *name_copy = aStrdup(name); + if (remove_control_chars(name_copy)) { + aFree(name_copy); + return -2; // control chars in name + } + aFree(name_copy); + } // check for reserved names if( strcmpi(name, wisp_server_name) == 0 ) @@ -1571,19 +1622,9 @@ int char_check_char_name(char * name, char * esc_name) if( strchr(char_name_letters, name[i]) != NULL ) return -5; } - if( name_ignoring_case ) { - if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT 1 FROM `%s` WHERE BINARY `name` = '%s' LIMIT 1", char_db, esc_name) ) { - Sql_ShowDebug(inter->sql_handle); - return -2; - } - } else { - if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT 1 FROM `%s` WHERE `name` = '%s' LIMIT 1", char_db, esc_name) ) { - Sql_ShowDebug(inter->sql_handle); - return -2; - } - } - if( SQL->NumRows(inter->sql_handle) > 0 ) - return -1; // name already exists + + if (chr->name_exists(name, esc_name)) + return -1; return 0; } @@ -1811,11 +1852,11 @@ int char_delete_char_sql(int char_id) /* remove homunculus */ if( hom_id ) - mapif->homunculus_delete(hom_id); + inter_homunculus->delete(hom_id); /* remove elemental */ if (elemental_id) - mapif->elemental_delete(elemental_id); + inter_elemental->delete(elemental_id); /* remove mercenary data */ inter_mercenary->owner_delete(char_id); @@ -1887,9 +1928,9 @@ int char_delete_char_sql(int char_id) if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `guild_id` FROM `%s` WHERE `char_id` = '%d'", guild_db, char_id) ) Sql_ShowDebug(inter->sql_handle); else if( SQL->NumRows(inter->sql_handle) > 0 ) - mapif->parse_BreakGuild(0,guild_id); + inter_guild->disband(guild_id); else if( guild_id ) - inter_guild->leave(guild_id, account_id, char_id);// Leave your guild. + inter_guild->leave(guild_id, account_id, char_id, 0, "** Character Deleted **", -1);// Leave your guild. return 0; } @@ -2479,17 +2520,6 @@ void char_parse_fromlogin_account_reg2(int fd) RFIFOSKIP(fd, RFIFOW(fd,2)); } -void mapif_ban(int id, unsigned int flag, int status) -{ - // send to all map-servers to disconnect the player - unsigned char buf[11]; - WBUFW(buf,0) = 0x2b14; - WBUFL(buf,2) = id; - WBUFB(buf,6) = flag; // 0: change of status, 1: ban - WBUFL(buf,7) = status; // status or final date of a banishment - mapif->sendall(buf, 11); -} - void char_parse_fromlogin_ban(int fd) { mapif->ban(RFIFOL(fd,2), RFIFOB(fd,6), RFIFOL(fd,7)); @@ -2561,14 +2591,14 @@ void char_parse_fromlogin_update_ip(int fd) void char_parse_fromlogin_accinfo2_failed(int fd) { - mapif->parse_accinfo2(false, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), + inter->accinfo2(false, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, 0, 0); RFIFOSKIP(fd,18); } void char_parse_fromlogin_accinfo2_ok(int fd) { - mapif->parse_accinfo2(true, RFIFOL(fd,167), RFIFOL(fd,171), RFIFOL(fd,175), RFIFOL(fd,179), + inter->accinfo2(true, RFIFOL(fd,167), RFIFOL(fd,171), RFIFOL(fd,175), RFIFOL(fd,179), RFIFOP(fd,2), RFIFOP(fd,26), RFIFOP(fd,59), RFIFOP(fd,99), RFIFOP(fd,119), RFIFOP(fd,151), RFIFOP(fd,156), RFIFOL(fd,115), RFIFOL(fd,143), RFIFOL(fd,147)); RFIFOSKIP(fd,183); @@ -2912,70 +2942,6 @@ int char_loadName(int char_id, char* name) return 0; } -/// Initializes a server structure. -void mapif_server_init(int id) -{ - //memset(&chr->server[id], 0, sizeof(server[id])); - chr->server[id].fd = -1; -} - -/// Destroys a server structure. -void mapif_server_destroy(int id) -{ - if( chr->server[id].fd == -1 ) - { - sockt->close(chr->server[id].fd); - chr->server[id].fd = -1; - } -} - - -/// Resets all the data related to a server. -void mapif_server_reset(int id) -{ - int i,j; - unsigned char buf[16384]; - int fd = chr->server[id].fd; - //Notify other map servers that this one is gone. [Skotlex] - WBUFW(buf,0) = 0x2b20; - WBUFL(buf,4) = htonl(chr->server[id].ip); - WBUFW(buf,8) = htons(chr->server[id].port); - j = 0; - for (i = 0; i < VECTOR_LENGTH(chr->server[id].maps); i++) { - uint16 m = VECTOR_INDEX(chr->server[id].maps, i); - if (m != 0) - WBUFW(buf,10+(j++)*4) = m; - } - if (j > 0) { - WBUFW(buf,2) = j * 4 + 10; - mapif->sendallwos(fd, buf, WBUFW(buf,2)); - } - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `index`='%d'", ragsrvinfo_db, chr->server[id].fd) ) - Sql_ShowDebug(inter->sql_handle); - chr->online_char_db->foreach(chr->online_char_db,chr->db_setoffline,id); //Tag relevant chars as 'in disconnected' server. - mapif->server_destroy(id); - mapif->server_init(id); -} - -/// Called when the connection to a Map Server is disconnected. -void mapif_on_disconnect(int id) -{ - ShowStatus("Map-server #%d has disconnected.\n", id); - mapif->server_reset(id); -} - -void mapif_on_parse_accinfo(int account_id, int u_fd, int u_aid, int u_group, int map_fd) { - Assert_retv(chr->login_fd > 0); - WFIFOHEAD(chr->login_fd,22); - WFIFOW(chr->login_fd,0) = 0x2740; - WFIFOL(chr->login_fd,2) = account_id; - WFIFOL(chr->login_fd,6) = u_fd; - WFIFOL(chr->login_fd,10) = u_aid; - WFIFOL(chr->login_fd,14) = u_group; - WFIFOL(chr->login_fd,18) = map_fd; - WFIFOSET(chr->login_fd,22); -} - void char_parse_frommap_datasync(int fd) { sockt->datasync(fd, false); @@ -3357,16 +3323,6 @@ void char_parse_frommap_change_email(int fd) RFIFOSKIP(fd, 86); } -void mapif_char_ban(int char_id, time_t timestamp) -{ - unsigned char buf[11]; - WBUFW(buf,0) = 0x2b14; - WBUFL(buf,2) = char_id; - WBUFB(buf,6) = 2; - WBUFL(buf,7) = (unsigned int)timestamp; - mapif->sendall(buf, 11); -} - void char_ban(int account_id, int char_id, time_t *unban_time, short year, short month, short day, short hour, short minute, short second) { time_t timestamp; @@ -4812,7 +4768,6 @@ void char_parse_char_rename_char(int fd, struct char_session_data* sd) { int i, cid =RFIFOL(fd,2); char name[NAME_LENGTH]; - char esc_name[NAME_LENGTH*2+1]; safestrncpy(name, RFIFOP(fd,6), NAME_LENGTH); RFIFOSKIP(fd,30); @@ -4821,8 +4776,7 @@ void char_parse_char_rename_char(int fd, struct char_session_data* sd) return; normalize_name(name,TRIM_CHARS); - SQL->EscapeStringLen(inter->sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); - if( !chr->check_char_name(name,esc_name) ) { + if (chr->check_char_name(name, NULL) == 0) { i = 1; safestrncpy(sd->new_name, name, NAME_LENGTH); } else { @@ -4837,7 +4791,6 @@ void char_parse_char_rename_char2(int fd, struct char_session_data* sd) { int i, aid = RFIFOL(fd,2), cid =RFIFOL(fd,6); char name[NAME_LENGTH]; - char esc_name[NAME_LENGTH*2+1]; safestrncpy(name, RFIFOP(fd,10), NAME_LENGTH); RFIFOSKIP(fd,34); @@ -4848,14 +4801,12 @@ void char_parse_char_rename_char2(int fd, struct char_session_data* sd) return; normalize_name(name,TRIM_CHARS); - SQL->EscapeStringLen(inter->sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); - if( !chr->check_char_name(name,esc_name) ) - { + if (chr->check_char_name(name, NULL) == 0) { i = 1; safestrncpy(sd->new_name, name, NAME_LENGTH); - } - else + } else { i = 0; + } chr->allow_rename(fd, i); } @@ -5254,70 +5205,6 @@ int char_parse_char(int fd) return 0; } -int mapif_sendall(const unsigned char *buf, unsigned int len) -{ - int i, c; - - nullpo_ret(buf); - c = 0; - for(i = 0; i < ARRAYLENGTH(chr->server); i++) { - int fd; - if ((fd = chr->server[i].fd) > 0) { - WFIFOHEAD(fd,len); - memcpy(WFIFOP(fd,0), buf, len); - WFIFOSET(fd,len); - c++; - } - } - - return c; -} - -int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len) -{ - int i, c; - - nullpo_ret(buf); - c = 0; - for(i = 0; i < ARRAYLENGTH(chr->server); i++) { - int fd; - if ((fd = chr->server[i].fd) > 0 && fd != sfd) { - WFIFOHEAD(fd,len); - memcpy(WFIFOP(fd,0), buf, len); - WFIFOSET(fd,len); - c++; - } - } - - return c; -} - -int mapif_send(int fd, unsigned char *buf, unsigned int len) -{ - nullpo_ret(buf); - if (fd >= 0) { - int i; - ARR_FIND( 0, ARRAYLENGTH(chr->server), i, fd == chr->server[i].fd ); - if( i < ARRAYLENGTH(chr->server) ) - { - WFIFOHEAD(fd,len); - memcpy(WFIFOP(fd,0), buf, len); - WFIFOSET(fd,len); - return 1; - } - } - return 0; -} - -void mapif_send_users_count(int users) -{ - uint8 buf[6]; - // send number of players to all map-servers - WBUFW(buf,0) = 0x2b00; - WBUFL(buf,2) = users; - mapif->sendall(buf,6); -} - int char_broadcast_user_count(int tid, int64 tick, int id, intptr_t data) { int users = chr->count_users(); @@ -6465,6 +6352,7 @@ void char_defaults(void) chr->mmo_char_sql_init = char_mmo_char_sql_init; chr->char_slotchange = char_char_slotchange; chr->rename_char_sql = char_rename_char_sql; + chr->name_exists = char_name_exists; chr->check_char_name = char_check_char_name; chr->make_new_char_sql = char_make_new_char_sql; chr->divorce_char_sql = char_divorce_char_sql; diff --git a/src/char/char.h b/src/char/char.h index a644f11ab..4d816583a 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -147,7 +147,8 @@ struct char_interface { int (*mmo_char_sql_init) (void); bool (*char_slotchange) (struct char_session_data *sd, int fd, unsigned short from, unsigned short to); int (*rename_char_sql) (struct char_session_data *sd, int char_id); - int (*check_char_name) (char * name, char * esc_name); + bool (*name_exists) (const char *name, const char *esc_name); + int (*check_char_name) (const char *name, const char *esc_name); int (*make_new_char_sql) (struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex); int (*divorce_char_sql) (int partner_id1, int partner_id2); int (*count_users) (void); diff --git a/src/char/int_auction.c b/src/char/int_auction.c index 3a11f1865..9cd4c900c 100644 --- a/src/char/int_auction.c +++ b/src/char/int_auction.c @@ -148,16 +148,6 @@ unsigned int inter_auction_create(struct auction_data *auction) return auction->auction_id; } -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; - mapif->sendall(buf,7); -} - static int inter_auction_end_timer(int tid, int64 tick, int id, intptr_t data) { struct auction_data *auction; if( (auction = (struct auction_data *)idb_get(inter_auction->db, id)) != NULL ) @@ -269,231 +259,6 @@ void inter_auctions_fromsql(void) SQL->FreeResult(inter->sql_handle); } -void mapif_auction_sendlist(int fd, int char_id, short count, short pages, unsigned char *buf) -{ - int len = (sizeof(struct auction_data) * count) + 12; - - nullpo_retv(buf); - - WFIFOHEAD(fd, len); - WFIFOW(fd,0) = 0x3850; - WFIFOW(fd,2) = len; - WFIFOL(fd,4) = char_id; - WFIFOW(fd,8) = count; - WFIFOW(fd,10) = pages; - memcpy(WFIFOP(fd,12), buf, len - 12); - WFIFOSET(fd,len); -} - -void mapif_parse_auction_requestlist(int fd) -{ - char searchtext[NAME_LENGTH]; - int char_id = RFIFOL(fd,4), len = sizeof(struct auction_data); - int price = RFIFOL(fd,10); - short type = RFIFOW(fd,8), page = max(1,RFIFOW(fd,14)); - unsigned char buf[5 * sizeof(struct auction_data)]; - struct DBIterator *iter = db_iterator(inter_auction->db); - struct auction_data *auction; - short i = 0, j = 0, pages = 1; - - memcpy(searchtext, RFIFOP(fd,16), NAME_LENGTH); - - for( auction = dbi_first(iter); dbi_exists(iter); auction = dbi_next(iter) ) - { - if( (type == 0 && auction->type != IT_ARMOR && auction->type != IT_PETARMOR) || - (type == 1 && auction->type != IT_WEAPON) || - (type == 2 && auction->type != IT_CARD) || - (type == 3 && auction->type != IT_ETC) || - (type == 4 && !strstr(auction->item_name, searchtext)) || - (type == 5 && auction->price > price) || - (type == 6 && auction->seller_id != char_id) || - (type == 7 && auction->buyer_id != char_id) ) - continue; - - i++; - if( i > 5 ) - { // Counting Pages of Total Results (5 Results per Page) - pages++; - i = 1; // First Result of This Page - } - - if( page != pages ) - continue; // This is not the requested Page - - memcpy(WBUFP(buf, j * len), auction, len); - j++; // Found Results - } - dbi_destroy(iter); - - mapif->auction_sendlist(fd, char_id, j, pages, buf); -} - -void mapif_auction_register(int fd, struct auction_data *auction) -{ - int len = sizeof(struct auction_data) + 4; - - nullpo_retv(auction); - - WFIFOHEAD(fd,len); - WFIFOW(fd,0) = 0x3851; - WFIFOW(fd,2) = len; - memcpy(WFIFOP(fd,4), auction, sizeof(struct auction_data)); - WFIFOSET(fd,len); -} - -void mapif_parse_auction_register(int fd) -{ - struct auction_data auction; - if( RFIFOW(fd,2) != sizeof(struct auction_data) + 4 ) - return; - - memcpy(&auction, RFIFOP(fd,4), sizeof(struct auction_data)); - if( inter_auction->count(auction.seller_id, false) < 5 ) - auction.auction_id = inter_auction->create(&auction); - - mapif->auction_register(fd, &auction); -} - -void mapif_auction_cancel(int fd, int char_id, unsigned char result) -{ - WFIFOHEAD(fd,7); - WFIFOW(fd,0) = 0x3852; - WFIFOL(fd,2) = char_id; - WFIFOB(fd,6) = result; - WFIFOSET(fd,7); -} - -void mapif_parse_auction_cancel(int fd) -{ - int char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6); - struct auction_data *auction; - - if( (auction = (struct auction_data *)idb_get(inter_auction->db, auction_id)) == NULL ) - { - mapif->auction_cancel(fd, char_id, 1); // Bid Number is Incorrect - return; - } - - if( auction->seller_id != char_id ) - { - mapif->auction_cancel(fd, char_id, 2); // You cannot end the auction - return; - } - - if( auction->buyer_id > 0 ) - { - mapif->auction_cancel(fd, char_id, 3); // An auction with at least one bidder cannot be canceled - return; - } - - inter_mail->sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Auction canceled.", 0, &auction->item); - inter_auction->delete_(auction); - - mapif->auction_cancel(fd, char_id, 0); // The auction has been canceled -} - -void mapif_auction_close(int fd, int char_id, unsigned char result) -{ - WFIFOHEAD(fd,7); - WFIFOW(fd,0) = 0x3853; - WFIFOL(fd,2) = char_id; - WFIFOB(fd,6) = result; - WFIFOSET(fd,7); -} - -void mapif_parse_auction_close(int fd) -{ - int char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6); - struct auction_data *auction; - - if( (auction = (struct auction_data *)idb_get(inter_auction->db, auction_id)) == NULL ) - { - mapif->auction_close(fd, char_id, 2); // Bid Number is Incorrect - return; - } - - if( auction->seller_id != char_id ) - { - mapif->auction_close(fd, char_id, 1); // You cannot end the auction - return; - } - - if( auction->buyer_id == 0 ) - { - mapif->auction_close(fd, char_id, 1); // You cannot end the auction - return; - } - - // Send Money to Seller - inter_mail->sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Auction closed.", auction->price, NULL); - // Send Item to Buyer - inter_mail->sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Auction winner.", 0, &auction->item); - mapif->auction_message(auction->buyer_id, 6); // You have won the auction - inter_auction->delete_(auction); - - mapif->auction_close(fd, char_id, 0); // You have ended the auction -} - -void mapif_auction_bid(int fd, int char_id, int bid, unsigned char result) -{ - WFIFOHEAD(fd,11); - WFIFOW(fd,0) = 0x3855; - WFIFOL(fd,2) = char_id; - WFIFOL(fd,6) = bid; // To Return Zeny - WFIFOB(fd,10) = result; - WFIFOSET(fd,11); -} - -void mapif_parse_auction_bid(int fd) -{ - int char_id = RFIFOL(fd,4), bid = RFIFOL(fd,12); - unsigned int auction_id = RFIFOL(fd,8); - struct auction_data *auction; - - if( (auction = (struct auction_data *)idb_get(inter_auction->db, auction_id)) == NULL || auction->price >= bid || auction->seller_id == char_id ) - { - mapif->auction_bid(fd, char_id, bid, 0); // You have failed to bid in the auction - return; - } - - if( inter_auction->count(char_id, true) > 4 && bid < auction->buynow && auction->buyer_id != char_id ) - { - mapif->auction_bid(fd, char_id, bid, 9); // You cannot place more than 5 bids at a time - return; - } - - if( auction->buyer_id > 0 ) - { // Send Money back to the previous Buyer - if( auction->buyer_id != char_id ) - { - inter_mail->sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Someone has placed a higher bid.", auction->price, NULL); - mapif->auction_message(auction->buyer_id, 7); // You have failed to win the auction - } - else - inter_mail->sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "You have placed a higher bid.", auction->price, NULL); - } - - auction->buyer_id = char_id; - safestrncpy(auction->buyer_name, RFIFOP(fd,16), NAME_LENGTH); - auction->price = bid; - - if( bid >= auction->buynow ) - { // Automatic won the auction - mapif->auction_bid(fd, char_id, bid - auction->buynow, 1); // You have successfully bid in the auction - - inter_mail->sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "You have won the auction.", 0, &auction->item); - mapif->auction_message(char_id, 6); // You have won the auction - inter_mail->sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Payment for your auction!.", auction->buynow, NULL); - - inter_auction->delete_(auction); - return; - } - - inter_auction->save(auction); - - mapif->auction_bid(fd, char_id, 0, 1); // You have successfully bid in the auction -} - /*========================================== * Packets From Map Server *------------------------------------------*/ diff --git a/src/char/int_clan.c b/src/char/int_clan.c index e68f6a655..1b875d7e1 100644 --- a/src/char/int_clan.c +++ b/src/char/int_clan.c @@ -123,32 +123,6 @@ int inter_clan_count_members(int clan_id, int kick_interval) return count; } -int mapif_parse_ClanMemberCount(int fd, int clan_id, int kick_interval) -{ - - WFIFOHEAD(fd, 10); - WFIFOW(fd, 0) = 0x3858; - WFIFOL(fd, 2) = clan_id; - WFIFOL(fd, 6) = inter_clan->count_members(clan_id, kick_interval); - WFIFOSET(fd, 10); - return 0; -} - -int mapif_parse_ClanMemberKick(int fd, int clan_id, int kick_interval) -{ - int count = 0; - - if (inter_clan->kick_inactive_members(clan_id, kick_interval) == 1) - count = inter_clan->count_members(clan_id, kick_interval); - - WFIFOHEAD(fd, 10); - WFIFOW(fd, 0) = 0x3858; - WFIFOL(fd, 2) = clan_id; - WFIFOL(fd, 6) = count; - WFIFOSET(fd, 10); - return 0; -} - // Communication from the map server // - Can analyzed only one by one packet // Data packet length that you set to inter.c diff --git a/src/char/int_elemental.c b/src/char/int_elemental.c index f847d16ae..8aeb01704 100644 --- a/src/char/int_elemental.c +++ b/src/char/int_elemental.c @@ -50,7 +50,7 @@ struct inter_elemental_interface *inter_elemental; * @param[in,out] ele The new elemental's data. * @retval false in case of errors. */ -bool mapif_elemental_create(struct s_elemental *ele) +bool inter_elemental_create(struct s_elemental *ele) { nullpo_retr(false, ele); Assert_retr(false, ele->elemental_id == 0); @@ -73,7 +73,7 @@ bool mapif_elemental_create(struct s_elemental *ele) * @param ele The elemental's data. * @retval false in case of errors. */ -bool mapif_elemental_save(const struct s_elemental *ele) +bool inter_elemental_save(const struct s_elemental *ele) { nullpo_retr(false, ele); Assert_retr(false, ele->elemental_id > 0); @@ -90,7 +90,8 @@ bool mapif_elemental_save(const struct s_elemental *ele) return true; } -bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) { +bool inter_elemental_load(int ele_id, int char_id, struct s_elemental *ele) +{ char* data; nullpo_retr(false, ele); @@ -134,7 +135,8 @@ bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) { return true; } -bool mapif_elemental_delete(int ele_id) { +bool inter_elemental_delete(int ele_id) +{ if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `ele_id` = '%d'", elemental_db, ele_id) ) { Sql_ShowDebug(inter->sql_handle); return false; @@ -143,60 +145,6 @@ bool mapif_elemental_delete(int ele_id) { return true; } -void mapif_elemental_send(int fd, struct s_elemental *ele, unsigned char flag) { - int size = sizeof(struct s_elemental) + 5; - - nullpo_retv(ele); - WFIFOHEAD(fd,size); - WFIFOW(fd,0) = 0x387c; - WFIFOW(fd,2) = size; - WFIFOB(fd,4) = flag; - memcpy(WFIFOP(fd,5),ele,sizeof(struct s_elemental)); - WFIFOSET(fd,size); -} - -void mapif_parse_elemental_create(int fd, const struct s_elemental *ele) -{ - struct s_elemental ele_; - bool result; - - memcpy(&ele_, ele, sizeof(ele_)); - - result = mapif->elemental_create(&ele_); - mapif->elemental_send(fd, &ele_, result); -} - -void mapif_parse_elemental_load(int fd, int ele_id, int char_id) { - struct s_elemental ele; - bool result = mapif->elemental_load(ele_id, char_id, &ele); - mapif->elemental_send(fd, &ele, result); -} - -void mapif_elemental_deleted(int fd, unsigned char flag) { - WFIFOHEAD(fd,3); - WFIFOW(fd,0) = 0x387d; - WFIFOB(fd,2) = flag; - WFIFOSET(fd,3); -} - -void mapif_parse_elemental_delete(int fd, int ele_id) { - bool result = mapif->elemental_delete(ele_id); - mapif->elemental_deleted(fd, result); -} - -void mapif_elemental_saved(int fd, unsigned char flag) { - WFIFOHEAD(fd,3); - WFIFOW(fd,0) = 0x387e; - WFIFOB(fd,2) = flag; - WFIFOSET(fd,3); -} - -void mapif_parse_elemental_save(int fd, const struct s_elemental *ele) -{ - bool result = mapif->elemental_save(ele); - mapif->elemental_saved(fd, result); -} - void inter_elemental_sql_init(void) { return; } @@ -229,4 +177,9 @@ void inter_elemental_defaults(void) inter_elemental->sql_init = inter_elemental_sql_init; inter_elemental->sql_final = inter_elemental_sql_final; inter_elemental->parse_frommap = inter_elemental_parse_frommap; + + inter_elemental->create = inter_elemental_create; + inter_elemental->save = inter_elemental_save; + inter_elemental->load = inter_elemental_load; + inter_elemental->delete = inter_elemental_delete; } diff --git a/src/char/int_elemental.h b/src/char/int_elemental.h index 646009b50..3172dcacf 100644 --- a/src/char/int_elemental.h +++ b/src/char/int_elemental.h @@ -22,6 +22,7 @@ #define CHAR_INT_ELEMENTAL_H #include "common/hercules.h" +#include "common/mmo.h" /** * inter_elemental_interface interface @@ -30,6 +31,11 @@ struct inter_elemental_interface { void (*sql_init) (void); void (*sql_final) (void); int (*parse_frommap) (int fd); + + bool (*create) (struct s_elemental *ele); + bool (*save) (const struct s_elemental *ele); + bool (*load) (int ele_id, int char_id, struct s_elemental *ele); + bool (*delete) (int ele_id); }; #ifdef HERCULES_CORE diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 38c79ec28..c74c7f008 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -891,277 +891,7 @@ int inter_guild_calcinfo(struct guild *g) return 0; } -//------------------------------------------------------------------- -// Packet sent to map server - -int mapif_guild_created(int fd, int account_id, struct guild *g) -{ - WFIFOHEAD(fd, 10); - WFIFOW(fd,0)=0x3830; - WFIFOL(fd,2)=account_id; - if(g != NULL) - { - WFIFOL(fd,6)=g->guild_id; - ShowInfo("int_guild: Guild created (%d - %s)\n",g->guild_id,g->name); - } else - WFIFOL(fd,6)=0; - - WFIFOSET(fd,10); - return 0; -} - -// Guild not found -int mapif_guild_noinfo(int fd, int guild_id) -{ - unsigned char buf[12]; - WBUFW(buf,0)=0x3831; - WBUFW(buf,2)=8; - WBUFL(buf,4)=guild_id; - ShowWarning("int_guild: info not found %d\n",guild_id); - if(fd<0) - mapif->sendall(buf,8); - else - mapif->send(fd,buf,8); - return 0; -} - -// Send guild info -int mapif_guild_info(int fd, struct guild *g) -{ - unsigned char buf[8+sizeof(struct guild)]; - nullpo_ret(g); - WBUFW(buf,0)=0x3831; - WBUFW(buf,2)=4+sizeof(struct guild); - memcpy(buf+4,g,sizeof(struct guild)); - if(fd<0) - mapif->sendall(buf,WBUFW(buf,2)); - else - mapif->send(fd,buf,WBUFW(buf,2)); - return 0; -} - -// ACK member add -int mapif_guild_memberadded(int fd, int guild_id, int account_id, int char_id, int flag) -{ - WFIFOHEAD(fd, 15); - WFIFOW(fd,0)=0x3832; - WFIFOL(fd,2)=guild_id; - WFIFOL(fd,6)=account_id; - WFIFOL(fd,10)=char_id; - WFIFOB(fd,14)=flag; - WFIFOSET(fd,15); - return 0; -} - -// ACK member leave -int mapif_guild_withdraw(int guild_id,int account_id,int char_id,int flag, const char *name, const char *mes) -{ - unsigned char buf[55+NAME_LENGTH]; - - nullpo_ret(name); - nullpo_ret(mes); - - WBUFW(buf, 0)=0x3834; - WBUFL(buf, 2)=guild_id; - WBUFL(buf, 6)=account_id; - WBUFL(buf,10)=char_id; - WBUFB(buf,14)=flag; - memcpy(WBUFP(buf,15),mes,40); - memcpy(WBUFP(buf,55),name,NAME_LENGTH); - mapif->sendall(buf,55+NAME_LENGTH); - ShowInfo("int_guild: guild withdraw (%d - %d: %s - %s)\n",guild_id,account_id,name,mes); - return 0; -} - -// Send short member's info -int mapif_guild_memberinfoshort(struct guild *g, int idx) -{ - unsigned char buf[23]; - nullpo_ret(g); - Assert_ret(idx >= 0 && idx < MAX_GUILD); - WBUFW(buf, 0)=0x3835; - WBUFL(buf, 2)=g->guild_id; - WBUFL(buf, 6)=g->member[idx].account_id; - WBUFL(buf,10)=g->member[idx].char_id; - WBUFB(buf,14)=(unsigned char)g->member[idx].online; - WBUFW(buf,15)=g->member[idx].lv; - WBUFW(buf,17)=g->member[idx].class; - WBUFL(buf,19)=g->member[idx].last_login; - mapif->sendall(buf,23); - return 0; -} - -// Send guild broken -int mapif_guild_broken(int guild_id, int flag) -{ - unsigned char buf[7]; - WBUFW(buf,0)=0x3836; - WBUFL(buf,2)=guild_id; - WBUFB(buf,6)=flag; - mapif->sendall(buf,7); - ShowInfo("int_guild: Guild broken (%d)\n",guild_id); - return 0; -} - -// Send guild message -int mapif_guild_message(int guild_id, int account_id, const char *mes, int len, int sfd) -{ - unsigned char buf[512]; - nullpo_ret(mes); - if (len > 500) - len = 500; - WBUFW(buf,0)=0x3837; - WBUFW(buf,2)=len+12; - WBUFL(buf,4)=guild_id; - WBUFL(buf,8)=account_id; - memcpy(WBUFP(buf,12),mes,len); - mapif->sendallwos(sfd, buf,len+12); - return 0; -} - -// Send basic info -int mapif_guild_basicinfochanged(int guild_id, int type, const void *data, int len) -{ - unsigned char buf[2048]; - nullpo_ret(data); - if (len > 2038) - len = 2038; - WBUFW(buf, 0)=0x3839; - WBUFW(buf, 2)=len+10; - WBUFL(buf, 4)=guild_id; - WBUFW(buf, 8)=type; - memcpy(WBUFP(buf,10),data,len); - mapif->sendall(buf,len+10); - return 0; -} - -// Send member info -int mapif_guild_memberinfochanged(int guild_id, int account_id, int char_id, int type, const void *data, int len) -{ - unsigned char buf[2048]; - nullpo_ret(data); - if (len > 2030) - len = 2030; - WBUFW(buf, 0)=0x383a; - WBUFW(buf, 2)=len+18; - WBUFL(buf, 4)=guild_id; - WBUFL(buf, 8)=account_id; - WBUFL(buf,12)=char_id; - WBUFW(buf,16)=type; - memcpy(WBUFP(buf,18),data,len); - mapif->sendall(buf,len+18); - return 0; -} - -// ACK guild skill up -int mapif_guild_skillupack(int guild_id, uint16 skill_id, int account_id) -{ - unsigned char buf[14]; - WBUFW(buf, 0)=0x383c; - WBUFL(buf, 2)=guild_id; - WBUFL(buf, 6)=skill_id; - WBUFL(buf,10)=account_id; - mapif->sendall(buf,14); - return 0; -} - -// ACK guild alliance -int mapif_guild_alliance(int guild_id1, int guild_id2, int account_id1, int account_id2, int flag, const char *name1, const char *name2) -{ - unsigned char buf[19+2*NAME_LENGTH]; - nullpo_ret(name1); - nullpo_ret(name2); - WBUFW(buf, 0)=0x383d; - WBUFL(buf, 2)=guild_id1; - WBUFL(buf, 6)=guild_id2; - WBUFL(buf,10)=account_id1; - WBUFL(buf,14)=account_id2; - WBUFB(buf,18)=flag; - memcpy(WBUFP(buf,19),name1,NAME_LENGTH); - memcpy(WBUFP(buf,19+NAME_LENGTH),name2,NAME_LENGTH); - mapif->sendall(buf,19+2*NAME_LENGTH); - return 0; -} - -// Send a guild position desc -int mapif_guild_position(struct guild *g, int idx) -{ - unsigned char buf[12 + sizeof(struct guild_position)]; - nullpo_ret(g); - Assert_ret(idx >= 0 && idx < MAX_GUILDPOSITION); - WBUFW(buf,0)=0x383b; - WBUFW(buf,2)=sizeof(struct guild_position)+12; - WBUFL(buf,4)=g->guild_id; - WBUFL(buf,8)=idx; - memcpy(WBUFP(buf,12),&g->position[idx],sizeof(struct guild_position)); - mapif->sendall(buf,WBUFW(buf,2)); - return 0; -} - -// Send the guild notice -int mapif_guild_notice(struct guild *g) -{ - unsigned char buf[256]; - nullpo_ret(g); - WBUFW(buf,0)=0x383e; - WBUFL(buf,2)=g->guild_id; - memcpy(WBUFP(buf,6),g->mes1,MAX_GUILDMES1); - memcpy(WBUFP(buf,66),g->mes2,MAX_GUILDMES2); - mapif->sendall(buf,186); - return 0; -} - -// Send emblem data -int mapif_guild_emblem(struct guild *g) -{ - unsigned char buf[12 + sizeof(g->emblem_data)]; - nullpo_ret(g); - WBUFW(buf,0)=0x383f; - WBUFW(buf,2)=g->emblem_len+12; - WBUFL(buf,4)=g->guild_id; - WBUFL(buf,8)=g->emblem_id; - memcpy(WBUFP(buf,12),g->emblem_data,g->emblem_len); - mapif->sendall(buf,WBUFW(buf,2)); - return 0; -} - -int mapif_guild_master_changed(struct guild *g, int aid, int cid) -{ - unsigned char buf[14]; - nullpo_ret(g); - WBUFW(buf,0)=0x3843; - WBUFL(buf,2)=g->guild_id; - WBUFL(buf,6)=aid; - WBUFL(buf,10)=cid; - mapif->sendall(buf,14); - return 0; -} - -int mapif_guild_castle_dataload(int fd, int sz, const int *castle_ids) -{ - struct guild_castle *gc = NULL; - int num = (sz - 4) / sizeof(int); - int len = 4 + num * sizeof(*gc); - int i; - - nullpo_ret(castle_ids); - WFIFOHEAD(fd, len); - WFIFOW(fd, 0) = 0x3840; - WFIFOW(fd, 2) = len; - for (i = 0; i < num; i++) { - gc = inter_guild->castle_fromsql(*(castle_ids++)); - memcpy(WFIFOP(fd, 4 + i * sizeof(*gc)), gc, sizeof(*gc)); - } - WFIFOSET(fd, len); - return 0; -} - -//------------------------------------------------------------------- -// Packet received from map server - - -// Guild creation request -int mapif_parse_CreateGuild(int fd, int account_id, const char *name, const struct guild_member *master) +struct guild *inter_guild_create(const char *name, const struct guild_member *master) { struct guild *g; int i=0; @@ -1172,21 +902,18 @@ int mapif_parse_CreateGuild(int fd, int account_id, const char *name, const stru nullpo_ret(master); if(inter_guild->search_guildname(name) != 0){ ShowInfo("int_guild: guild with same name exists [%s]\n",name); - mapif->guild_created(fd,account_id,NULL); - return 0; + return NULL; } // Check Authorized letters/symbols in the name of the character if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorized for (i = 0; i < NAME_LENGTH && name[i]; i++) if (strchr(char_name_letters, name[i]) == NULL) { - mapif->guild_created(fd,account_id,NULL); - return 0; + return NULL; } } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden for (i = 0; i < NAME_LENGTH && name[i]; i++) if (strchr(char_name_letters, name[i]) != NULL) { - mapif->guild_created(fd,account_id,NULL); - return 0; + return NULL; } } @@ -1222,108 +949,79 @@ int mapif_parse_CreateGuild(int fd, int account_id, const char *name, const stru if (!inter_guild->tosql(g,GS_BASIC|GS_POSITION|GS_SKILL|GS_MEMBER)) { //Failed to Create guild.... ShowError("Failed to create Guild %s (Guild Master: %s)\n", g->name, g->master); - mapif->guild_created(fd,account_id,NULL); aFree(g); - return 0; + return NULL; } ShowInfo("Created Guild %d - %s (Guild Master: %s)\n", g->guild_id, g->name, g->master); //Add to cache idb_put(inter_guild->guild_db, g->guild_id, g); - // Report to client - mapif->guild_created(fd,account_id,g); - mapif->guild_info(fd,g); - if (inter->enable_logs) inter->log("guild %s (id=%d) created by master %s (id=%d)\n", name, g->guild_id, master->name, master->account_id); - return 0; -} - -// Return guild info to client -int mapif_parse_GuildInfo(int fd, int guild_id) -{ - struct guild * g = inter_guild->fromsql(guild_id); //We use this because on start-up the info of castle-owned guilds is required. [Skotlex] - if(g) - { - if (!inter_guild->calcinfo(g)) - mapif->guild_info(fd,g); - } - else - mapif->guild_noinfo(fd,guild_id); // Failed to load info - return 0; + return g; } // Add member to guild -int mapif_parse_GuildAddMember(int fd, int guild_id, const struct guild_member *m) +bool inter_guild_add_member(int guild_id, const struct guild_member *member) { struct guild * g; int i; + nullpo_ret(member); - nullpo_ret(m); g = inter_guild->fromsql(guild_id); - if(g==NULL){ - mapif->guild_memberadded(fd,guild_id,m->account_id,m->char_id,1); // 1: Failed to add - return 0; - } + if (g == NULL) + return false; // Find an empty slot - for(i=0;i<g->max_member;i++) - { - if(g->member[i].account_id==0) - { - memcpy(&g->member[i],m,sizeof(struct guild_member)); + for (i = 0; i < g->max_member; i++) { + if (g->member[i].account_id == 0) { + g->member[i] = *member; g->member[i].modified = (GS_MEMBER_NEW | GS_MEMBER_MODIFIED); - mapif->guild_memberadded(fd,guild_id,m->account_id,m->char_id,0); // 0: success if (!inter_guild->calcinfo(g)) //Send members if it was not invoked. - mapif->guild_info(-1,g); + mapif->guild_info(-1, g); g->save_flag |= GS_MEMBER; if (g->save_flag&GS_REMOVE) g->save_flag&=~GS_REMOVE; - return 0; + return true; } } - - mapif->guild_memberadded(fd,guild_id,m->account_id,m->char_id,1); // 1: Failed to add - return 0; + return false; } // Delete member from guild -int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, int flag, const char *mes) +bool inter_guild_leave(int guild_id, int account_id, int char_id, int flag, const char *mes, int map_fd) { int i; - struct guild* g = inter_guild->fromsql(guild_id); - if( g == NULL ) - { + struct guild *g = inter_guild->fromsql(guild_id); + if (g == NULL) { // Unknown guild, just update the player - if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `account_id`='%d' AND `char_id`='%d'", char_db, account_id, char_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `account_id`='%d' AND `char_id`='%d'", char_db, account_id, char_id)) Sql_ShowDebug(inter->sql_handle); // mapif->guild_withdraw(guild_id,account_id,char_id,flag,g->member[i].name,mes); - return 0; + return false; } nullpo_ret(mes); // Find the member - ARR_FIND( 0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id ); - if( i == g->max_member ) - { + ARR_FIND(0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id); + if (i == g->max_member) { //TODO - return 0; + return false; } if (flag) { // Write expulsion reason // Find an empty slot int j; - ARR_FIND( 0, MAX_GUILDEXPULSION, j, g->expulsion[j].account_id == 0 ); - if( j == MAX_GUILDEXPULSION ) - { + ARR_FIND(0, MAX_GUILDEXPULSION, j, g->expulsion[j].account_id == 0); + if (j == MAX_GUILDEXPULSION) { // Expulsion list is full, flush the oldest one - for( j = 0; j < MAX_GUILDEXPULSION - 1; j++ ) + for (j = 0; j < MAX_GUILDEXPULSION - 1; j++) g->expulsion[j] = g->expulsion[j+1]; j = MAX_GUILDEXPULSION-1; } @@ -1338,39 +1036,38 @@ int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, in memset(&g->member[i],0,sizeof(struct guild_member)); - if( inter_guild->check_empty(g) ) - mapif->parse_BreakGuild(-1,guild_id); //Break the guild. - else { + if (inter_guild->check_empty(g)) { + inter_guild->disband(guild_id); + } else { //Update member info. if (!inter_guild->calcinfo(g)) - mapif->guild_info(fd,g); + mapif->guild_info(map_fd,g); g->save_flag |= GS_EXPULSION; } - return 0; + return true; } // Change member info -int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id, int char_id, int online, int lv, int16 class) +bool inter_guild_update_member_info_short(int guild_id, int account_id, int char_id, int online, int lv, int16 class) { // Could speed up by manipulating only guild_member - struct guild * g; + struct guild *g; int i,sum,c; int prev_count, prev_alv; g = inter_guild->fromsql(guild_id); - if(g==NULL) - return 0; + if (g == NULL) + return false; - ARR_FIND( 0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id ); - if( i < g->max_member ) - { + ARR_FIND(0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id); + if (i < g->max_member) { g->member[i].online = online; g->member[i].lv = lv; g->member[i].class = class; g->member[i].last_login = (uint32)time(NULL); g->member[i].modified = GS_MEMBER_MODIFIED; - mapif->guild_memberinfoshort(g,i); + mapif->guild_memberinfoshort(g, i); } prev_count = g->connect_member; @@ -1381,99 +1078,90 @@ int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id, c = 0; sum = 0; - for( i = 0; i < g->max_member; i++ ) - { - if( g->member[i].account_id > 0 ) - { + for (i = 0; i < g->max_member; i++) { + if (g->member[i].account_id > 0) { sum += g->member[i].lv; c++; } - if( g->member[i].online ) + if (g->member[i].online) g->connect_member++; } - if( c ) // this check should always succeed... - { + if (c != 0) { // this check should always succeed... g->average_lv = sum / c; - if( g->connect_member != prev_count || g->average_lv != prev_alv ) + if (g->connect_member != prev_count || g->average_lv != prev_alv) g->save_flag |= GS_CONNECT; - if( g->save_flag & GS_REMOVE ) + if (g->save_flag & GS_REMOVE) g->save_flag &= ~GS_REMOVE; } g->save_flag |= GS_MEMBER; //Update guild member data - return 0; + return true; } // BreakGuild -int mapif_parse_BreakGuild(int fd, int guild_id) +bool inter_guild_disband(int guild_id) { - struct guild * g; - - g = inter_guild->fromsql(guild_id); - if(g==NULL) - return 0; + struct guild *g = inter_guild->fromsql(guild_id); + if (g == NULL) + return false; // Delete guild from sql //printf("- Delete guild %d from guild\n",guild_id); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_db, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_db, guild_id)) Sql_ShowDebug(inter->sql_handle); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_member_db, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_member_db, guild_id)) Sql_ShowDebug(inter->sql_handle); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_castle_db, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_castle_db, guild_id)) Sql_ShowDebug(inter->sql_handle); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_storage_db, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_storage_db, guild_id)) Sql_ShowDebug(inter->sql_handle); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d' OR `alliance_id` = '%d'", guild_alliance_db, guild_id, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d' OR `alliance_id` = '%d'", guild_alliance_db, guild_id, guild_id)) Sql_ShowDebug(inter->sql_handle); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_position_db, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_position_db, guild_id)) Sql_ShowDebug(inter->sql_handle); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_skill_db, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_skill_db, guild_id)) Sql_ShowDebug(inter->sql_handle); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_expulsion_db, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `guild_id` = '%d'", guild_expulsion_db, guild_id)) Sql_ShowDebug(inter->sql_handle); //printf("- Update guild %d of char\n",guild_id); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'", char_db, guild_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `guild_id`='%d'", char_db, guild_id)) Sql_ShowDebug(inter->sql_handle); - mapif->guild_broken(guild_id,0); + mapif->guild_broken(guild_id, 0); if (inter->enable_logs) inter->log("guild %s (id=%d) broken\n", g->name, guild_id); //Remove the guild from memory. [Skotlex] idb_remove(inter_guild->guild_db, guild_id); - return 0; -} -// Forward Guild message to others map servers -int mapif_parse_GuildMessage(int fd, int guild_id, int account_id, const char *mes, int len) -{ - return mapif->guild_message(guild_id,account_id,mes,len, fd); + return true; } /** * Changes basic guild information * The types are available in mmo.h::guild_basic_info **/ -int mapif_parse_GuildBasicInfoChange(int fd, int guild_id, int type, const void *data, int len) { +bool inter_guild_update_basic_info(int guild_id, int type, const void *data, int len) +{ struct guild *g; struct guild_skill gd_skill; short value; g = inter_guild->fromsql(guild_id); - if( g == NULL ) - return 0; + if (g == NULL) + return false; nullpo_ret(data); - switch(type) { + switch (type) { case GBI_EXP: value = *((const int16 *)data); if( value < 0 && abs(value) > g->exp ) @@ -1509,26 +1197,25 @@ int mapif_parse_GuildBasicInfoChange(int fd, int guild_id, int type, const void default: ShowError("int_guild: GuildBasicInfoChange: Unknown type %d, see mmo.h::guild_basic_info for more information\n",type); - return 0; + return false; } mapif->guild_info(-1,g); g->save_flag |= GS_LEVEL; - // Information is already sent in mapif->guild_info - //mapif->guild_basicinfochanged(guild_id,type,data,len); - return 0; + + return true; } // Modification of the guild -int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int char_id, int type, const char *data, int len) +bool inter_guild_update_member_info(int guild_id, int account_id, int char_id, int type, const char *data, int len) { // Could make some improvement in speed, because only change guild_member int i; - struct guild * g; + struct guild *g; nullpo_ret(data); g = inter_guild->fromsql(guild_id); if(g==NULL) - return 0; + return false; // Search the member for (i = 0; i < g->max_member; i++) { @@ -1540,7 +1227,7 @@ int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int if(i==g->max_member){ ShowWarning("int_guild: GuildMemberChange: Not found %d,%d in guild (%d - %s)\n", account_id,char_id,guild_id,g->name); - return 0; + return false; } switch(type) @@ -1621,14 +1308,15 @@ int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int } default: ShowError("int_guild: GuildMemberInfoChange: Unknown type %d\n",type); + return false; break; } - return 0; + return true; } int inter_guild_sex_changed(int guild_id, int account_id, int char_id, short gender) { - return mapif->parse_GuildMemberInfoChange(0, guild_id, account_id, char_id, GMI_GENDER, (const char*)&gender, sizeof(gender)); + return inter_guild->update_member_info(guild_id, account_id, char_id, GMI_GENDER, (const char*)&gender, sizeof(gender)); } int inter_guild_charname_changed(int guild_id, int account_id, int char_id, char *name) @@ -1669,35 +1357,34 @@ int inter_guild_charname_changed(int guild_id, int account_id, int char_id, char } // Change a position desc -int mapif_parse_GuildPosition(int fd, int guild_id, int idx, const struct guild_position *p) +bool inter_guild_update_position(int guild_id, int idx, const struct guild_position *p) { // Could make some improvement in speed, because only change guild_position - struct guild * g; + struct guild *g; nullpo_ret(p); g = inter_guild->fromsql(guild_id); if(g==NULL || idx<0 || idx>=MAX_GUILDPOSITION) - return 0; + return false; memcpy(&g->position[idx],p,sizeof(struct guild_position)); mapif->guild_position(g,idx); g->position[idx].modified = GS_POSITION_MODIFIED; g->save_flag |= GS_POSITION; // Change guild_position - return 0; + return true; } // Guild Skill UP -int mapif_parse_GuildSkillUp(int fd, int guild_id, uint16 skill_id, int account_id, int max) +bool inter_guild_use_skill_point(int guild_id, uint16 skill_id, int account_id, int max) { struct guild * g; int idx = skill_id - GD_SKILLBASE; g = inter_guild->fromsql(guild_id); if(g == NULL || idx < 0 || idx >= MAX_GUILDSKILL) - return 0; + return false; - if(g->skill_point>0 && g->skill[idx].id>0 && g->skill[idx].lv<max ) - { + if (g->skill_point > 0 && g->skill[idx].id > 0 && g->skill[idx].lv < max) { g->skill[idx].lv++; g->skill_point--; if (!inter_guild->calcinfo(g)) @@ -1705,11 +1392,11 @@ int mapif_parse_GuildSkillUp(int fd, int guild_id, uint16 skill_id, int account_ mapif->guild_skillupack(guild_id,skill_id,account_id); g->save_flag |= (GS_LEVEL|GS_SKILL); // Change guild & guild_skill } - return 0; + return true; } //Manual deletion of an alliance when partnering guild does not exists. [Skotlex] -int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, int account_id1, int account_id2, int flag) +bool inter_guild_remove_alliance(struct guild *g, int guild_id, int account_id1, int account_id2, int flag) { int i; char name[NAME_LENGTH]; @@ -1717,18 +1404,18 @@ int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, int account_i nullpo_retr(-1, g); ARR_FIND( 0, MAX_GUILDALLIANCE, i, g->alliance[i].guild_id == guild_id ); if( i == MAX_GUILDALLIANCE ) - return -1; + return false; strcpy(name, g->alliance[i].name); g->alliance[i].guild_id=0; mapif->guild_alliance(g->guild_id,guild_id,account_id1,account_id2,flag,g->name,name); g->save_flag |= GS_ALLIANCE; - return 0; + return true; } // Alliance modification -int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_id1, int account_id2, int flag) +bool inter_guild_change_alliance(int guild_id1, int guild_id2, int account_id1, int account_id2, int flag) { // Could speed up struct guild *g[2] = { NULL }; @@ -1737,10 +1424,10 @@ int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_ g[1] = inter_guild->fromsql(guild_id2); if(g[0] && g[1]==NULL && (flag & GUILD_ALLIANCE_REMOVE)) //Requested to remove an alliance with a not found guild. - return mapif->parse_GuildDeleteAlliance(g[0], guild_id2, account_id1, account_id2, flag); //Try to do a manual removal of said guild. + return inter_guild->remove_alliance(g[0], guild_id2, account_id1, account_id2, flag); //Try to do a manual removal of said guild. if(g[0]==NULL || g[1]==NULL) - return 0; + return false; if( flag&GUILD_ALLIANCE_REMOVE ) { // Remove alliance/opposition, in case of alliance, remove on both side @@ -1769,11 +1456,11 @@ int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_ // Mark the two guild to be saved g[0]->save_flag |= GS_ALLIANCE; g[1]->save_flag |= GS_ALLIANCE; - return 0; + return true; } // Change guild message -int mapif_parse_GuildNotice(int fd, int guild_id, const char *mes1, const char *mes2) +bool inter_guild_update_notice(int guild_id, const char *mes1, const char *mes2) { struct guild *g; @@ -1781,22 +1468,23 @@ int mapif_parse_GuildNotice(int fd, int guild_id, const char *mes1, const char * nullpo_ret(mes2); g = inter_guild->fromsql(guild_id); if(g==NULL) - return 0; + return false; memcpy(g->mes1,mes1,MAX_GUILDMES1); memcpy(g->mes2,mes2,MAX_GUILDMES2); g->save_flag |= GS_MES; //Change mes of guild - return mapif->guild_notice(g); + mapif->guild_notice(g); + return true; } -int mapif_parse_GuildEmblem(int fd, int len, int guild_id, int dummy, const char *data) +bool inter_guild_update_emblem(int len, int guild_id, const char *data) { struct guild * g; nullpo_ret(data); g = inter_guild->fromsql(guild_id); if(g==NULL) - return 0; + return false; if (len > sizeof(g->emblem_data)) len = sizeof(g->emblem_data); @@ -1805,21 +1493,17 @@ int mapif_parse_GuildEmblem(int fd, int len, int guild_id, int dummy, const char g->emblem_len=len; g->emblem_id++; g->save_flag |= GS_EMBLEM; //Change guild - return mapif->guild_emblem(g); -} - -int mapif_parse_GuildCastleDataLoad(int fd, int len, const int *castle_ids) -{ - return mapif->guild_castle_dataload(fd, len, castle_ids); + mapif->guild_emblem(g); + return true; } -int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value) +bool inter_guild_update_castle_data(int castle_id, int index, int value) { struct guild_castle *gc = inter_guild->castle_fromsql(castle_id); if (gc == NULL) { - ShowError("mapif->parse_GuildCastleDataSave: castle id=%d not found\n", castle_id); - return 0; + ShowError("inter_guild->update_castle_data: castle id=%d not found\n", castle_id); + return false; } switch (index) { @@ -1845,14 +1529,14 @@ int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value) gc->guardian[index-10].visible = value; break; } - ShowError("mapif->parse_GuildCastleDataSave: not found index=%d\n", index); - return 0; + ShowError("inter_guild->update_castle_data: not found index=%d\n", index); + return false; } inter_guild->castle_tosql(gc); - return 0; + return true; } -int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int len) +bool inter_guild_change_leader(int guild_id, const char *name, int len) { struct guild * g; struct guild_member gm; @@ -1887,7 +1571,8 @@ int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int le ShowInfo("int_guild: Guildmaster Changed to %s (Guild %d - %s)\n",g->master, guild_id, g->name); g->save_flag |= (GS_BASIC|GS_MEMBER); //Save main data and member data. - return mapif->guild_master_changed(g, g->member[0].account_id, g->member[0].char_id); + mapif->guild_master_changed(g, g->member[0].account_id, g->member[0].char_id); + return true; } // Communication from the map server @@ -1926,12 +1611,6 @@ int inter_guild_parse_frommap(int fd) return 1; } -//Leave request from the server (for deleting character from guild) -int inter_guild_leave(int guild_id, int account_id, int char_id) -{ - return mapif->parse_GuildLeave(-1, guild_id, account_id, char_id, 0, "** Character Deleted **"); -} - int inter_guild_broken(int guild_id) { return mapif->guild_broken(guild_id, 0); @@ -1965,6 +1644,20 @@ void inter_guild_defaults(void) inter_guild->sex_changed = inter_guild_sex_changed; inter_guild->charname_changed = inter_guild_charname_changed; inter_guild->parse_frommap = inter_guild_parse_frommap; - inter_guild->leave = inter_guild_leave; inter_guild->broken = inter_guild_broken; + inter_guild->create = inter_guild_create; + inter_guild->add_member = inter_guild_add_member; + inter_guild->leave = inter_guild_leave; + inter_guild->update_member_info_short = inter_guild_update_member_info_short; + inter_guild->update_member_info = inter_guild_update_member_info; + inter_guild->disband = inter_guild_disband; + inter_guild->update_basic_info = inter_guild_update_basic_info; + inter_guild->update_position = inter_guild_update_position; + inter_guild->use_skill_point = inter_guild_use_skill_point; + inter_guild->remove_alliance = inter_guild_remove_alliance; + inter_guild->change_alliance = inter_guild_change_alliance; + inter_guild->update_notice = inter_guild_update_notice; + inter_guild->update_emblem = inter_guild_update_emblem; + inter_guild->update_castle_data = inter_guild_update_castle_data; + inter_guild->change_leader = inter_guild_change_leader; } diff --git a/src/char/int_guild.h b/src/char/int_guild.h index 6fefba598..2af8f6801 100644 --- a/src/char/int_guild.h +++ b/src/char/int_guild.h @@ -68,8 +68,22 @@ struct inter_guild_interface { int (*sex_changed) (int guild_id, int account_id, int char_id, short gender); int (*charname_changed) (int guild_id, int account_id, int char_id, char *name); int (*parse_frommap) (int fd); - int (*leave) (int guild_id, int account_id, int char_id); int (*broken) (int guild_id); + struct guild *(*create) (const char *name, const struct guild_member *master); + bool (*add_member) (int guild_id, const struct guild_member *member); + bool (*leave) (int guild_id, int account_id, int char_id, int flag, const char *mes, int map_fd); + bool (*update_member_info_short) (int guild_id, int account_id, int char_id, int online, int lv, int16 class); + bool (*update_member_info) (int guild_id, int account_id, int char_id, int type, const char *data, int len); + bool (*disband) (int guild_id); + bool (*update_basic_info) (int guild_id, int type, const void *data, int len); + bool (*update_position) (int guild_id, int idx, const struct guild_position *p); + bool (*use_skill_point) (int guild_id, uint16 skill_id, int account_id, int max); + bool (*remove_alliance) (struct guild *g, int guild_id, int account_id1, int account_id2, int flag); + bool (*change_alliance) (int guild_id1, int guild_id2, int account_id1, int account_id2, int flag); + bool (*update_notice) (int guild_id, const char *mes1, const char *mes2); + bool (*update_emblem) (int len, int guild_id, const char *data); + bool (*update_castle_data) (int castle_id, int index, int value); + bool (*change_leader) (int guild_id, const char *name, int len); }; #ifdef HERCULES_CORE diff --git a/src/char/int_homun.c b/src/char/int_homun.c index 1844c8182..28ec848be 100644 --- a/src/char/int_homun.c +++ b/src/char/int_homun.c @@ -49,66 +49,6 @@ void inter_homunculus_sql_final(void) return; } -void mapif_homunculus_created(int fd, int account_id, const struct s_homunculus *sh, unsigned char flag) -{ - nullpo_retv(sh); - WFIFOHEAD(fd, sizeof(struct s_homunculus)+9); - WFIFOW(fd,0) = 0x3890; - WFIFOW(fd,2) = sizeof(struct s_homunculus)+9; - WFIFOL(fd,4) = account_id; - WFIFOB(fd,8)= flag; - memcpy(WFIFOP(fd,9),sh,sizeof(struct s_homunculus)); - WFIFOSET(fd, WFIFOW(fd,2)); -} - -void mapif_homunculus_deleted(int fd, int flag) -{ - WFIFOHEAD(fd, 3); - WFIFOW(fd, 0) = 0x3893; - WFIFOB(fd,2) = flag; //Flag 1 = success - WFIFOSET(fd, 3); -} - -void mapif_homunculus_loaded(int fd, int account_id, struct s_homunculus *hd) -{ - WFIFOHEAD(fd, sizeof(struct s_homunculus)+9); - WFIFOW(fd,0) = 0x3891; - WFIFOW(fd,2) = sizeof(struct s_homunculus)+9; - WFIFOL(fd,4) = account_id; - if( hd != NULL ) - { - WFIFOB(fd,8) = 1; // success - memcpy(WFIFOP(fd,9), hd, sizeof(struct s_homunculus)); - } - else - { - WFIFOB(fd,8) = 0; // not found. - memset(WFIFOP(fd,9), 0, sizeof(struct s_homunculus)); - } - WFIFOSET(fd, sizeof(struct s_homunculus)+9); -} - -void mapif_homunculus_saved(int fd, int account_id, bool flag) -{ - WFIFOHEAD(fd, 7); - WFIFOW(fd,0) = 0x3892; - WFIFOL(fd,2) = account_id; - WFIFOB(fd,6) = flag; // 1:success, 0:failure - WFIFOSET(fd, 7); -} - -void mapif_homunculus_renamed(int fd, int account_id, int char_id, unsigned char flag, const char *name) -{ - nullpo_retv(name); - WFIFOHEAD(fd, NAME_LENGTH+12); - WFIFOW(fd, 0) = 0x3894; - WFIFOL(fd, 2) = account_id; - WFIFOL(fd, 6) = char_id; - WFIFOB(fd,10) = flag; - safestrncpy(WFIFOP(fd,11), name, NAME_LENGTH); - WFIFOSET(fd, NAME_LENGTH+12); -} - /** * Creates a new homunculus with the given data. * @@ -119,7 +59,7 @@ void mapif_homunculus_renamed(int fd, int account_id, int char_id, unsigned char * @param[in,out] hd The new homunculus' data. * @retval false in case of errors. */ -bool mapif_homunculus_create(struct s_homunculus *hd) +bool inter_homunculus_create(struct s_homunculus *hd) { char esc_name[NAME_LENGTH*2+1]; @@ -146,7 +86,7 @@ bool mapif_homunculus_create(struct s_homunculus *hd) * @param hd The homunculus' data. * @retval false in case of errors. */ -bool mapif_homunculus_save(const struct s_homunculus *hd) +bool inter_homunculus_save(const struct s_homunculus *hd) { bool flag = true; char esc_name[NAME_LENGTH*2+1]; @@ -188,7 +128,7 @@ bool mapif_homunculus_save(const struct s_homunculus *hd) } // Load an homunculus -bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd) +bool inter_homunculus_load(int homun_id, struct s_homunculus* hd) { char* data; size_t len; @@ -269,7 +209,7 @@ bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd) return true; } -bool mapif_homunculus_delete(int homun_id) +bool inter_homunculus_delete(int homun_id) { if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%d'", homunculus_db, homun_id) || SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `homun_id` = '%d'", skill_homunculus_db, homun_id) @@ -280,7 +220,7 @@ bool mapif_homunculus_delete(int homun_id) return true; } -bool mapif_homunculus_rename(const char *name) +bool inter_homunculus_rename(const char *name) { int i; @@ -302,43 +242,6 @@ bool mapif_homunculus_rename(const char *name) return true; } - -void mapif_parse_homunculus_create(int fd, int len, int account_id, const struct s_homunculus *phd) -{ - struct s_homunculus shd; - bool result; - - memcpy(&shd, phd, sizeof(shd)); - - result = mapif->homunculus_create(&shd); - mapif->homunculus_created(fd, account_id, &shd, result); -} - -void mapif_parse_homunculus_delete(int fd, int homun_id) -{ - bool result = mapif->homunculus_delete(homun_id); - mapif->homunculus_deleted(fd, result); -} - -void mapif_parse_homunculus_load(int fd, int account_id, int homun_id) -{ - struct s_homunculus hd; - bool result = mapif->homunculus_load(homun_id, &hd); - mapif->homunculus_loaded(fd, account_id, ( result ? &hd : NULL )); -} - -void mapif_parse_homunculus_save(int fd, int len, int account_id, const struct s_homunculus *phd) -{ - bool result = mapif->homunculus_save(phd); - mapif->homunculus_saved(fd, account_id, result); -} - -void mapif_parse_homunculus_rename(int fd, int account_id, int char_id, const char *name) -{ - bool result = mapif->homunculus_rename(name); - mapif->homunculus_renamed(fd, account_id, char_id, result, name); -} - /*========================================== * Inter Packets *------------------------------------------*/ @@ -365,4 +268,10 @@ void inter_homunculus_defaults(void) inter_homunculus->sql_init = inter_homunculus_sql_init; inter_homunculus->sql_final = inter_homunculus_sql_final; inter_homunculus->parse_frommap = inter_homunculus_parse_frommap; + + inter_homunculus->create = inter_homunculus_create; + inter_homunculus->save = inter_homunculus_save; + inter_homunculus->load = inter_homunculus_load; + inter_homunculus->delete = inter_homunculus_delete; + inter_homunculus->rename = inter_homunculus_rename; } diff --git a/src/char/int_homun.h b/src/char/int_homun.h index fbd9d0eb9..8eba66963 100644 --- a/src/char/int_homun.h +++ b/src/char/int_homun.h @@ -22,6 +22,7 @@ #define CHAR_INT_HOMUN_H #include "common/hercules.h" +#include "common/mmo.h" /** * inter_homunculus interface @@ -30,6 +31,12 @@ struct inter_homunculus_interface { int (*sql_init) (void); void (*sql_final) (void); int (*parse_frommap) (int fd); + + bool (*create) (struct s_homunculus *hd); + bool (*save) (const struct s_homunculus *hd); + bool (*load) (int homun_id, struct s_homunculus* hd); + bool (*delete) (int homun_id); + bool (*rename) (const char *name); }; #ifdef HERCULES_CORE diff --git a/src/char/int_mail.c b/src/char/int_mail.c index 29c90b7c0..a20446710 100644 --- a/src/char/int_mail.c +++ b/src/char/int_mail.c @@ -242,40 +242,16 @@ static bool inter_mail_loadmessage(int mail_id, struct mail_message* msg) return true; } -void mapif_mail_sendinbox(int fd, int char_id, unsigned char flag, struct mail_data *md) -{ - nullpo_retv(md); - //FIXME: dumping the whole structure like this is unsafe [ultramage] - WFIFOHEAD(fd, sizeof(struct mail_data) + 9); - WFIFOW(fd,0) = 0x3848; - WFIFOW(fd,2) = sizeof(struct mail_data) + 9; - WFIFOL(fd,4) = char_id; - WFIFOB(fd,8) = flag; - memcpy(WFIFOP(fd,9),md,sizeof(struct mail_data)); - WFIFOSET(fd,WFIFOW(fd,2)); -} - -/*========================================== - * 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); -} - /*========================================== * Mark mail as 'Read' *------------------------------------------*/ -void mapif_parse_mail_read(int fd) +bool inter_mail_mark_read(int mail_id) { - int mail_id = RFIFOL(fd,2); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_READ, mail_id) ) + if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_READ, mail_id)) { Sql_ShowDebug(inter->sql_handle); + return false; + } + return true; } /*========================================== @@ -305,191 +281,100 @@ static bool inter_mail_DeleteAttach(int mail_id) return true; } -void mapif_mail_sendattach(int fd, int char_id, struct mail_message *msg) +bool inter_mail_get_attachment(int char_id, int mail_id, struct mail_message *msg) { - nullpo_retv(msg); - WFIFOHEAD(fd, sizeof(struct item) + 12); - WFIFOW(fd,0) = 0x384a; - WFIFOW(fd,2) = sizeof(struct item) + 12; - WFIFOL(fd,4) = char_id; - WFIFOL(fd,8) = (msg->zeny > 0)?msg->zeny:0; - memcpy(WFIFOP(fd,12), &msg->item, sizeof(struct item)); - WFIFOSET(fd,WFIFOW(fd,2)); -} - -void mapif_mail_getattach(int fd, int char_id, int mail_id) -{ - struct mail_message msg; - memset(&msg, 0, sizeof(msg)); + nullpo_retr(false, msg); - if( !inter_mail->loadmessage(mail_id, &msg) ) - return; - - if( msg.dest_id != char_id ) - return; - - if( msg.status != MAIL_READ ) - return; + if (!inter_mail->loadmessage(mail_id, msg)) + return false; - if( (msg.item.nameid < 1 || msg.item.amount < 1) && msg.zeny < 1 ) - return; // No Attachment + if (msg->dest_id != char_id) + return false; - if( !inter_mail->DeleteAttach(mail_id) ) - return; + if (msg->status != MAIL_READ) + return false; - mapif->mail_sendattach(fd, char_id, &msg); -} + if ((msg->item.nameid < 1 || msg->item.amount < 1) && msg->zeny < 1) + return false; // No Attachment -void mapif_parse_mail_getattach(int fd) -{ - mapif->mail_getattach(fd, RFIFOL(fd,2), RFIFOL(fd,6)); -} + if (!inter_mail->DeleteAttach(mail_id)) + return false; -/*========================================== - * Delete Mail - *------------------------------------------*/ -void mapif_mail_delete(int fd, int char_id, int mail_id, bool failed) -{ - WFIFOHEAD(fd,11); - WFIFOW(fd,0) = 0x384b; - WFIFOL(fd,2) = char_id; - WFIFOL(fd,6) = mail_id; - WFIFOB(fd,10) = failed; - WFIFOSET(fd,11); + return true; } -void mapif_parse_mail_delete(int fd) +bool inter_mail_delete(int char_id, int mail_id) { - int char_id = RFIFOL(fd,2); - int mail_id = RFIFOL(fd,6); - bool failed = false; - if ( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) ) - { + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id)) { Sql_ShowDebug(inter->sql_handle); - failed = true; + return false; } - mapif->mail_delete(fd, char_id, mail_id, failed); + return true; } -/*========================================== - * Report New Mail to Map Server - *------------------------------------------*/ -void mapif_mail_new(struct mail_message *msg) +bool inter_mail_return_message(int char_id, int mail_id, int *new_mail) { - unsigned char buf[74]; - - 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); - mapif->sendall(buf, 74); -} + struct mail_message msg; + nullpo_retr(false, new_mail); -/*========================================== - * Return Mail - *------------------------------------------*/ -void mapif_mail_return(int fd, int char_id, int mail_id, int new_mail) -{ - WFIFOHEAD(fd,11); - WFIFOW(fd,0) = 0x384c; - WFIFOL(fd,2) = char_id; - WFIFOL(fd,6) = mail_id; - WFIFOB(fd,10) = (new_mail == 0); - WFIFOSET(fd,11); -} + if (!inter_mail->loadmessage(mail_id, &msg)) + return false; -void mapif_parse_mail_return(int fd) -{ - int char_id = RFIFOL(fd,2); - int mail_id = RFIFOL(fd,6); - struct mail_message msg; - int new_mail = 0; + if (msg.dest_id != char_id) + return false; - if( inter_mail->loadmessage(mail_id, &msg) ) - { - if( msg.dest_id != char_id) - return; - else if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) ) - Sql_ShowDebug(inter->sql_handle); - else - { - char temp_[MAIL_TITLE_LENGTH]; + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id)) { + Sql_ShowDebug(inter->sql_handle); + } else { + char temp_[MAIL_TITLE_LENGTH]; - // swap sender and receiver - swap(msg.send_id, msg.dest_id); - safestrncpy(temp_, msg.send_name, NAME_LENGTH); - safestrncpy(msg.send_name, msg.dest_name, NAME_LENGTH); - safestrncpy(msg.dest_name, temp_, NAME_LENGTH); + // swap sender and receiver + swap(msg.send_id, msg.dest_id); + safestrncpy(temp_, msg.send_name, NAME_LENGTH); + safestrncpy(msg.send_name, msg.dest_name, NAME_LENGTH); + safestrncpy(msg.dest_name, temp_, NAME_LENGTH); - // set reply message title - safesnprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title); - safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH); + // set reply message title + safesnprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title); + safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH); - msg.status = MAIL_NEW; - msg.timestamp = time(NULL); + msg.status = MAIL_NEW; + msg.timestamp = time(NULL); - new_mail = inter_mail->savemessage(&msg); - mapif->mail_new(&msg); - } + *new_mail = inter_mail->savemessage(&msg); + mapif->mail_new(&msg); } - mapif->mail_return(fd, char_id, mail_id, new_mail); -} + return true; -/*========================================== - * Send Mail - *------------------------------------------*/ -void mapif_mail_send(int fd, struct mail_message* msg) -{ - int len = sizeof(struct mail_message) + 4; - - nullpo_retv(msg); - WFIFOHEAD(fd,len); - WFIFOW(fd,0) = 0x384d; - WFIFOW(fd,2) = len; - memcpy(WFIFOP(fd,4), msg, sizeof(struct mail_message)); - WFIFOSET(fd,len); } -void mapif_parse_mail_send(int fd) +bool inter_mail_send(int account_id, struct mail_message *msg) { - struct mail_message msg; char esc_name[NAME_LENGTH*2+1]; - int account_id = 0; - if(RFIFOW(fd,2) != 8 + sizeof(struct mail_message)) - return; - - account_id = RFIFOL(fd,4); - memcpy(&msg, RFIFOP(fd,8), sizeof(struct mail_message)); + nullpo_retr(false, msg); // Try to find the Dest Char by Name - SQL->EscapeStringLen(inter->sql_handle, esc_name, msg.dest_name, strnlen(msg.dest_name, NAME_LENGTH)); - if ( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `account_id`, `char_id` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) ) + SQL->EscapeStringLen(inter->sql_handle, esc_name, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH)); + if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `account_id`, `char_id` FROM `%s` WHERE `name` = '%s'", char_db, esc_name)) { Sql_ShowDebug(inter->sql_handle); - else - if ( SQL_SUCCESS == SQL->NextRow(inter->sql_handle) ) - { + } else if (SQL_SUCCESS == SQL->NextRow(inter->sql_handle)) { char *data; SQL->GetData(inter->sql_handle, 0, &data, NULL); - if (atoi(data) != account_id) - { // Cannot send mail to char in the same account + if (atoi(data) != account_id) { + // Cannot send mail to char in the same account SQL->GetData(inter->sql_handle, 1, &data, NULL); - msg.dest_id = atoi(data); + msg->dest_id = atoi(data); } } SQL->FreeResult(inter->sql_handle); - msg.status = MAIL_NEW; + msg->status = MAIL_NEW; - if( msg.dest_id > 0 ) - msg.id = inter_mail->savemessage(&msg); + if (msg->dest_id > 0) + msg->id = inter_mail->savemessage(msg); - mapif->mail_send(fd, &msg); // notify sender - mapif->mail_new(&msg); // notify recipient + return true; } void inter_mail_sendmail(int send_id, const char* send_name, int dest_id, const char* dest_name, const char* title, const char* body, int zeny, struct item *item) @@ -558,4 +443,9 @@ void inter_mail_defaults(void) inter_mail->sql_final = inter_mail_sql_final; inter_mail->fromsql = inter_mail_fromsql; inter_mail->loadmessage = inter_mail_loadmessage; + inter_mail->mark_read = inter_mail_mark_read; + inter_mail->get_attachment = inter_mail_get_attachment; + inter_mail->delete = inter_mail_delete; + inter_mail->return_message = inter_mail_return_message; + inter_mail->send = inter_mail_send; } diff --git a/src/char/int_mail.h b/src/char/int_mail.h index 9ca5fdad6..95934d0a1 100644 --- a/src/char/int_mail.h +++ b/src/char/int_mail.h @@ -39,6 +39,11 @@ struct inter_mail_interface { bool (*loadmessage) (int mail_id, struct mail_message* msg); bool (*DeleteAttach) (int mail_id); void (*sendmail) (int send_id, const char* send_name, int dest_id, const char* dest_name, const char* title, const char* body, int zeny, struct item *item); + bool (*mark_read) (int mail_id); + bool (*get_attachment) (int char_id, int mail_id, struct mail_message *msg); + bool (*delete) (int char_id, int mail_id); + bool (*return_message) (int char_id, int mail_id, int *new_mail); + bool (*send) (int account_id, struct mail_message *msg); }; #ifdef HERCULES_CORE diff --git a/src/char/int_mercenary.c b/src/char/int_mercenary.c index bf1df5588..52afdcb9f 100644 --- a/src/char/int_mercenary.c +++ b/src/char/int_mercenary.c @@ -104,7 +104,7 @@ bool inter_mercenary_owner_delete(int char_id) * @param[in,out] merc The new mercenary's data. * @retval false in case of errors. */ -bool mapif_mercenary_create(struct s_mercenary *merc) +bool inter_mercenary_create(struct s_mercenary *merc) { nullpo_retr(false, merc); Assert_retr(false, merc->mercenary_id == 0); @@ -126,7 +126,7 @@ bool mapif_mercenary_create(struct s_mercenary *merc) * @param merc The mercenary's data. * @retval false in case of errors. */ -bool mapif_mercenary_save(const struct s_mercenary *merc) +bool inter_mercenary_save(const struct s_mercenary *merc) { nullpo_retr(false, merc); Assert_retr(false, merc->mercenary_id > 0); @@ -141,7 +141,7 @@ bool mapif_mercenary_save(const struct s_mercenary *merc) return true; } -bool mapif_mercenary_load(int merc_id, int char_id, struct s_mercenary *merc) +bool inter_mercenary_load(int merc_id, int char_id, struct s_mercenary *merc) { char* data; @@ -174,7 +174,7 @@ bool mapif_mercenary_load(int merc_id, int char_id, struct s_mercenary *merc) return true; } -bool mapif_mercenary_delete(int merc_id) +bool inter_mercenary_delete(int merc_id) { if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `mer_id` = '%d'", mercenary_db, merc_id) ) { @@ -185,65 +185,6 @@ bool mapif_mercenary_delete(int merc_id) return true; } -void mapif_mercenary_send(int fd, struct s_mercenary *merc, unsigned char flag) -{ - int size = sizeof(struct s_mercenary) + 5; - - nullpo_retv(merc); - WFIFOHEAD(fd,size); - WFIFOW(fd,0) = 0x3870; - WFIFOW(fd,2) = size; - WFIFOB(fd,4) = flag; - memcpy(WFIFOP(fd,5),merc,sizeof(struct s_mercenary)); - WFIFOSET(fd,size); -} - -void mapif_parse_mercenary_create(int fd, const struct s_mercenary *merc) -{ - struct s_mercenary merc_; - bool result; - - memcpy(&merc_, merc, sizeof(merc_)); - - result = mapif->mercenary_create(&merc_); - mapif->mercenary_send(fd, &merc_, result); -} - -void mapif_parse_mercenary_load(int fd, int merc_id, int char_id) -{ - struct s_mercenary merc; - bool result = mapif->mercenary_load(merc_id, char_id, &merc); - mapif->mercenary_send(fd, &merc, result); -} - -void mapif_mercenary_deleted(int fd, unsigned char flag) -{ - WFIFOHEAD(fd,3); - WFIFOW(fd,0) = 0x3871; - WFIFOB(fd,2) = flag; - WFIFOSET(fd,3); -} - -void mapif_parse_mercenary_delete(int fd, int merc_id) -{ - bool result = mapif->mercenary_delete(merc_id); - mapif->mercenary_deleted(fd, result); -} - -void mapif_mercenary_saved(int fd, unsigned char flag) -{ - WFIFOHEAD(fd,3); - WFIFOW(fd,0) = 0x3872; - WFIFOB(fd,2) = flag; - WFIFOSET(fd,3); -} - -void mapif_parse_mercenary_save(int fd, struct s_mercenary* merc) -{ - bool result = mapif->mercenary_save(merc); - mapif->mercenary_saved(fd, result); -} - int inter_mercenary_sql_init(void) { return 0; @@ -282,4 +223,9 @@ void inter_mercenary_defaults(void) inter_mercenary->sql_init = inter_mercenary_sql_init; inter_mercenary->sql_final = inter_mercenary_sql_final; inter_mercenary->parse_frommap = inter_mercenary_parse_frommap; + + inter_mercenary->create = inter_mercenary_create; + inter_mercenary->load = inter_mercenary_load; + inter_mercenary->save = inter_mercenary_save; + inter_mercenary->delete = inter_mercenary_delete; } diff --git a/src/char/int_mercenary.h b/src/char/int_mercenary.h index 2b7c82dfa..6291bfcf6 100644 --- a/src/char/int_mercenary.h +++ b/src/char/int_mercenary.h @@ -22,6 +22,7 @@ #define CHAR_INT_MERCENARY_H #include "common/hercules.h" +#include "common/mmo.h" struct mmo_charstatus; @@ -35,6 +36,11 @@ struct inter_mercenary_interface { int (*sql_init) (void); void (*sql_final) (void); int (*parse_frommap) (int fd); + + bool (*create) (struct s_mercenary *merc); + bool (*save) (const struct s_mercenary *merc); + bool (*load) (int merc_id, int char_id, struct s_mercenary *merc); + bool (*delete) (int merc_id); }; #ifdef HERCULES_CORE diff --git a/src/char/int_party.c b/src/char/int_party.c index 144e6661c..e089d1567 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -333,161 +333,16 @@ int inter_party_check_empty(struct party_data *p) return 1; } -//------------------------------------------------------------------- -// Communication to the map server - - -// Create a party whether or not -int mapif_party_created(int fd, int account_id, int char_id, struct party *p) -{ - WFIFOHEAD(fd, 39); - WFIFOW(fd,0)=0x3820; - WFIFOL(fd,2)=account_id; - WFIFOL(fd,6)=char_id; - if(p!=NULL){ - WFIFOB(fd,10)=0; - WFIFOL(fd,11)=p->party_id; - memcpy(WFIFOP(fd,15),p->name,NAME_LENGTH); - ShowInfo("int_party: Party created (%d - %s)\n",p->party_id,p->name); - }else{ - WFIFOB(fd,10)=1; - WFIFOL(fd,11)=0; - memset(WFIFOP(fd,15),0,NAME_LENGTH); - } - WFIFOSET(fd,39); - - return 0; -} - -//Party information not found -void mapif_party_noinfo(int fd, int party_id, int char_id) -{ - WFIFOHEAD(fd, 12); - WFIFOW(fd,0) = 0x3821; - WFIFOW(fd,2) = 12; - WFIFOL(fd,4) = char_id; - WFIFOL(fd,8) = party_id; - WFIFOSET(fd,12); - ShowWarning("int_party: info not found (party_id=%d char_id=%d)\n", party_id, char_id); -} - -//Digest party information -void mapif_party_info(int fd, struct party* p, int char_id) -{ - unsigned char buf[8 + sizeof(struct party)]; - nullpo_retv(p); - 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) - mapif->sendall(buf,WBUFW(buf,2)); - else - mapif->send(fd,buf,WBUFW(buf,2)); -} - -//Whether or not additional party members -int mapif_party_memberadded(int fd, int party_id, int account_id, int char_id, int flag) { - WFIFOHEAD(fd, 15); - WFIFOW(fd,0) = 0x3822; - WFIFOL(fd,2) = party_id; - WFIFOL(fd,6) = account_id; - WFIFOL(fd,10) = char_id; - WFIFOB(fd,14) = flag; - WFIFOSET(fd,15); - - return 0; -} - -// Party setting change notification -int mapif_party_optionchanged(int fd, struct party *p, int account_id, int flag) -{ - unsigned char buf[16]; - nullpo_ret(p); - 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) - mapif->sendall(buf,15); - else - mapif->send(fd,buf,15); - return 0; -} - -//Withdrawal notification party -int mapif_party_withdraw(int party_id,int account_id, int 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; - mapif->sendall(buf, 14); - return 0; -} - -//Party map update notification -int mapif_party_membermoved(struct party *p, int idx) -{ - unsigned char buf[20]; - - nullpo_ret(p); - Assert_ret(idx >= 0 && idx < MAX_PARTY); - 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; - mapif->sendall(buf, 19); - return 0; -} - -//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; - mapif->sendall(buf,7); - //printf("int_party: broken %d\n",party_id); - return 0; -} - -//Remarks in the party -int mapif_party_message(int party_id, int account_id, const char *mes, int len, int sfd) -{ - unsigned char buf[512]; - nullpo_ret(mes); - WBUFW(buf,0)=0x3827; - WBUFW(buf,2)=len+12; - WBUFL(buf,4)=party_id; - WBUFL(buf,8)=account_id; - memcpy(WBUFP(buf,12),mes,len); - mapif->sendallwos(sfd, buf,len+12); - return 0; -} - -//------------------------------------------------------------------- -// Communication from the map server - - // Create Party -int mapif_parse_CreateParty(int fd, const char *name, int item, int item2, const struct party_member *leader) +struct party_data *inter_party_create(const char *name, int item, int item2, const struct party_member *leader) { struct party_data *p; int i; nullpo_ret(name); nullpo_ret(leader); - if (!*name || (p = inter_party->search_partyname(name)) != NULL) { - mapif->party_created(fd,leader->account_id,leader->char_id,NULL); - return 0; + + if (!*name || inter_party->search_partyname(name) != NULL) { + return NULL; } // Check Authorized letters/symbols in the name of the character if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorized @@ -497,18 +352,16 @@ int mapif_parse_CreateParty(int fd, const char *name, int item, int item2, const char *newname = aStrndup(name, NAME_LENGTH-1); normalize_name(newname,"\""); trim(newname); - mapif->parse_CreateParty(fd, newname, item, item2, leader); + p = inter_party->create(newname, item, item2, leader); aFree(newname); - return 0; + return p; } - mapif->party_created(fd,leader->account_id,leader->char_id,NULL); - return 0; + return NULL; } } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden for (i = 0; i < NAME_LENGTH && name[i]; i++) if (strchr(char_name_letters, name[i]) != NULL) { - mapif->party_created(fd,leader->account_id,leader->char_id,NULL); - return 0; + return NULL; } } @@ -523,34 +376,20 @@ int mapif_parse_CreateParty(int fd, const char *name, int item, int item2, const p->party.member[0].online=1; p->party.party_id=-1;//New party. - if (inter_party->tosql(&p->party,PS_CREATE|PS_ADDMEMBER,0)) { - //Add party to db - inter_party->calc_state(p); - idb_put(inter_party->db, p->party.party_id, p); - mapif->party_info(fd, &p->party, 0); - mapif->party_created(fd,leader->account_id,leader->char_id,&p->party); - } else { //Failed to create party. + if (!inter_party->tosql(&p->party, PS_CREATE | PS_ADDMEMBER, 0)) { aFree(p); - mapif->party_created(fd,leader->account_id,leader->char_id,NULL); + return NULL; } - return 0; -} - -// Party information request -void mapif_parse_PartyInfo(int fd, int party_id, int char_id) -{ - struct party_data *p; - p = inter_party->fromsql(party_id); + //Add party to db + inter_party->calc_state(p); + idb_put(inter_party->db, p->party.party_id, p); - if (p) - mapif->party_info(fd, &p->party, char_id); - else - mapif->party_noinfo(fd, party_id, char_id); + return p; } // Add a player to party request -int mapif_parse_PartyAddMember(int fd, int party_id, const struct party_member *member) +bool inter_party_add_member(int party_id, const struct party_member *member) { struct party_data *p; int i; @@ -558,15 +397,13 @@ int mapif_parse_PartyAddMember(int fd, int party_id, const struct party_member * nullpo_ret(member); p = inter_party->fromsql(party_id); if( p == NULL || p->size == MAX_PARTY ) { - mapif->party_memberadded(fd, party_id, member->account_id, member->char_id, 1); - return 0; + return false; } ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == 0 ); - if( i == MAX_PARTY ) - {// Party full - mapif->party_memberadded(fd, party_id, member->account_id, member->char_id, 1); - return 0; + if (i == MAX_PARTY) { + // Party full + return false; } memcpy(&p->party.member[i], member, sizeof(struct party_member)); @@ -582,21 +419,20 @@ int mapif_parse_PartyAddMember(int fd, int party_id, const struct party_member * } mapif->party_info(-1, &p->party, 0); - mapif->party_memberadded(fd, party_id, member->account_id, member->char_id, 0); inter_party->tosql(&p->party, PS_ADDMEMBER, i); - return 0; + return true; } //Party setting change request -int mapif_parse_PartyChangeOption(int fd,int party_id,int account_id,int exp,int item) +bool inter_party_change_option(int party_id, int account_id, int exp, int item, int map_fd) { struct party_data *p; int flag = 0; p = inter_party->fromsql(party_id); if(!p) - return 0; + return false; p->party.exp=exp; if( exp && !inter_party->check_exp_share(p) ){ @@ -604,13 +440,13 @@ int mapif_parse_PartyChangeOption(int fd,int party_id,int account_id,int exp,int p->party.exp=0; } p->party.item = item&0x3; //Filter out invalid values. - mapif->party_optionchanged(fd,&p->party,account_id,flag); + mapif->party_optionchanged(map_fd, &p->party, account_id, flag); inter_party->tosql(&p->party, PS_BASIC, 0); - return 0; + return true; } //Request leave party -int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) +bool inter_party_leave(int party_id, int account_id, int char_id) { struct party_data *p; int i,j; @@ -620,7 +456,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) {// Party does not exists? if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) ) Sql_ShowDebug(inter->sql_handle); - return 0; + return false; } for (i = 0; i < MAX_PARTY; i++) { @@ -630,7 +466,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) } } if (i >= MAX_PARTY) - return 0; //Member not found? + return false; //Member not found? mapif->party_withdraw(party_id, account_id, char_id); @@ -648,23 +484,25 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) inter_party->tosql(&p->party, PS_DELMEMBER, i); mapif->party_info(-1, &p->party, 0); } - return 0; + return true; } + // When member goes to other map or levels up. -int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv) +bool inter_party_change_map(int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv) { struct party_data *p; int i; p = inter_party->fromsql(party_id); if (p == NULL) - return 0; + return false; for(i = 0; i < MAX_PARTY && (p->party.member[i].account_id != account_id || p->party.member[i].char_id != char_id); i++); - if (i == MAX_PARTY) return 0; + if (i == MAX_PARTY) + return false; if (p->party.member[i].online != online) { @@ -704,30 +542,24 @@ int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, int char_id p->party.member[i].map = map; mapif->party_membermoved(&p->party, i); } - return 0; + return true; } //Request party dissolution -int mapif_parse_BreakParty(int fd, int party_id) +bool inter_party_disband(int party_id) { struct party_data *p; p = inter_party->fromsql(party_id); if(!p) - return 0; + return false; inter_party->tosql(&p->party,PS_BREAK,0); mapif->party_broken(party_id, 1); return 0; } -//Party sending the message -int mapif_parse_PartyMessage(int fd, int party_id, int account_id, const char *mes, int len) -{ - return mapif->party_message(party_id,account_id,mes,len, fd); -} - -int mapif_parse_PartyLeaderChange(int fd, int party_id, int account_id, int char_id) +bool inter_party_change_leader(int party_id, int account_id, int char_id) { struct party_data *p; int i; @@ -735,7 +567,7 @@ int mapif_parse_PartyLeaderChange(int fd, int party_id, int account_id, int char p = inter_party->fromsql(party_id); if(!p) - return 0; + return false; for (i = 0; i < MAX_PARTY; i++) { if(p->party.member[i].leader) @@ -745,10 +577,9 @@ int mapif_parse_PartyLeaderChange(int fd, int party_id, int account_id, int char inter_party->tosql(&p->party,PS_LEADER, i); } } - return 1; + return true; } - // Communication from the map server //-Analysis that only one packet // Data packet length is set to inter.c that you @@ -775,12 +606,6 @@ int inter_party_parse_frommap(int fd) return 1; } -//Leave request from the server (for delete character) -int inter_party_leave(int party_id,int account_id, int char_id) -{ - return mapif->parse_PartyLeave(-1,party_id,account_id, char_id); -} - int inter_party_CharOnline(int char_id, int party_id) { struct party_data* p; @@ -895,4 +720,11 @@ void inter_party_defaults(void) inter_party->leave = inter_party_leave; inter_party->CharOnline = inter_party_CharOnline; inter_party->CharOffline = inter_party_CharOffline; + + inter_party->create = inter_party_create; + inter_party->add_member = inter_party_add_member; + inter_party->change_option = inter_party_change_option; + inter_party->change_map = inter_party_change_map; + inter_party->disband = inter_party_disband; + inter_party->change_leader = inter_party_change_leader; } diff --git a/src/char/int_party.h b/src/char/int_party.h index 0e1215eea..b9a888cca 100644 --- a/src/char/int_party.h +++ b/src/char/int_party.h @@ -60,9 +60,15 @@ struct inter_party_interface { int (*check_exp_share) (struct party_data *p); int (*check_empty) (struct party_data *p); int (*parse_frommap) (int fd); - int (*leave) (int party_id,int account_id, int char_id); + bool (*leave) (int party_id,int account_id, int char_id); int (*CharOnline) (int char_id, int party_id); int (*CharOffline) (int char_id, int party_id); + struct party_data *(*create) (const char *name, int item, int item2, const struct party_member *leader); + bool (*add_member) (int party_id, const struct party_member *member); + bool (*change_option) (int party_id, int account_id, int exp, int item, int map_fd); + bool (*change_map) (int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv); + bool (*disband) (int party_id); + bool (*change_leader) (int party_id, int account_id, int char_id); }; #ifdef HERCULES_CORE diff --git a/src/char/int_pet.c b/src/char/int_pet.c index f270f205d..0a3a51b3a 100644 --- a/src/char/int_pet.c +++ b/src/char/int_pet.c @@ -156,73 +156,7 @@ int inter_pet_delete(int pet_id) { return 0; } //------------------------------------------------------ -int mapif_pet_created(int fd, int account_id, struct s_pet *p) -{ - WFIFOHEAD(fd, 12); - WFIFOW(fd, 0) = 0x3880; - WFIFOL(fd, 2) = account_id; - if(p!=NULL){ - WFIFOW(fd, 6) = p->class_; - WFIFOL(fd, 8) = p->pet_id; - ShowInfo("int_pet: created pet %d - %s\n", p->pet_id, p->name); - }else{ - WFIFOB(fd, 6) = 0; - WFIFOL(fd, 8) = 0; - } - WFIFOSET(fd, 12); - - return 0; -} - -int mapif_pet_info(int fd, int account_id, struct s_pet *p) -{ - nullpo_ret(p); - WFIFOHEAD(fd, sizeof(struct s_pet) + 9); - WFIFOW(fd, 0) =0x3881; - WFIFOW(fd, 2) =sizeof(struct s_pet) + 9; - WFIFOL(fd, 4) =account_id; - WFIFOB(fd, 8)=0; - memcpy(WFIFOP(fd, 9), p, sizeof(struct s_pet)); - WFIFOSET(fd, WFIFOW(fd, 2)); - - return 0; -} - -int mapif_pet_noinfo(int fd, int account_id) -{ - WFIFOHEAD(fd, sizeof(struct s_pet) + 9); - WFIFOW(fd, 0) =0x3881; - WFIFOW(fd, 2) =sizeof(struct s_pet) + 9; - WFIFOL(fd, 4) =account_id; - WFIFOB(fd, 8)=1; - memset(WFIFOP(fd, 9), 0, sizeof(struct s_pet)); - WFIFOSET(fd, WFIFOW(fd, 2)); - - return 0; -} - -int mapif_save_pet_ack(int fd, int account_id, int flag) -{ - WFIFOHEAD(fd, 7); - WFIFOW(fd, 0) =0x3882; - WFIFOL(fd, 2) =account_id; - WFIFOB(fd, 6) =flag; - WFIFOSET(fd, 7); - - return 0; -} - -int mapif_delete_pet_ack(int fd, int flag) -{ - WFIFOHEAD(fd, 3); - WFIFOW(fd, 0) =0x3883; - WFIFOB(fd, 2) =flag; - WFIFOSET(fd, 3); - - return 0; -} - -int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id, +struct s_pet *inter_pet_create(int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id, short pet_equip, short intimate, short hungry, char rename_flag, char incubate, const char *pet_name) { nullpo_ret(pet_name); @@ -254,87 +188,29 @@ int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short inter_pet->pt->pet_id = 0; //Signal NEW pet. if ((inter_pet->pt->pet_id = inter_pet->tosql(inter_pet->pt)) != 0) - mapif->pet_created(fd, account_id, inter_pet->pt); + return inter_pet->pt; else //Failed... - mapif->pet_created(fd, account_id, NULL); - - return 0; + return NULL; } -int mapif_load_pet(int fd, int account_id, int char_id, int pet_id) +struct s_pet *inter_pet_load(int account_id, int char_id, int pet_id) { memset(inter_pet->pt, 0, sizeof(struct s_pet)); inter_pet->fromsql(pet_id, inter_pet->pt); if(inter_pet->pt!=NULL) { - if(inter_pet->pt->incubate == 1) { + if (inter_pet->pt->incubate == 1) { inter_pet->pt->account_id = inter_pet->pt->char_id = 0; - mapif->pet_info(fd, account_id, inter_pet->pt); + return inter_pet->pt; + } else if (account_id == inter_pet->pt->account_id && char_id == inter_pet->pt->char_id) { + return inter_pet->pt; + } else { + return NULL; } - else if(account_id == inter_pet->pt->account_id && char_id == inter_pet->pt->char_id) - mapif->pet_info(fd, account_id, inter_pet->pt); - else - mapif->pet_noinfo(fd, account_id); } - else - mapif->pet_noinfo(fd, account_id); - return 0; -} - -int mapif_save_pet(int fd, int account_id, const struct s_pet *data) -{ - //here process pet save request. - int len; - nullpo_ret(data); - RFIFOHEAD(fd); - len=RFIFOW(fd, 2); - if (sizeof(struct s_pet) != len-8) { - ShowError("inter pet: data size mismatch: %d != %"PRIuS"\n", len-8, sizeof(struct s_pet)); - return 0; - } - - inter_pet->tosql(data); - mapif->save_pet_ack(fd, account_id, 0); - - return 0; -} - -int mapif_delete_pet(int fd, int pet_id) -{ - mapif->delete_pet_ack(fd, inter_pet->delete_(pet_id)); - - return 0; -} - -int mapif_parse_CreatePet(int fd) -{ - RFIFOHEAD(fd); - mapif->create_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOW(fd, 10), RFIFOW(fd, 12), RFIFOW(fd, 14), RFIFOW(fd, 16), RFIFOW(fd, 18), - RFIFOW(fd, 20), RFIFOB(fd, 22), RFIFOB(fd, 23), RFIFOP(fd, 24)); - return 0; -} - -int mapif_parse_LoadPet(int fd) -{ - RFIFOHEAD(fd); - mapif->load_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10)); - return 0; -} - -int mapif_parse_SavePet(int fd) -{ - RFIFOHEAD(fd); - mapif->save_pet(fd, RFIFOL(fd, 4), RFIFOP(fd, 8)); - return 0; -} - -int mapif_parse_DeletePet(int fd) -{ - RFIFOHEAD(fd); - mapif->delete_pet(fd, RFIFOL(fd, 2)); - return 0; + return NULL; } int inter_pet_parse_frommap(int fd) @@ -363,4 +239,7 @@ void inter_pet_defaults(void) inter_pet->sql_final = inter_pet_sql_final; inter_pet->delete_ = inter_pet_delete; inter_pet->parse_frommap = inter_pet_parse_frommap; + + inter_pet->create = inter_pet_create; + inter_pet->load = inter_pet_load; } diff --git a/src/char/int_pet.h b/src/char/int_pet.h index ab14a6580..9e3a2ac59 100644 --- a/src/char/int_pet.h +++ b/src/char/int_pet.h @@ -36,6 +36,10 @@ struct inter_pet_interface { void (*sql_final) (void); int (*delete_) (int pet_id); int (*parse_frommap) (int fd); + + struct s_pet *(*create) (int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id, + short pet_equip, short intimate, short hungry, char rename_flag, char incubate, const char *pet_name); + struct s_pet *(*load) (int account_id, int char_id, int pet_id); }; #ifdef HERCULES_CORE diff --git a/src/char/int_quest.c b/src/char/int_quest.c index f967e5cfb..afd01579e 100644 --- a/src/char/int_quest.c +++ b/src/char/int_quest.c @@ -48,7 +48,7 @@ struct inter_quest_interface *inter_quest; * @return Array of found entries. It has *count entries, and it is care of the * caller to aFree() it afterwards. */ -struct quest *mapif_quests_fromsql(int char_id, int *count) +struct quest *inter_quest_fromsql(int char_id, int *count) { struct quest *questlog = NULL; struct quest tmp_quest; @@ -129,7 +129,7 @@ struct quest *mapif_quests_fromsql(int char_id, int *count) * @param quest_id Quest ID * @return false in case of errors, true otherwise */ -bool mapif_quest_delete(int char_id, int quest_id) +bool inter_quest_delete(int char_id, int quest_id) { if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, quest_id, char_id)) { Sql_ShowDebug(inter->sql_handle); @@ -146,7 +146,7 @@ bool mapif_quest_delete(int char_id, int quest_id) * @param qd Quest data * @return false in case of errors, true otherwise */ -bool mapif_quest_add(int char_id, struct quest qd) +bool inter_quest_add(int char_id, struct quest qd) { StringBuf buf; int i; @@ -178,7 +178,7 @@ bool mapif_quest_add(int char_id, struct quest qd) * @param qd Quest data * @return false in case of errors, true otherwise */ -bool mapif_quest_update(int char_id, struct quest qd) +bool inter_quest_update(int char_id, struct quest qd) { StringBuf buf; int i; @@ -200,34 +200,13 @@ bool mapif_quest_update(int char_id, struct quest qd) return true; } -void mapif_quest_save_ack(int fd, int char_id, bool success) +bool inter_quest_save(int char_id, const struct quest *new_qd, int new_n) { - WFIFOHEAD(fd,7); - WFIFOW(fd,0) = 0x3861; - WFIFOL(fd,2) = char_id; - WFIFOB(fd,6) = success?1:0; - WFIFOSET(fd,7); -} - -/** - * Handles the save request from mapserver for a character's questlog. - * - * Received quests are saved, and an ack is sent back to the map server. - * - * @see inter_parse_frommap - */ -int mapif_parse_quest_save(int fd) -{ - int i, j, k, old_n, new_n = (RFIFOW(fd,2)-8)/sizeof(struct quest); - int char_id = RFIFOL(fd,4); + int i, j, k, old_n; struct quest *old_qd = NULL; - const struct quest *new_qd = NULL; bool success = true; - if (new_n > 0) - new_qd = RFIFOP(fd,8); - - old_qd = mapif->quests_fromsql(char_id, &old_n); + old_qd = inter_quest->fromsql(char_id, &old_n); for (i = 0; i < new_n; i++) { ARR_FIND( 0, old_n, j, new_qd[i].quest_id == old_qd[j].quest_id ); @@ -237,7 +216,7 @@ int mapif_parse_quest_save(int fd) // Only states and counts are changeable. ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, new_qd[i].count[k] != old_qd[j].count[k] ); if (k != MAX_QUEST_OBJECTIVES || new_qd[i].state != old_qd[j].state) - success &= mapif->quest_update(char_id, new_qd[i]); + success &= inter_quest->update(char_id, new_qd[i]); if (j < (--old_n)) { // Compact array @@ -246,59 +225,17 @@ int mapif_parse_quest_save(int fd) } } else { // Add new quests - success &= mapif->quest_add(char_id, new_qd[i]); + success &= inter_quest->add(char_id, new_qd[i]); } } for (i = 0; i < old_n; i++) // Quests not in new_qd but in old_qd are to be erased. - success &= mapif->quest_delete(char_id, old_qd[i].quest_id); + success &= inter_quest->delete(char_id, old_qd[i].quest_id); if (old_qd) aFree(old_qd); - // Send ack - mapif->quest_save_ack(fd, char_id, success); - - return 0; -} - -void mapif_send_quests(int fd, int char_id, struct quest *tmp_questlog, int num_quests) -{ - WFIFOHEAD(fd,num_quests*sizeof(struct quest)+8); - WFIFOW(fd,0) = 0x3860; - WFIFOW(fd,2) = num_quests*sizeof(struct quest)+8; - WFIFOL(fd,4) = char_id; - - if (num_quests > 0) { - nullpo_retv(tmp_questlog); - memcpy(WFIFOP(fd,8), tmp_questlog, sizeof(struct quest)*num_quests); - } - - WFIFOSET(fd,num_quests*sizeof(struct quest)+8); -} - -/** - * Sends questlog to the map server - * - * Note: Completed quests (state == Q_COMPLETE) are guaranteed to be sent last - * and the map server relies on this behavior (once the first Q_COMPLETE quest, - * all of them are considered to be Q_COMPLETE) - * - * @see inter_parse_frommap - */ -int mapif_parse_quest_load(int fd) -{ - int char_id = RFIFOL(fd,2); - struct quest *tmp_questlog = NULL; - int num_quests; - - tmp_questlog = mapif->quests_fromsql(char_id, &num_quests); - mapif->send_quests(fd, char_id, tmp_questlog, num_quests); - - if (tmp_questlog) - aFree(tmp_questlog); - - return 0; + return success; } /** @@ -322,4 +259,9 @@ void inter_quest_defaults(void) inter_quest = &inter_quest_s; inter_quest->parse_frommap = inter_quest_parse_frommap; + inter_quest->fromsql = inter_quest_fromsql; + inter_quest->delete = inter_quest_delete; + inter_quest->add = inter_quest_add; + inter_quest->update = inter_quest_update; + inter_quest->save = inter_quest_save; } diff --git a/src/char/int_quest.h b/src/char/int_quest.h index 6f34645bf..e71afc561 100644 --- a/src/char/int_quest.h +++ b/src/char/int_quest.h @@ -28,6 +28,12 @@ **/ struct inter_quest_interface { int (*parse_frommap) (int fd); + + struct quest *(*fromsql) (int char_id, int *count); + bool (*delete) (int char_id, int quest_id); + bool (*add) (int char_id, struct quest qd); + bool (*update) (int char_id, struct quest qd); + bool (*save) (int char_id, const struct quest *new_qd, int new_n); }; #ifdef HERCULES_CORE diff --git a/src/char/int_rodex.c b/src/char/int_rodex.c index 0dab66f61..ddd019bb8 100644 --- a/src/char/int_rodex.c +++ b/src/char/int_rodex.c @@ -347,110 +347,12 @@ int64 inter_rodex_savemessage(struct rodex_message* msg) } /*========================================== - * Inbox Request - *------------------------------------------*/ -void mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails) -{ - int per_packet = (UINT16_MAX - 24) / sizeof(struct rodex_message); - int sent = 0; - bool is_first = true; - nullpo_retv(mails); - Assert_retv(char_id > 0); - Assert_retv(count >= 0); - Assert_retv(mail_id >= 0); - - do { - int i = 24, j, size, limit; - int to_send = count - sent; - bool is_last = true; - - if (to_send <= per_packet) { - size = to_send * sizeof(struct rodex_message) + 24; - limit = to_send; - is_last = true; - } else { - limit = min(to_send, per_packet); - if (limit != to_send) { - is_last = false; - } - size = limit * sizeof(struct rodex_message) + 24; - } - - WFIFOHEAD(fd, size); - WFIFOW(fd, 0) = 0x3895; - WFIFOW(fd, 2) = size; - WFIFOL(fd, 4) = char_id; - WFIFOB(fd, 8) = opentype; - WFIFOB(fd, 9) = flag; - WFIFOB(fd, 10) = is_last; - WFIFOB(fd, 11) = is_first; - WFIFOL(fd, 12) = limit; - WFIFOQ(fd, 16) = mail_id; - for (j = 0; j < limit; ++j, ++sent, i += sizeof(struct rodex_message)) { - memcpy(WFIFOP(fd, i), &VECTOR_INDEX(*mails, sent), sizeof(struct rodex_message)); - } - WFIFOSET(fd, size); - - is_first = false; - } while (sent < count); -} - -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); -} - -/*========================================== -* Checks if there are new mails -*------------------------------------------*/ -void mapif_rodex_sendhasnew(int fd, int char_id, bool has_new) -{ - Assert_retv(char_id > 0); - - WFIFOHEAD(fd, 7); - WFIFOW(fd, 0) = 0x3896; - WFIFOL(fd, 2) = char_id; - WFIFOB(fd, 6) = has_new; - WFIFOSET(fd, 7); -} - -void mapif_parse_rodex_checkhasnew(int fd) -{ - int char_id = RFIFOL(fd, 2); - int account_id = RFIFOL(fd, 6); - bool has_new; - - Assert_retv(account_id >= START_ACCOUNT_NUM && account_id <= END_ACCOUNT_NUM); - Assert_retv(char_id >= START_CHAR_NUM); - - has_new = inter_rodex->hasnew(char_id, account_id); - mapif->rodex_sendhasnew(fd, char_id, has_new); -} - -/*========================================== * Update/Delete mail *------------------------------------------*/ -void mapif_parse_rodex_updatemail(int fd) +bool inter_rodex_updatemail(int64 mail_id, int8 flag) { - int64 mail_id = RFIFOL(fd, 2); - int8 flag = RFIFOB(fd, 10); - - Assert_retv(mail_id > 0); - Assert_retv(flag >= 0 && flag <= 4); + Assert_retr(false, mail_id > 0); + Assert_retr(false, flag >= 0 && flag <= 4); switch (flag) { case 0: // Read @@ -481,72 +383,10 @@ void mapif_parse_rodex_updatemail(int fd) if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `sender_read` = 1 WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) Sql_ShowDebug(inter->sql_handle); break; + default: + return false; } -} - -/*========================================== - * Send Mail - *------------------------------------------*/ -void mapif_rodex_send(int fd, int sender_id, int receiver_id, int receiver_accountid, bool result) -{ - Assert_retv(sender_id >= 0); - Assert_retv(receiver_id + receiver_accountid > 0); - - WFIFOHEAD(fd,15); - WFIFOW(fd,0) = 0x3897; - WFIFOL(fd,2) = sender_id; - WFIFOL(fd,6) = receiver_id; - WFIFOL(fd,10) = receiver_accountid; - WFIFOB(fd,14) = result; - WFIFOSET(fd,15); -} - -void mapif_parse_rodex_send(int fd) -{ - struct rodex_message msg = { 0 }; - - if (RFIFOW(fd,2) != 4 + sizeof(struct rodex_message)) - return; - - memcpy(&msg, RFIFOP(fd,4), sizeof(struct rodex_message)); - if (msg.receiver_id > 0 || msg.receiver_accountid > 0) - msg.id = inter_rodex->savemessage(&msg); - - mapif->rodex_send(fd, msg.sender_id, msg.receiver_id, msg.receiver_accountid, msg.id > 0 ? true : false); -} - -/*------------------------------------------ - * Check Player - *------------------------------------------*/ -void mapif_rodex_checkname(int fd, int reqchar_id, int target_char_id, short target_class, int target_level, char *name) -{ - nullpo_retv(name); - Assert_retv(reqchar_id > 0); - Assert_retv(target_char_id >= 0); - - WFIFOHEAD(fd, 16 + NAME_LENGTH); - WFIFOW(fd, 0) = 0x3898; - WFIFOL(fd, 2) = reqchar_id; - WFIFOL(fd, 6) = target_char_id; - WFIFOW(fd, 10) = target_class; - WFIFOL(fd, 12) = target_level; - safestrncpy(WFIFOP(fd, 16), name, NAME_LENGTH); - WFIFOSET(fd, 16 + NAME_LENGTH); -} - -void mapif_parse_rodex_checkname(int fd) -{ - int reqchar_id = RFIFOL(fd, 2); - char name[NAME_LENGTH]; - int target_char_id, target_level; - short target_class; - - safestrncpy(name, RFIFOP(fd, 6), NAME_LENGTH); - - if (inter_rodex->checkname(name, &target_char_id, &target_class, &target_level) == true) - mapif->rodex_checkname(fd, reqchar_id, target_char_id, target_class, target_level, name); - else - mapif->rodex_checkname(fd, reqchar_id, 0, 0, 0, name); + return true; } /*========================================== @@ -588,4 +428,5 @@ void inter_rodex_defaults(void) inter_rodex->fromsql = inter_rodex_fromsql; inter_rodex->hasnew = inter_rodex_hasnew; inter_rodex->checkname = inter_rodex_checkname; + inter_rodex->updatemail = inter_rodex_updatemail; } diff --git a/src/char/int_rodex.h b/src/char/int_rodex.h index 801ebcb89..43e2d891c 100644 --- a/src/char/int_rodex.h +++ b/src/char/int_rodex.h @@ -36,6 +36,7 @@ struct inter_rodex_interface { bool (*hasnew) (int char_id, int account_id); bool (*checkname) (const char *name, int *target_char_id, short *target_class, int *target_level); int64 (*savemessage) (struct rodex_message* msg); + bool (*updatemail) (int64 mail_id, int8 flag); }; #ifdef HERCULES_CORE diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 0d31800fe..3deb8d58b 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -235,12 +235,23 @@ int inter_storage_fromsql(int account_id, struct storage_data *p) } /// Save guild_storage data to sql -int inter_storage_guild_storage_tosql(int guild_id, const struct guild_storage *p) +bool inter_storage_guild_storage_tosql(int guild_id, const struct guild_storage *p) { nullpo_ret(p); + + if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id)) { + Sql_ShowDebug(inter->sql_handle); + return false; + } else if (SQL->NumRows(inter->sql_handle) < 1) { + // guild doesn't exist + SQL->FreeResult(inter->sql_handle); + return false; + } + SQL->FreeResult(inter->sql_handle); + chr->memitemdata_to_sql(p->items, guild_id, TABLE_GUILD_STORAGE); ShowInfo ("guild storage save to DB - guild: %d\n", guild_id); - return 0; + return true; } /// Load guild_storage data to mem @@ -328,213 +339,11 @@ int inter_storage_guild_storage_delete(int guild_id) return 0; } -//--------------------------------------------------------- -// packet from map server - -int mapif_load_guild_storage(int fd, int account_id, int guild_id, char flag) -{ - if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) ) - Sql_ShowDebug(inter->sql_handle); - else if( SQL->NumRows(inter->sql_handle) > 0 ) - {// guild exists - WFIFOHEAD(fd, sizeof(struct guild_storage)+13); - WFIFOW(fd,0) = 0x3818; - WFIFOW(fd,2) = sizeof(struct guild_storage)+13; - WFIFOL(fd,4) = account_id; - WFIFOL(fd,8) = guild_id; - WFIFOB(fd,12) = flag; //1 open storage, 0 don't open - inter_storage->guild_storage_fromsql(guild_id, WFIFOP(fd,13)); - WFIFOSET(fd, WFIFOW(fd,2)); - return 0; - } - // guild does not exist - SQL->FreeResult(inter->sql_handle); - WFIFOHEAD(fd, 12); - WFIFOW(fd,0) = 0x3818; - WFIFOW(fd,2) = 12; - WFIFOL(fd,4) = account_id; - WFIFOL(fd,8) = 0; - WFIFOSET(fd, 12); - return 0; -} -int mapif_save_guild_storage_ack(int fd, int account_id, int guild_id, int fail) -{ - WFIFOHEAD(fd,11); - WFIFOW(fd,0)=0x3819; - WFIFOL(fd,2)=account_id; - WFIFOL(fd,6)=guild_id; - WFIFOB(fd,10)=fail; - WFIFOSET(fd,11); - return 0; -} - -//========================================================= -// Account Storage -//--------------------------------------------------------- -/** - * Parses account storage load request from map server. - * @packet 0x3010 [in] <account_id>.L - * @param fd [in] file/socket descriptor - * @return 1 on success, 0 on failure. - */ -int mapif_parse_AccountStorageLoad(int fd) -{ - int account_id = RFIFOL(fd, 2); - - Assert_ret(fd > 0); - Assert_ret(account_id > 0); - - mapif->account_storage_load(fd, account_id); - - return 1; -} - -/** - * Loads the account storage and send to the map server. - * @packet 0x3805 [out] <account_id>.L <struct item[]>.P - * @param fd [in] file/socket descriptor. - * @param account_id [in] account id of the session. - * @return 1 on success, 0 on failure. - */ -int mapif_account_storage_load(int fd, int account_id) -{ - struct storage_data stor = { 0 }; - int count = 0, i = 0, len = 0; - - Assert_ret(account_id > 0); - - VECTOR_INIT(stor.item); - count = inter_storage->fromsql(account_id, &stor); - - len = 8 + count * sizeof(struct item); - - WFIFOHEAD(fd, len); - WFIFOW(fd, 0) = 0x3805; - WFIFOW(fd, 2) = (uint16) len; - WFIFOL(fd, 4) = account_id; - for (i = 0; i < count; i++) - memcpy(WFIFOP(fd, 8 + i * sizeof(struct item)), &VECTOR_INDEX(stor.item, i), sizeof(struct item)); - WFIFOSET(fd, len); - - VECTOR_CLEAR(stor.item); - - return 1; -} - -/** - * Parses an account storage save request from the map server. - * @packet 0x3011 [in] <packet_len>.W <account_id>.L <struct item[]>.P - * @param fd [in] file/socket descriptor. - * @return 1 on success, 0 on failure. - */ -int mapif_parse_AccountStorageSave(int fd) -{ - int payload_size = RFIFOW(fd, 2) - 8, account_id = RFIFOL(fd, 4); - int i = 0, count = 0; - struct storage_data p_stor = { 0 }; - - Assert_ret(fd > 0); - Assert_ret(account_id > 0); - - count = payload_size/sizeof(struct item); - - VECTOR_INIT(p_stor.item); - - if (count > 0) { - VECTOR_ENSURE(p_stor.item, count, 1); - - for (i = 0; i < count; i++) { - const struct item *it = RFIFOP(fd, 8 + i * sizeof(struct item)); - - VECTOR_PUSH(p_stor.item, *it); - } - - p_stor.aggregate = count; - } - - inter_storage->tosql(account_id, &p_stor); - - VECTOR_CLEAR(p_stor.item); - - mapif->sAccountStorageSaveAck(fd, account_id, true); - - return 1; -} - -/** - * Sends an acknowledgement for the save - * status of the account storage. - * @packet 0x3808 [out] <account_id>.L <save_flag>.B - * @param fd [in] File/Socket Descriptor. - * @param account_id [in] Account ID of the storage in question. - * @param flag [in] Save flag, true for success and false for failure. - */ -void mapif_send_AccountStorageSaveAck(int fd, int account_id, bool flag) -{ - WFIFOHEAD(fd, 7); - WFIFOW(fd, 0) = 0x3808; - WFIFOL(fd, 2) = account_id; - WFIFOB(fd, 6) = flag ? 1 : 0; - WFIFOSET(fd, 7); -} - -//========================================================= -// Guild Storage -//--------------------------------------------------------- -int mapif_parse_LoadGuildStorage(int fd) -{ - RFIFOHEAD(fd); - - mapif->load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6),1); - - return 0; -} - -int mapif_parse_SaveGuildStorage(int fd) -{ - int guild_id; - int len; - - RFIFOHEAD(fd); - guild_id = RFIFOL(fd,8); - len = RFIFOW(fd,2); - - if (sizeof(struct guild_storage) != len - 12) { - ShowError("inter storage: data size mismatch: %d != %"PRIuS"\n", len - 12, sizeof(struct guild_storage)); - } else { - if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id)) { - Sql_ShowDebug(inter->sql_handle); - } else if(SQL->NumRows(inter->sql_handle) > 0) { - // guild exists - SQL->FreeResult(inter->sql_handle); - inter_storage->guild_storage_tosql(guild_id, RFIFOP(fd,12)); - mapif->save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 0); - return 0; - } - SQL->FreeResult(inter->sql_handle); - } - mapif->save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 1); - - return 0; -} - -int mapif_itembound_ack(int fd, int aid, int guild_id) -{ -#ifdef GP_BOUND_ITEMS - WFIFOHEAD(fd,8); - WFIFOW(fd,0) = 0x3856; - WFIFOL(fd,2) = aid;/* the value is not being used, drop? */ - WFIFOW(fd,6) = guild_id; - WFIFOSET(fd,8); -#endif - return 0; -} - //------------------------------------------------ //Guild bound items pull for offline characters [Akinari] //Revised by [Mhalicot] //------------------------------------------------ -int mapif_parse_ItemBoundRetrieve_sub(int fd) +bool inter_storage_retrieve_bound_items(int char_id, int account_id, int guild_id) { #ifdef GP_BOUND_ITEMS StringBuf buf; @@ -543,9 +352,6 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) int j, i=0, s=0, bound_qt=0; struct item items[MAX_INVENTORY]; unsigned int bound_item[MAX_INVENTORY] = {0}; - int char_id = RFIFOL(fd,2); - int aid = RFIFOL(fd,6); - int guild_id = RFIFOW(fd,10); StrBuf->Init(&buf); StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`"); @@ -562,7 +368,7 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) Sql_ShowDebug(inter->sql_handle); SQL->StmtFree(stmt); StrBuf->Destroy(&buf); - return 1; + return false; } memset(&item, 0, sizeof(item)); @@ -594,7 +400,7 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) if (i == 0) { //No items found - No need to continue StrBuf->Destroy(&buf); SQL->StmtFree(stmt); - return 0; + return true; } //First we delete the character's items @@ -627,7 +433,7 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) Sql_ShowDebug(inter->sql_handle); SQL->StmtFree(stmt); StrBuf->Destroy(&buf); - return 1; + return false; } // Removes any view id that was set by an item that was removed @@ -661,7 +467,7 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) Sql_ShowDebug(inter->sql_handle); SQL->StmtFree(stmt); StrBuf->Destroy(&buf); - return 1; + return false; } #undef CHECK_REMOVE } @@ -702,26 +508,13 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) Sql_ShowDebug(inter->sql_handle); SQL->StmtFree(stmt); StrBuf->Destroy(&buf); - return 1; + return false; } StrBuf->Destroy(&buf); SQL->StmtFree(stmt); - - //Finally reload storage and tell map we're done - mapif->load_guild_storage(fd,aid,guild_id,0); - - // If character is logged in char, disconnect - chr->disconnect_player(aid); #endif - return 0; -} - -void mapif_parse_ItemBoundRetrieve(int fd) -{ - mapif->parse_ItemBoundRetrieve_sub(fd); - /* tell map server the operation is over and it can unlock the storage */ - mapif->itembound_ack(fd,RFIFOL(fd,6),RFIFOW(fd,10)); + return true; } int inter_storage_parse_frommap(int fd) @@ -754,4 +547,5 @@ void inter_storage_defaults(void) inter_storage->delete_ = inter_storage_delete; inter_storage->guild_storage_delete = inter_storage_guild_storage_delete; inter_storage->parse_frommap = inter_storage_parse_frommap; + inter_storage->retrieve_bound_items = inter_storage_retrieve_bound_items; } diff --git a/src/char/int_storage.h b/src/char/int_storage.h index 89886c390..918927620 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -33,13 +33,14 @@ struct guild_storage; struct inter_storage_interface { int (*tosql) (int account_id, const struct storage_data *p); int (*fromsql) (int account_id, struct storage_data *p); - int (*guild_storage_tosql) (int guild_id, const struct guild_storage *p); + bool (*guild_storage_tosql) (int guild_id, const struct guild_storage *p); int (*guild_storage_fromsql) (int guild_id, struct guild_storage* p); int (*sql_init) (void); void (*sql_final) (void); int (*delete_) (int account_id); int (*guild_storage_delete) (int guild_id); int (*parse_frommap) (int fd); + bool (*retrieve_bound_items) (int char_id, int account_id, int guild_id); }; #ifdef HERCULES_CORE diff --git a/src/char/inter.c b/src/char/inter.c index cd363e8a2..28e2f2488 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -81,11 +81,6 @@ int inter_recv_packet_length[] = { -1,10,-1, 6, 0, 20,10,11, -1,6 + NAME_LENGTH, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator], RoDEX packets }; -struct WisData { - int id, fd, count, len; - int64 tick; - unsigned char src[24], dst[24], msg[512]; -}; static struct DBMap *wis_db = NULL; // int wis_id -> struct WisData* static int wis_dellist[WISDELLIST_MAX], wis_delnum; @@ -446,15 +441,12 @@ void inter_msg_to_fd(int fd, int u_fd, int aid, char *msg, ...) } /* [Dekamaster/Nightroad] */ -void mapif_parse_accinfo(int fd) +void inter_accinfo(int u_fd, int aid, int castergroup, const char *query, int map_fd) { - int u_fd = RFIFOL(fd,2), aid = RFIFOL(fd,6), castergroup = RFIFOL(fd,10); - char query[NAME_LENGTH], query_esq[NAME_LENGTH*2+1]; + char query_esq[NAME_LENGTH*2+1]; int account_id; char *data; - safestrncpy(query, RFIFOP(fd,14), NAME_LENGTH); - SQL->EscapeString(inter->sql_handle, query_esq, query); account_id = atoi(query); @@ -464,10 +456,10 @@ void mapif_parse_accinfo(int fd) if ( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", char_db, query_esq) || SQL->NumRows(inter->sql_handle) == 0 ) { if( SQL->NumRows(inter->sql_handle) == 0 ) { - inter->msg_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query); + inter->msg_to_fd(map_fd, u_fd, aid, "No matches were found for your criteria, '%s'",query); } else { Sql_ShowDebug(inter->sql_handle); - inter->msg_to_fd(fd, u_fd, aid, "An error occurred, bother your admin about it."); + inter->msg_to_fd(map_fd, u_fd, aid, "An error occurred, bother your admin about it."); } SQL->FreeResult(inter->sql_handle); return; @@ -477,7 +469,7 @@ void mapif_parse_accinfo(int fd) SQL->GetData(inter->sql_handle, 0, &data, NULL); account_id = atoi(data); SQL->FreeResult(inter->sql_handle); } else {// more than one, listing... [Dekamaster/Nightroad] - inter->msg_to_fd(fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)SQL->NumRows(inter->sql_handle)); + inter->msg_to_fd(map_fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)SQL->NumRows(inter->sql_handle)); while ( SQL_SUCCESS == SQL->NextRow(inter->sql_handle) ) { int class; int base_level, job_level, online; @@ -490,7 +482,7 @@ void mapif_parse_accinfo(int fd) SQL->GetData(inter->sql_handle, 4, &data, NULL); job_level = atoi(data); SQL->GetData(inter->sql_handle, 5, &data, NULL); online = atoi(data); - inter->msg_to_fd(fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, inter->job_name(class), base_level, job_level, online?"Online":"Offline"); + inter->msg_to_fd(map_fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, inter->job_name(class), base_level, job_level, online?"Online":"Offline"); } SQL->FreeResult(inter->sql_handle); return; @@ -501,12 +493,13 @@ void mapif_parse_accinfo(int fd) /* it will only get here if we have a single match */ /* and we will send packet with account id to login server asking for account info */ if( account_id ) { - mapif->on_parse_accinfo(account_id, u_fd, aid, castergroup, fd); + mapif->on_parse_accinfo(account_id, u_fd, aid, castergroup, map_fd); } return; } -void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, + +void inter_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state) { @@ -1012,102 +1005,6 @@ int inter_mapif_init(int fd) return 0; } - -//-------------------------------------------------------- - -// broadcast sending -int mapif_broadcast(const unsigned char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd) -{ - unsigned char *buf = (unsigned char*)aMalloc((len)*sizeof(unsigned char)); - - nullpo_ret(mes); - Assert_ret(len >= 16); - WBUFW(buf,0) = 0x3800; - WBUFW(buf,2) = len; - WBUFL(buf,4) = fontColor; - WBUFW(buf,8) = fontType; - WBUFW(buf,10) = fontSize; - WBUFW(buf,12) = fontAlign; - WBUFW(buf,14) = fontY; - memcpy(WBUFP(buf,16), mes, len - 16); - mapif->sendallwos(sfd, buf, len); - - aFree(buf); - return 0; -} - -// Wis sending -int mapif_wis_message(struct WisData *wd) -{ - unsigned char buf[2048]; - nullpo_ret(wd); - //if (wd->len > 2047-56) wd->len = 2047-56; //Force it to fit to avoid crashes. [Skotlex] - if (wd->len < 0) - wd->len = 0; - if (wd->len >= (int)sizeof(wd->msg) - 1) - wd->len = (int)sizeof(wd->msg) - 1; - - 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 = mapif->sendall(buf,WBUFW(buf,2)); - - return 0; -} - -void mapif_wis_response(int fd, const unsigned char *src, int flag) -{ - unsigned char buf[27]; - nullpo_retv(src); - WBUFW(buf, 0)=0x3802; - memcpy(WBUFP(buf, 2),src,24); - WBUFB(buf,26)=flag; - mapif->send(fd,buf,27); -} - -// Wis sending result -int mapif_wis_end(struct WisData *wd, int flag) -{ - nullpo_ret(wd); - mapif->wis_response(wd->fd, wd->src, flag); - return 0; -} - -#if 0 -// Account registry transfer to map-server -static void mapif_account_reg(int fd, unsigned char *src) -{ - nullpo_retv(src); - WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO - mapif->sendallwos(fd, src, WBUFW(src,2)); -} -#endif // 0 - -// Send the requested account_reg -int mapif_account_reg_reply(int fd,int account_id,int char_id, int type) -{ - inter->accreg_fromsql(account_id,char_id,fd,type); - return 0; -} - -//Request to kick char from a certain map server. [Skotlex] -int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason) -{ - if (fd >= 0) - { - WFIFOHEAD(fd,7); - WFIFOW(fd,0) = 0x2b1f; - WFIFOL(fd,2) = account_id; - WFIFOB(fd,6) = reason; - WFIFOSET(fd,7); - return 0; - } - return -1; -} - //-------------------------------------------------------- /** @@ -1147,225 +1044,36 @@ int inter_check_ttl_wisdata(void) return 0; } -//-------------------------------------------------------- - -// broadcast sending -int mapif_parse_broadcast(int fd) -{ - mapif->broadcast(RFIFOP(fd,16), RFIFOW(fd,2), RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), fd); - return 0; -} - - -// Wisp/page request to send -int mapif_parse_WisRequest(int fd) -{ - struct WisData* wd; - char name[NAME_LENGTH]; - char esc_name[NAME_LENGTH*2+1];// escaped name - char* data; - size_t len; - - - if ( fd <= 0 ) {return 0;} // check if we have a valid fd - - if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) { - ShowWarning("inter: Wis message size too long.\n"); - return 0; - } else if (RFIFOW(fd,2)-52 <= 0) { // normally, impossible, but who knows... - ShowError("inter: Wis message doesn't exist.\n"); - return 0; - } - - safestrncpy(name, RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex] - - SQL->EscapeStringLen(inter->sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); - if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", char_db, esc_name) ) - Sql_ShowDebug(inter->sql_handle); - - // search if character exists before to ask all map-servers - if( SQL_SUCCESS != SQL->NextRow(inter->sql_handle) ) - { - mapif->wis_response(fd, RFIFOP(fd, 4), 1); - } - else - {// Character exists. So, ask all map-servers - // to be sure of the correct name, rewrite it - SQL->GetData(inter->sql_handle, 0, &data, &len); - memset(name, 0, NAME_LENGTH); - memcpy(name, data, min(len, NAME_LENGTH)); - // if source is destination, don't ask other servers. - if (strncmp(RFIFOP(fd,4), name, NAME_LENGTH) == 0) { - mapif->wis_response(fd, RFIFOP(fd, 4), 1); - } - else - { - static int wisid = 0; - CREATE(wd, struct WisData, 1); - - // Whether the failure of previous wisp/page transmission (timeout) - inter->check_ttl_wisdata(); - - wd->id = ++wisid; - wd->fd = fd; - wd->len= RFIFOW(fd,2)-52; - memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH); - memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH); - memcpy(wd->msg, RFIFOP(fd,52), wd->len); - wd->tick = timer->gettick(); - idb_put(wis_db, wd->id, wd); - mapif->wis_message(wd); - } - } - - SQL->FreeResult(inter->sql_handle); - return 0; -} - - -// Wisp/page transmission result -int mapif_parse_WisReply(int fd) +struct WisData *inter_add_wisdata(int fd, const unsigned char *src, const unsigned char *dst, const unsigned char *msg, int msg_len) { - int id, flag; + static int wisid = 0; struct WisData *wd; - id = RFIFOL(fd,2); - flag = RFIFOB(fd,6); - wd = (struct WisData*)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 whisper, 1: target character is not logged in?, 2: ignored by target - idb_remove(wis_db, id); - } + CREATE(wd, struct WisData, 1); - return 0; -} + // Whether the failure of previous wisp/page transmission (timeout) + inter->check_ttl_wisdata(); -// 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 <min_gm_level>.w <message>.?B + wd->id = ++wisid; + wd->fd = fd; + wd->len = msg_len; + memcpy(wd->src, src, NAME_LENGTH); + memcpy(wd->dst, dst, NAME_LENGTH); + memcpy(wd->msg, msg, wd->len); + wd->tick = timer->gettick(); + idb_put(wis_db, wd->id, wd); - memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2)); // Message contains the NUL terminator (see intif_wis_message_to_gm()) - WBUFW(buf, 0) = 0x3803; - mapif->sendall(buf, RFIFOW(fd,2)); - - return 0; + return wd; } -// Save account_reg into sql (type=2) -int mapif_parse_Registry(int fd) +struct WisData *inter_get_wisdata(int id) { - int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12); - - if( count ) { - int cursor = 14, i; - char key[SCRIPT_VARNAME_LENGTH+1], sval[254]; - bool isLoginActive = sockt->session_is_active(chr->login_fd); - - if( isLoginActive ) - chr->global_accreg_to_login_start(account_id,char_id); - - for(i = 0; i < count; i++) { - unsigned int index; - int len = RFIFOB(fd, cursor); - safestrncpy(key, RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); - cursor += len + 1; - - index = RFIFOL(fd, cursor); - cursor += 4; - - switch (RFIFOB(fd, cursor++)) { - /* int */ - case 0: - inter->savereg(account_id,char_id,key,index,RFIFOL(fd, cursor),false); - cursor += 4; - break; - case 1: - inter->savereg(account_id,char_id,key,index,0,false); - break; - /* str */ - case 2: - len = RFIFOB(fd, cursor); - safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); - cursor += len + 1; - inter->savereg(account_id,char_id,key,index,(intptr_t)sval,true); - break; - case 3: - inter->savereg(account_id,char_id,key,index,0,true); - break; - default: - ShowError("mapif->parse_Registry: unknown type %d\n",RFIFOB(fd, cursor - 1)); - return 1; - } - - } - - if (isLoginActive) - chr->global_accreg_to_login_send(); - } - return 0; -} - -// Request the value of all registries. -int mapif_parse_RegistryRequest(int fd) -{ - //Load Char Registry - if (RFIFOB(fd,12)) mapif->account_reg_reply(fd,RFIFOL(fd,2),RFIFOL(fd,6),3); // 3: char reg - //Load Account Registry - if (RFIFOB(fd,11)) mapif->account_reg_reply(fd,RFIFOL(fd,2),RFIFOL(fd,6),2); // 2: account reg - //Ask Login Server for Account2 values. - if (RFIFOB(fd,10)) chr->request_accreg2(RFIFOL(fd,2),RFIFOL(fd,6)); - return 1; + return idb_get(wis_db, id); } -void mapif_namechange_ack(int fd, int account_id, int char_id, int type, int flag, const char *const name) +void inter_remove_wisdata(int id) { - nullpo_retv(name); - WFIFOHEAD(fd, NAME_LENGTH+13); - WFIFOW(fd, 0) = 0x3806; - WFIFOL(fd, 2) = account_id; - WFIFOL(fd, 6) = char_id; - WFIFOB(fd,10) = type; - WFIFOB(fd,11) = flag; - memcpy(WFIFOP(fd, 12), name, NAME_LENGTH); - WFIFOSET(fd, NAME_LENGTH+13); -} - -int mapif_parse_NameChangeRequest(int fd) -{ - int account_id, char_id, type; - const char *name; - int i; - - account_id = RFIFOL(fd,2); - char_id = RFIFOL(fd,6); - type = RFIFOB(fd,10); - name = RFIFOP(fd,11); - - // Check Authorized letters/symbols in the name - if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorized - for (i = 0; i < NAME_LENGTH && name[i]; i++) - if (strchr(char_name_letters, name[i]) == NULL) { - mapif->namechange_ack(fd, account_id, char_id, type, 0, name); - return 0; - } - } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden - for (i = 0; i < NAME_LENGTH && name[i]; i++) - if (strchr(char_name_letters, name[i]) != NULL) { - mapif->namechange_ack(fd, account_id, char_id, type, 0, name); - return 0; - } - } - //TODO: type holds the type of object to rename. - //If it were a player, it needs to have the guild information and db information - //updated here, because changing it on the map won't make it be saved [Skotlex] - - //name allowed. - mapif->namechange_ack(fd, account_id, char_id, type, 1, name); - return 0; + idb_remove(wis_db, id); } //-------------------------------------------------------- @@ -1461,4 +1169,9 @@ void inter_defaults(void) inter->final = inter_final; inter->config_read_log = inter_config_read_log; inter->config_read_connection = inter_config_read_connection; + inter->accinfo = inter_accinfo; + inter->accinfo2 = inter_accinfo2; + inter->add_wisdata = inter_add_wisdata; + inter->get_wisdata = inter_get_wisdata; + inter->remove_wisdata = inter_remove_wisdata; } diff --git a/src/char/inter.h b/src/char/inter.h index 7f901927c..94ee3ab60 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -30,6 +30,12 @@ struct Sql; // common/sql.h struct config_t; // common/conf.h +struct WisData { + int id, fd, count, len; + int64 tick; + unsigned char src[24], dst[24], msg[512]; +}; + /** * inter interface **/ @@ -56,6 +62,13 @@ struct inter_interface { bool (*config_read) (const char *filename, bool imported); bool (*config_read_log) (const char *filename, const struct config_t *config, bool imported); bool (*config_read_connection) (const char *filename, const struct config_t *config, bool imported); + void (*accinfo) (int u_fd, int aid, int castergroup, const char *query, int map_fd); + void (*accinfo2) (bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, + const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, + int group_id, int logincount, int state); + struct WisData *(*add_wisdata) (int fd, const unsigned char *src, const unsigned char *dst, const unsigned char *msg, int msg_len); + struct WisData *(*get_wisdata) (int id); + void (*remove_wisdata) (int id); }; #ifdef HERCULES_CORE diff --git a/src/char/mapif.c b/src/char/mapif.c index 28a592d57..cb1d50698 100644 --- a/src/char/mapif.c +++ b/src/char/mapif.c @@ -20,210 +20,2323 @@ */ #define HERCULES_CORE +#include "config/core.h" // GP_BOUND_ITEMS #include "mapif.h" #include "char/char.h" #include "char/int_auction.h" +#include "char/int_clan.h" #include "char/int_guild.h" #include "char/int_homun.h" +#include "char/int_elemental.h" +#include "char/int_mail.h" +#include "char/int_mercenary.h" +#include "char/int_party.h" +#include "char/int_pet.h" +#include "char/int_quest.h" #include "char/int_rodex.h" +#include "char/int_storage.h" +#include "char/inter.h" #include "common/cbasetypes.h" +#include "common/memmgr.h" #include "common/mmo.h" +#include "common/nullpo.h" #include "common/random.h" #include "common/showmsg.h" #include "common/socket.h" +#include "common/sql.h" #include "common/strlib.h" #include <stdlib.h> -void mapif_ban(int id, unsigned int flag, int status); -void mapif_server_init(int id); -void mapif_server_destroy(int id); -void mapif_server_reset(int id); -void mapif_on_disconnect(int id); -void mapif_on_parse_accinfo(int account_id, int u_fd, int u_aid, int u_group, int map_fd); -void mapif_char_ban(int char_id, time_t timestamp); -int mapif_sendall(const unsigned char *buf, unsigned int len); -int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len); -int mapif_send(int fd, unsigned char *buf, unsigned int len); -void mapif_send_users_count(int users); -void mapif_auction_message(int char_id, unsigned char result); -void mapif_auction_sendlist(int fd, int char_id, short count, short pages, unsigned char *buf); -void mapif_parse_auction_requestlist(int fd); -void mapif_auction_register(int fd, struct auction_data *auction); -void mapif_parse_auction_register(int fd); -void mapif_auction_cancel(int fd, int char_id, unsigned char result); -void mapif_parse_auction_cancel(int fd); -void mapif_auction_close(int fd, int char_id, unsigned char result); -void mapif_parse_auction_close(int fd); -void mapif_auction_bid(int fd, int char_id, int bid, unsigned char result); -void mapif_parse_auction_bid(int fd); -bool mapif_elemental_create(struct s_elemental *ele); -bool mapif_elemental_save(const struct s_elemental *ele); -bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele); -bool mapif_elemental_delete(int ele_id); -void mapif_elemental_send(int fd, struct s_elemental *ele, unsigned char flag); -void mapif_parse_elemental_create(int fd, const struct s_elemental *ele); -void mapif_parse_elemental_load(int fd, int ele_id, int char_id); -void mapif_elemental_deleted(int fd, unsigned char flag); -void mapif_parse_elemental_delete(int fd, int ele_id); -void mapif_elemental_saved(int fd, unsigned char flag); -void mapif_parse_elemental_save(int fd, const struct s_elemental *ele); -int mapif_guild_created(int fd, int account_id, struct guild *g); -int mapif_guild_noinfo(int fd, int guild_id); -int mapif_guild_info(int fd, struct guild *g); -int mapif_guild_memberadded(int fd, int guild_id, int account_id, int char_id, int flag); -int mapif_guild_withdraw(int guild_id, int account_id, int char_id, int flag, const char *name, const char *mes); -int mapif_guild_memberinfoshort(struct guild *g, int idx); -int mapif_guild_broken(int guild_id, int flag); -int mapif_guild_message(int guild_id, int account_id, const char *mes, int len, int sfd); -int mapif_guild_basicinfochanged(int guild_id, int type, const void *data, int len); -int mapif_guild_memberinfochanged(int guild_id, int account_id, int char_id, int type, const void *data, int len); -int mapif_guild_skillupack(int guild_id, uint16 skill_id, int account_id); -int mapif_guild_alliance(int guild_id1, int guild_id2, int account_id1, int account_id2, int flag, const char *name1, const char *name2); -int mapif_guild_position(struct guild *g, int idx); -int mapif_guild_notice(struct guild *g); -int mapif_guild_emblem(struct guild *g); -int mapif_guild_master_changed(struct guild *g, int aid, int cid); -int mapif_guild_castle_dataload(int fd, int sz, const int *castle_ids); -int mapif_parse_CreateGuild(int fd, int account_id, const char *name, const struct guild_member *master); -int mapif_parse_GuildInfo(int fd, int guild_id); -int mapif_parse_GuildAddMember(int fd, int guild_id, const struct guild_member *m); -int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, int flag, const char *mes); -int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id, int char_id, int online, int lv, int16 class); -int mapif_parse_BreakGuild(int fd, int guild_id); -int mapif_parse_GuildMessage(int fd, int guild_id, int account_id, const char *mes, int len); -int mapif_parse_GuildBasicInfoChange(int fd, int guild_id, int type, const void *data, int len); -int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int char_id, int type, const char *data, int len); -int mapif_parse_GuildPosition(int fd, int guild_id, int idx, const struct guild_position *p); -int mapif_parse_GuildSkillUp(int fd, int guild_id, uint16 skill_id, int account_id, int max); -int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, int account_id1, int account_id2, int flag); -int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_id1, int account_id2, int flag); -int mapif_parse_GuildNotice(int fd, int guild_id, const char *mes1, const char *mes2); -int mapif_parse_GuildEmblem(int fd, int len, int guild_id, int dummy, const char *data); -int mapif_parse_GuildCastleDataLoad(int fd, int len, const int *castle_ids); -int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value); -int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int len); -void mapif_homunculus_created(int fd, int account_id, const struct s_homunculus *sh, unsigned char flag); -void mapif_homunculus_deleted(int fd, int flag); -void mapif_homunculus_loaded(int fd, int account_id, struct s_homunculus *hd); -void mapif_homunculus_saved(int fd, int account_id, bool flag); -void mapif_homunculus_renamed(int fd, int account_id, int char_id, unsigned char flag, const char *name); -bool mapif_homunculus_create(struct s_homunculus *hd); -bool mapif_homunculus_save(const struct s_homunculus *hd); -bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd); -bool mapif_homunculus_delete(int homun_id); -bool mapif_homunculus_rename(const char *name); -void mapif_parse_homunculus_create(int fd, int len, int account_id, const struct s_homunculus *phd); -void mapif_parse_homunculus_delete(int fd, int homun_id); -void mapif_parse_homunculus_load(int fd, int account_id, int homun_id); -void mapif_parse_homunculus_save(int fd, int len, int account_id, const struct s_homunculus *phd); -void mapif_parse_homunculus_rename(int fd, int account_id, int char_id, const char *name); -void mapif_mail_sendinbox(int fd, int char_id, unsigned char flag, struct mail_data *md); -void mapif_parse_mail_requestinbox(int fd); -void mapif_parse_mail_read(int fd); -void mapif_mail_sendattach(int fd, int char_id, struct mail_message *msg); -void mapif_mail_getattach(int fd, int char_id, int mail_id); -void mapif_parse_mail_getattach(int fd); -void mapif_mail_delete(int fd, int char_id, int mail_id, bool failed); -void mapif_parse_mail_delete(int fd); -void mapif_mail_new(struct mail_message *msg); -void mapif_mail_return(int fd, int char_id, int mail_id, int new_mail); -void mapif_parse_mail_return(int fd); -void mapif_mail_send(int fd, struct mail_message* msg); -void mapif_parse_mail_send(int fd); -bool mapif_mercenary_create(struct s_mercenary *merc); -bool mapif_mercenary_save(const struct s_mercenary *merc); -bool mapif_mercenary_load(int merc_id, int char_id, struct s_mercenary *merc); -bool mapif_mercenary_delete(int merc_id); -void mapif_mercenary_send(int fd, struct s_mercenary *merc, unsigned char flag); -void mapif_parse_mercenary_create(int fd, const struct s_mercenary *merc); -void mapif_parse_mercenary_load(int fd, int merc_id, int char_id); -void mapif_mercenary_deleted(int fd, unsigned char flag); -void mapif_parse_mercenary_delete(int fd, int merc_id); -void mapif_mercenary_saved(int fd, unsigned char flag); -void mapif_parse_mercenary_save(int fd, const struct s_mercenary *merc); -int mapif_party_created(int fd, int account_id, int char_id, struct party *p); -void mapif_party_noinfo(int fd, int party_id, int char_id); -void mapif_party_info(int fd, struct party* p, int char_id); -int mapif_party_memberadded(int fd, int party_id, int account_id, int char_id, int flag); -int mapif_party_optionchanged(int fd, struct party *p, int account_id, int flag); -int mapif_party_withdraw(int party_id,int account_id, int char_id); -int mapif_party_membermoved(struct party *p, int idx); -int mapif_party_broken(int party_id, int flag); -int mapif_party_message(int party_id, int account_id, const char *mes, int len, int sfd); -int mapif_parse_CreateParty(int fd, const char *name, int item, int item2, const struct party_member *leader); -void mapif_parse_PartyInfo(int fd, int party_id, int char_id); -int mapif_parse_PartyAddMember(int fd, int party_id, const struct party_member *member); -int mapif_parse_PartyChangeOption(int fd,int party_id,int account_id,int exp,int item); -int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id); -int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv); -int mapif_parse_BreakParty(int fd, int party_id); -int mapif_parse_PartyMessage(int fd, int party_id, int account_id, const char *mes, int len); -int mapif_parse_PartyLeaderChange(int fd, int party_id, int account_id, int char_id); -int mapif_pet_created(int fd, int account_id, struct s_pet *p); -int mapif_pet_info(int fd, int account_id, struct s_pet *p); -int mapif_pet_noinfo(int fd, int account_id); -int mapif_save_pet_ack(int fd, int account_id, int flag); -int mapif_delete_pet_ack(int fd, int flag); -int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id, - short pet_equip, short intimate, short hungry, char rename_flag, char incubate, const char *pet_name); -int mapif_load_pet(int fd, int account_id, int char_id, int pet_id); -int mapif_save_pet(int fd, int account_id, const struct s_pet *data); -int mapif_delete_pet(int fd, int pet_id); -int mapif_parse_CreatePet(int fd); -int mapif_parse_LoadPet(int fd); -int mapif_parse_SavePet(int fd); -int mapif_parse_DeletePet(int fd); -struct quest *mapif_quests_fromsql(int char_id, int *count); -bool mapif_quest_delete(int char_id, int quest_id); -bool mapif_quest_add(int char_id, struct quest qd); -bool mapif_quest_update(int char_id, struct quest qd); -void mapif_quest_save_ack(int fd, int char_id, bool success); -int mapif_parse_quest_save(int fd); -void mapif_send_quests(int fd, int char_id, struct quest *tmp_questlog, int num_quests); -int mapif_parse_quest_load(int fd); +void mapif_ban(int id, unsigned int flag, int status) +{ + // send to all map-servers to disconnect the player + unsigned char buf[11]; + WBUFW(buf,0) = 0x2b14; + WBUFL(buf,2) = id; + WBUFB(buf,6) = flag; // 0: change of status, 1: ban + WBUFL(buf,7) = status; // status or final date of a banishment + mapif->sendall(buf, 11); +} + +/// Initializes a server structure. +void mapif_server_init(int id) +{ + //memset(&chr->server[id], 0, sizeof(server[id])); + chr->server[id].fd = -1; +} + +/// Destroys a server structure. +void mapif_server_destroy(int id) +{ + if (chr->server[id].fd == -1) { + sockt->close(chr->server[id].fd); + chr->server[id].fd = -1; + } +} + +/// Resets all the data related to a server. +void mapif_server_reset(int id) +{ + int i, j; + unsigned char buf[16384]; + int fd = chr->server[id].fd; + //Notify other map servers that this one is gone. [Skotlex] + WBUFW(buf, 0) = 0x2b20; + WBUFL(buf, 4) = htonl(chr->server[id].ip); + WBUFW(buf, 8) = htons(chr->server[id].port); + j = 0; + for (i = 0; i < VECTOR_LENGTH(chr->server[id].maps); i++) { + uint16 m = VECTOR_INDEX(chr->server[id].maps, i); + if (m != 0) + WBUFW(buf, 10 + (j++) * 4) = m; + } + if (j > 0) { + WBUFW(buf, 2) = j * 4 + 10; + mapif->sendallwos(fd, buf, WBUFW(buf, 2)); + } + if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `index`='%d'", ragsrvinfo_db, chr->server[id].fd)) + Sql_ShowDebug(inter->sql_handle); + chr->online_char_db->foreach(chr->online_char_db, chr->db_setoffline, id); //Tag relevant chars as 'in disconnected' server. + mapif->server_destroy(id); + mapif->server_init(id); +} + +/// Called when the connection to a Map Server is disconnected. +void mapif_on_disconnect(int id) +{ + ShowStatus("Map-server #%d has disconnected.\n", id); + mapif->server_reset(id); +} + +void mapif_on_parse_accinfo(int account_id, int u_fd, int u_aid, int u_group, int map_fd) +{ + Assert_retv(chr->login_fd > 0); + WFIFOHEAD(chr->login_fd, 22); + WFIFOW(chr->login_fd, 0) = 0x2740; + WFIFOL(chr->login_fd, 2) = account_id; + WFIFOL(chr->login_fd, 6) = u_fd; + WFIFOL(chr->login_fd, 10) = u_aid; + WFIFOL(chr->login_fd, 14) = u_group; + WFIFOL(chr->login_fd, 18) = map_fd; + WFIFOSET(chr->login_fd, 22); +} + +void mapif_char_ban(int char_id, time_t timestamp) +{ + unsigned char buf[11]; + WBUFW(buf, 0) = 0x2b14; + WBUFL(buf, 2) = char_id; + WBUFB(buf, 6) = 2; + WBUFL(buf, 7) = (unsigned int)timestamp; + mapif->sendall(buf, 11); +} + +int mapif_sendall(const unsigned char *buf, unsigned int len) +{ + int i, c; + + nullpo_ret(buf); + c = 0; + for (i = 0; i < ARRAYLENGTH(chr->server); i++) { + int fd; + if ((fd = chr->server[i].fd) > 0) { + WFIFOHEAD(fd, len); + memcpy(WFIFOP(fd, 0), buf, len); + WFIFOSET(fd, len); + c++; + } + } + + return c; +} + +int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len) +{ + int i, c; + + nullpo_ret(buf); + c = 0; + for (i = 0; i < ARRAYLENGTH(chr->server); i++) { + int fd; + if ((fd = chr->server[i].fd) > 0 && fd != sfd) { + WFIFOHEAD(fd, len); + memcpy(WFIFOP(fd, 0), buf, len); + WFIFOSET(fd, len); + c++; + } + } + + return c; +} + + +int mapif_send(int fd, unsigned char *buf, unsigned int len) +{ + nullpo_ret(buf); + if (fd >= 0) { + int i; + ARR_FIND (0, ARRAYLENGTH(chr->server), i, fd == chr->server[i].fd); + if (i < ARRAYLENGTH(chr->server)) { + WFIFOHEAD(fd, len); + memcpy(WFIFOP(fd, 0), buf, len); + WFIFOSET(fd, len); + return 1; + } + } + return 0; +} + +void mapif_send_users_count(int users) +{ + uint8 buf[6]; + // send number of players to all map-servers + WBUFW(buf, 0) = 0x2b00; + WBUFL(buf, 2) = users; + mapif->sendall(buf, 6); +} + + +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; + mapif->sendall(buf, 7); +} + +void mapif_auction_sendlist(int fd, int char_id, short count, short pages, unsigned char *buf) +{ + int len = (sizeof(struct auction_data) * count) + 12; + + nullpo_retv(buf); + + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = 0x3850; + WFIFOW(fd, 2) = len; + WFIFOL(fd, 4) = char_id; + WFIFOW(fd, 8) = count; + WFIFOW(fd, 10) = pages; + memcpy(WFIFOP(fd, 12), buf, len - 12); + WFIFOSET(fd, len); +} + +void mapif_parse_auction_requestlist(int fd) +{ + char searchtext[NAME_LENGTH]; + int char_id = RFIFOL(fd, 4), len = sizeof(struct auction_data); + int price = RFIFOL(fd, 10); + short type = RFIFOW(fd, 8), page = max(1, RFIFOW(fd, 14)); + unsigned char buf[5 * sizeof(struct auction_data)]; + struct DBIterator *iter = db_iterator(inter_auction->db); + struct auction_data *auction; + short i = 0, j = 0, pages = 1; + + memcpy(searchtext, RFIFOP(fd, 16), NAME_LENGTH); + + for (auction = dbi_first(iter); dbi_exists(iter); auction = dbi_next(iter)) { + if ((type == 0 && auction->type != IT_ARMOR && auction->type != IT_PETARMOR) + || (type == 1 && auction->type != IT_WEAPON) + || (type == 2 && auction->type != IT_CARD) + || (type == 3 && auction->type != IT_ETC) + || (type == 4 && !strstr(auction->item_name, searchtext)) + || (type == 5 && auction->price > price) + || (type == 6 && auction->seller_id != char_id) + || (type == 7 && auction->buyer_id != char_id)) + continue; + + i++; + if (i > 5) { + // Counting Pages of Total Results (5 Results per Page) + pages++; + i = 1; // First Result of This Page + } + + if (page != pages) + continue; // This is not the requested Page + + memcpy(WBUFP(buf, j * len), auction, len); + j++; // Found Results + } + dbi_destroy(iter); + + mapif->auction_sendlist(fd, char_id, j, pages, buf); +} + +void mapif_auction_register(int fd, struct auction_data *auction) +{ + int len = sizeof(struct auction_data) + 4; + + nullpo_retv(auction); + + WFIFOHEAD(fd,len); + WFIFOW(fd, 0) = 0x3851; + WFIFOW(fd, 2) = len; + memcpy(WFIFOP(fd, 4), auction, sizeof(struct auction_data)); + WFIFOSET(fd, len); +} + +void mapif_parse_auction_register(int fd) +{ + struct auction_data auction; + if( RFIFOW(fd, 2) != sizeof(struct auction_data) + 4 ) + return; + + memcpy(&auction, RFIFOP(fd, 4), sizeof(struct auction_data)); + if( inter_auction->count(auction.seller_id, false) < 5 ) + auction.auction_id = inter_auction->create(&auction); + + mapif->auction_register(fd, &auction); +} + +void mapif_auction_cancel(int fd, int char_id, unsigned char result) +{ + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x3852; + WFIFOL(fd, 2) = char_id; + WFIFOB(fd, 6) = result; + WFIFOSET(fd, 7); +} + +void mapif_parse_auction_cancel(int fd) +{ + int char_id = RFIFOL(fd, 2), auction_id = RFIFOL(fd, 6); + struct auction_data *auction; + + if ((auction = (struct auction_data *)idb_get(inter_auction->db, auction_id)) == NULL) { + mapif->auction_cancel(fd, char_id, 1); // Bid Number is Incorrect + return; + } + + if (auction->seller_id != char_id) { + mapif->auction_cancel(fd, char_id, 2); // You cannot end the auction + return; + } + + if (auction->buyer_id > 0) { + mapif->auction_cancel(fd, char_id, 3); // An auction with at least one bidder cannot be canceled + return; + } + + inter_mail->sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Auction canceled.", 0, &auction->item); + inter_auction->delete_(auction); + + mapif->auction_cancel(fd, char_id, 0); // The auction has been canceled +} + + +void mapif_auction_close(int fd, int char_id, unsigned char result) +{ + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x3853; + WFIFOL(fd, 2) = char_id; + WFIFOB(fd, 6) = result; + WFIFOSET(fd, 7); +} + +void mapif_parse_auction_close(int fd) +{ + int char_id = RFIFOL(fd, 2), auction_id = RFIFOL(fd, 6); + struct auction_data *auction; + + if ((auction = (struct auction_data *)idb_get(inter_auction->db, auction_id)) == NULL) { + mapif->auction_close(fd, char_id, 2); // Bid Number is Incorrect + return; + } + + if (auction->seller_id != char_id) { + mapif->auction_close(fd, char_id, 1); // You cannot end the auction + return; + } + + if (auction->buyer_id == 0) { + mapif->auction_close(fd, char_id, 1); // You cannot end the auction + return; + } + + // Send Money to Seller + inter_mail->sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Auction closed.", auction->price, NULL); + // Send Item to Buyer + inter_mail->sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Auction winner.", 0, &auction->item); + mapif->auction_message(auction->buyer_id, 6); // You have won the auction + inter_auction->delete_(auction); + + mapif->auction_close(fd, char_id, 0); // You have ended the auction +} + +void mapif_auction_bid(int fd, int char_id, int bid, unsigned char result) +{ + WFIFOHEAD(fd, 11); + WFIFOW(fd, 0) = 0x3855; + WFIFOL(fd, 2) = char_id; + WFIFOL(fd, 6) = bid; // To Return Zeny + WFIFOB(fd, 10) = result; + WFIFOSET(fd, 11); +} + +void mapif_parse_auction_bid(int fd) +{ + int char_id = RFIFOL(fd, 4), bid = RFIFOL(fd, 12); + unsigned int auction_id = RFIFOL(fd, 8); + struct auction_data *auction; + + if ((auction = (struct auction_data *)idb_get(inter_auction->db, auction_id)) == NULL || auction->price >= bid || auction->seller_id == char_id) { + mapif->auction_bid(fd, char_id, bid, 0); // You have failed to bid in the auction + return; + } + + if (inter_auction->count(char_id, true) > 4 && bid < auction->buynow && auction->buyer_id != char_id) { + mapif->auction_bid(fd, char_id, bid, 9); // You cannot place more than 5 bids at a time + return; + } + + if (auction->buyer_id > 0) { + // Send Money back to the previous Buyer + if (auction->buyer_id != char_id) { + inter_mail->sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "Someone has placed a higher bid.", auction->price, NULL); + mapif->auction_message(auction->buyer_id, 7); // You have failed to win the auction + } else { + inter_mail->sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "You have placed a higher bid.", auction->price, NULL); + } + } + + auction->buyer_id = char_id; + safestrncpy(auction->buyer_name, RFIFOP(fd, 16), NAME_LENGTH); + auction->price = bid; + + if (bid >= auction->buynow) { + // Automatic won the auction + mapif->auction_bid(fd, char_id, bid - auction->buynow, 1); // You have successfully bid in the auction + + inter_mail->sendmail(0, "Auction Manager", auction->buyer_id, auction->buyer_name, "Auction", "You have won the auction.", 0, &auction->item); + mapif->auction_message(char_id, 6); // You have won the auction + inter_mail->sendmail(0, "Auction Manager", auction->seller_id, auction->seller_name, "Auction", "Payment for your auction!.", auction->buynow, NULL); + + inter_auction->delete_(auction); + return; + } + + inter_auction->save(auction); + + mapif->auction_bid(fd, char_id, 0, 1); // You have successfully bid in the auction +} + +void mapif_elemental_send(int fd, struct s_elemental *ele, unsigned char flag) +{ + int size = sizeof(struct s_elemental) + 5; + + nullpo_retv(ele); + WFIFOHEAD(fd, size); + WFIFOW(fd, 0) = 0x387c; + WFIFOW(fd, 2) = size; + WFIFOB(fd, 4) = flag; + memcpy(WFIFOP(fd, 5), ele, sizeof(struct s_elemental)); + WFIFOSET(fd, size); +} + +void mapif_parse_elemental_create(int fd, const struct s_elemental *ele) +{ + struct s_elemental ele_; + bool result; + + memcpy(&ele_, ele, sizeof(ele_)); + + result = inter_elemental->create(&ele_); + mapif->elemental_send(fd, &ele_, result); +} + +void mapif_parse_elemental_load(int fd, int ele_id, int char_id) +{ + struct s_elemental ele; + bool result = inter_elemental->load(ele_id, char_id, &ele); + mapif->elemental_send(fd, &ele, result); +} + +void mapif_elemental_deleted(int fd, unsigned char flag) +{ + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x387d; + WFIFOB(fd, 2) = flag; + WFIFOSET(fd, 3); +} + +void mapif_parse_elemental_delete(int fd, int ele_id) +{ + bool result = inter_elemental->delete(ele_id); + mapif->elemental_deleted(fd, result); +} + +void mapif_elemental_saved(int fd, unsigned char flag) +{ + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x387e; + WFIFOB(fd, 2) = flag; + WFIFOSET(fd, 3); +} + +void mapif_parse_elemental_save(int fd, const struct s_elemental *ele) +{ + bool result = inter_elemental->save(ele); + mapif->elemental_saved(fd, result); +} + +int mapif_guild_created(int fd, int account_id, struct guild *g) +{ + WFIFOHEAD(fd, 10); + WFIFOW(fd, 0) = 0x3830; + WFIFOL(fd, 2) = account_id; + if (g != NULL) { + WFIFOL(fd, 6) = g->guild_id; + ShowInfo("int_guild: Guild created (%d - %s)\n", g->guild_id, g->name); + } else { + WFIFOL(fd, 6) = 0; + } + + WFIFOSET(fd, 10); + return 0; +} + +// Guild not found +int mapif_guild_noinfo(int fd, int guild_id) +{ + unsigned char buf[12]; + WBUFW(buf, 0) = 0x3831; + WBUFW(buf, 2) = 8; + WBUFL(buf, 4) = guild_id; + ShowWarning("int_guild: info not found %d\n", guild_id); + if (fd < 0) + mapif->sendall(buf, 8); + else + mapif->send(fd,buf, 8); + return 0; +} + +// Send guild info +int mapif_guild_info(int fd, struct guild *g) +{ + unsigned char buf[8 + sizeof(struct guild)]; + nullpo_ret(g); + WBUFW(buf, 0) = 0x3831; + WBUFW(buf, 2) = 4 + sizeof(struct guild); + memcpy(buf + 4, g, sizeof(struct guild)); + if (fd < 0) + mapif->sendall(buf, WBUFW(buf, 2)); + else + mapif->send(fd, buf, WBUFW(buf, 2)); + return 0; +} + +// ACK member add +int mapif_guild_memberadded(int fd, int guild_id, int account_id, int char_id, int flag) +{ + WFIFOHEAD(fd, 15); + WFIFOW(fd, 0) = 0x3832; + WFIFOL(fd, 2) = guild_id; + WFIFOL(fd, 6) = account_id; + WFIFOL(fd, 10) = char_id; + WFIFOB(fd, 14) = flag; + WFIFOSET(fd, 15); + return 0; +} + +// ACK member leave +int mapif_guild_withdraw(int guild_id, int account_id, int char_id, int flag, const char *name, const char *mes) +{ + unsigned char buf[55 + NAME_LENGTH]; + + nullpo_ret(name); + nullpo_ret(mes); + + WBUFW(buf, 0) = 0x3834; + WBUFL(buf, 2) = guild_id; + WBUFL(buf, 6) = account_id; + WBUFL(buf, 10) = char_id; + WBUFB(buf, 14) = flag; + memcpy(WBUFP(buf, 15), mes, 40); + memcpy(WBUFP(buf, 55), name, NAME_LENGTH); + mapif->sendall(buf, 55 + NAME_LENGTH); + ShowInfo("int_guild: guild withdraw (%d - %d: %s - %s)\n", guild_id, account_id, name, mes); + return 0; +} + +// Send short member's info +int mapif_guild_memberinfoshort(struct guild *g, int idx) +{ + unsigned char buf[23]; + nullpo_ret(g); + Assert_ret(idx >= 0 && idx < MAX_GUILD); + WBUFW(buf, 0) = 0x3835; + WBUFL(buf, 2) = g->guild_id; + WBUFL(buf, 6) = g->member[idx].account_id; + WBUFL(buf, 10) = g->member[idx].char_id; + WBUFB(buf, 14) = (unsigned char)g->member[idx].online; + WBUFW(buf, 15) = g->member[idx].lv; + WBUFW(buf, 17) = g->member[idx].class; + WBUFL(buf, 19) = g->member[idx].last_login; + mapif->sendall(buf, 23); + return 0; +} + +// Send guild broken +int mapif_guild_broken(int guild_id, int flag) +{ + unsigned char buf[7]; + WBUFW(buf, 0) = 0x3836; + WBUFL(buf, 2) = guild_id; + WBUFB(buf, 6) = flag; + mapif->sendall(buf, 7); + ShowInfo("int_guild: Guild broken (%d)\n", guild_id); + return 0; +} + +// Send guild message +int mapif_guild_message(int guild_id, int account_id, const char *mes, int len, int sfd) +{ + unsigned char buf[512]; + nullpo_ret(mes); + if (len > 500) + len = 500; + WBUFW(buf, 0) = 0x3837; + WBUFW(buf, 2) = len + 12; + WBUFL(buf, 4) = guild_id; + WBUFL(buf, 8) = account_id; + memcpy(WBUFP(buf, 12), mes, len); + mapif->sendallwos(sfd, buf, len + 12); + return 0; +} + +// Send basic info +int mapif_guild_basicinfochanged(int guild_id, int type, const void *data, int len) +{ + unsigned char buf[2048]; + nullpo_ret(data); + if (len > 2038) + len = 2038; + WBUFW(buf, 0) = 0x3839; + WBUFW(buf, 2) = len + 10; + WBUFL(buf, 4) = guild_id; + WBUFW(buf, 8) = type; + memcpy(WBUFP(buf, 10), data, len); + mapif->sendall(buf, len + 10); + return 0; +} + +// Send member info +int mapif_guild_memberinfochanged(int guild_id, int account_id, int char_id, int type, const void *data, int len) +{ + unsigned char buf[2048]; + nullpo_ret(data); + if (len > 2030) + len = 2030; + WBUFW(buf, 0) = 0x383a; + WBUFW(buf, 2) = len + 18; + WBUFL(buf, 4) = guild_id; + WBUFL(buf, 8) = account_id; + WBUFL(buf, 12) = char_id; + WBUFW(buf, 16) = type; + memcpy(WBUFP(buf, 18), data, len); + mapif->sendall(buf, len + 18); + return 0; +} + +// ACK guild skill up +int mapif_guild_skillupack(int guild_id, uint16 skill_id, int account_id) +{ + unsigned char buf[14]; + WBUFW(buf, 0) = 0x383c; + WBUFL(buf, 2) = guild_id; + WBUFL(buf, 6) = skill_id; + WBUFL(buf,10) = account_id; + mapif->sendall(buf, 14); + return 0; +} + +// ACK guild alliance +int mapif_guild_alliance(int guild_id1, int guild_id2, int account_id1, int account_id2, int flag, const char *name1, const char *name2) +{ + unsigned char buf[19 + 2 * NAME_LENGTH]; + nullpo_ret(name1); + nullpo_ret(name2); + WBUFW(buf, 0) = 0x383d; + WBUFL(buf, 2) = guild_id1; + WBUFL(buf, 6) = guild_id2; + WBUFL(buf, 10) = account_id1; + WBUFL(buf, 14) = account_id2; + WBUFB(buf, 18) = flag; + memcpy(WBUFP(buf, 19), name1, NAME_LENGTH); + memcpy(WBUFP(buf, 19 + NAME_LENGTH), name2, NAME_LENGTH); + mapif->sendall(buf,19 + 2 * NAME_LENGTH); + return 0; +} + +// Send a guild position desc +int mapif_guild_position(struct guild *g, int idx) +{ + unsigned char buf[12 + sizeof(struct guild_position)]; + nullpo_ret(g); + Assert_ret(idx >= 0 && idx < MAX_GUILDPOSITION); + WBUFW(buf, 0) = 0x383b; + WBUFW(buf, 2) = sizeof(struct guild_position)+12; + WBUFL(buf, 4) = g->guild_id; + WBUFL(buf, 8) = idx; + memcpy(WBUFP(buf, 12), &g->position[idx], sizeof(struct guild_position)); + mapif->sendall(buf, WBUFW(buf, 2)); + return 0; +} + +// Send the guild notice +int mapif_guild_notice(struct guild *g) +{ + unsigned char buf[256]; + nullpo_ret(g); + WBUFW(buf, 0) = 0x383e; + WBUFL(buf, 2) = g->guild_id; + memcpy(WBUFP(buf, 6), g->mes1, MAX_GUILDMES1); + memcpy(WBUFP(buf, 66), g->mes2, MAX_GUILDMES2); + mapif->sendall(buf, 186); + return 0; +} + +// Send emblem data +int mapif_guild_emblem(struct guild *g) +{ + unsigned char buf[12 + sizeof(g->emblem_data)]; + nullpo_ret(g); + WBUFW(buf, 0) = 0x383f; + WBUFW(buf, 2) = g->emblem_len+12; + WBUFL(buf, 4) = g->guild_id; + WBUFL(buf, 8) = g->emblem_id; + memcpy(WBUFP(buf, 12), g->emblem_data, g->emblem_len); + mapif->sendall(buf, WBUFW(buf, 2)); + return 0; +} + +int mapif_guild_master_changed(struct guild *g, int aid, int cid) +{ + unsigned char buf[14]; + nullpo_ret(g); + WBUFW(buf, 0) = 0x3843; + WBUFL(buf, 2) = g->guild_id; + WBUFL(buf, 6) = aid; + WBUFL(buf, 10) = cid; + mapif->sendall(buf, 14); + return 0; +} + +int mapif_guild_castle_dataload(int fd, int sz, const int *castle_ids) +{ + struct guild_castle *gc = NULL; + int num = (sz - 4) / sizeof(int); + int len = 4 + num * sizeof(*gc); + int i; + + nullpo_ret(castle_ids); + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = 0x3840; + WFIFOW(fd, 2) = len; + for (i = 0; i < num; i++) { + gc = inter_guild->castle_fromsql(*(castle_ids++)); + memcpy(WFIFOP(fd, 4 + i * sizeof(*gc)), gc, sizeof(*gc)); + } + WFIFOSET(fd, len); + return 0; +} + +// Guild creation request +int mapif_parse_CreateGuild(int fd, int account_id, const char *name, const struct guild_member *master) +{ + struct guild *g; + nullpo_ret(name); + nullpo_ret(master); + + g = inter_guild->create(name, master); + + // Report to client + mapif->guild_created(fd,account_id,g); + if (g != NULL) { + mapif->guild_info(fd,g); + } + + return 0; +} + +// Return guild info to client +int mapif_parse_GuildInfo(int fd, int guild_id) +{ + struct guild * g = inter_guild->fromsql(guild_id); //We use this because on start-up the info of castle-owned guilds is required. [Skotlex] + if (g != NULL) { + if (!inter_guild->calcinfo(g)) + mapif->guild_info(fd, g); + } else { + mapif->guild_noinfo(fd, guild_id); // Failed to load info + } + return 0; +} + +// Add member to guild +int mapif_parse_GuildAddMember(int fd, int guild_id, const struct guild_member *m) +{ + nullpo_ret(m); + + if (!inter_guild->add_member(guild_id, m)) { + mapif->guild_memberadded(fd, guild_id, m->account_id, m->char_id, 1); // 1: Failed to add + } else { + mapif->guild_memberadded(fd, guild_id, m->account_id, m->char_id, 0); // 0: success + } + return 0; +} + +// Delete member from guild +int mapif_parse_GuildLeave(int fd, int guild_id, int account_id, int char_id, int flag, const char *mes) +{ + inter_guild->leave(guild_id, account_id, char_id, flag, mes, fd); + return 0; +} + +// Change member info +int mapif_parse_GuildChangeMemberInfoShort(int fd, int guild_id, int account_id, int char_id, int online, int lv, int16 class) +{ + inter_guild->update_member_info_short(guild_id, account_id, char_id, online, lv, class); + return 0; +} + +// BreakGuild +int mapif_parse_BreakGuild(int fd, int guild_id) +{ + inter_guild->disband(guild_id); + return 0; +} + +// Forward Guild message to others map servers +int mapif_parse_GuildMessage(int fd, int guild_id, int account_id, const char *mes, int len) +{ + return mapif->guild_message(guild_id,account_id,mes,len, fd); +} + +/** + * Changes basic guild information + * The types are available in mmo.h::guild_basic_info + **/ +int mapif_parse_GuildBasicInfoChange(int fd, int guild_id, int type, const void *data, int len) +{ + inter_guild->update_basic_info(guild_id, type, data, len); + // Information is already sent in mapif->guild_info + //mapif->guild_basicinfochanged(guild_id,type,data,len); + return 0; +} + +// Modification of the guild +int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int char_id, int type, const char *data, int len) +{ + inter_guild->update_member_info(guild_id, account_id, char_id, type, data, len); + return 0; +} + +// Change a position desc +int mapif_parse_GuildPosition(int fd, int guild_id, int idx, const struct guild_position *p) +{ + nullpo_ret(p); + inter_guild->update_position(guild_id, idx, p); + return 0; +} + +// Guild Skill UP +int mapif_parse_GuildSkillUp(int fd, int guild_id, uint16 skill_id, int account_id, int max) +{ + inter_guild->use_skill_point(guild_id, skill_id, account_id, max); + return 0; +} + +// Alliance modification +int mapif_parse_GuildAlliance(int fd, int guild_id1, int guild_id2, int account_id1, int account_id2, int flag) +{ + inter_guild->change_alliance(guild_id1, guild_id2, account_id1, account_id2, flag); + return 0; +} + +// Change guild message +int mapif_parse_GuildNotice(int fd, int guild_id, const char *mes1, const char *mes2) +{ + inter_guild->update_notice(guild_id, mes1, mes2); + return 0; +} + +int mapif_parse_GuildEmblem(int fd, int len, int guild_id, int dummy, const char *data) +{ + inter_guild->update_emblem(len, guild_id, data); + return 0; +} + +int mapif_parse_GuildCastleDataLoad(int fd, int len, const int *castle_ids) +{ + return mapif->guild_castle_dataload(fd, len, castle_ids); +} + +int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value) +{ + inter_guild->update_castle_data(castle_id, index, value); + return 0; +} + +int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int len) +{ + inter_guild->change_leader(guild_id, name, len); + return 0; +} + +void mapif_homunculus_created(int fd, int account_id, const struct s_homunculus *sh, unsigned char flag) +{ + nullpo_retv(sh); + WFIFOHEAD(fd, sizeof(struct s_homunculus) + 9); + WFIFOW(fd, 0) = 0x3890; + WFIFOW(fd, 2) = sizeof(struct s_homunculus) + 9; + WFIFOL(fd, 4) = account_id; + WFIFOB(fd, 8) = flag; + memcpy(WFIFOP(fd, 9), sh, sizeof(struct s_homunculus)); + WFIFOSET(fd, WFIFOW(fd, 2)); +} + +void mapif_homunculus_deleted(int fd, int flag) +{ + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x3893; + WFIFOB(fd,2) = flag; //Flag 1 = success + WFIFOSET(fd, 3); +} + +void mapif_homunculus_loaded(int fd, int account_id, struct s_homunculus *hd) +{ + WFIFOHEAD(fd, sizeof(struct s_homunculus) + 9); + WFIFOW(fd, 0) = 0x3891; + WFIFOW(fd, 2) = sizeof(struct s_homunculus) + 9; + WFIFOL(fd, 4) = account_id; + if (hd != NULL) { + WFIFOB(fd, 8) = 1; // success + memcpy(WFIFOP(fd, 9), hd, sizeof(struct s_homunculus)); + } else { + WFIFOB(fd, 8) = 0; // not found. + memset(WFIFOP(fd, 9), 0, sizeof(struct s_homunculus)); + } + WFIFOSET(fd, sizeof(struct s_homunculus) + 9); +} + +void mapif_homunculus_saved(int fd, int account_id, bool flag) +{ + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x3892; + WFIFOL(fd, 2) = account_id; + WFIFOB(fd, 6) = flag; // 1:success, 0:failure + WFIFOSET(fd, 7); +} + +void mapif_homunculus_renamed(int fd, int account_id, int char_id, unsigned char flag, const char *name) +{ + nullpo_retv(name); + WFIFOHEAD(fd, NAME_LENGTH + 12); + WFIFOW(fd, 0) = 0x3894; + WFIFOL(fd, 2) = account_id; + WFIFOL(fd, 6) = char_id; + WFIFOB(fd, 10) = flag; + safestrncpy(WFIFOP(fd, 11), name, NAME_LENGTH); + WFIFOSET(fd, NAME_LENGTH + 12); +} + +void mapif_parse_homunculus_create(int fd, int len, int account_id, const struct s_homunculus *phd) +{ + struct s_homunculus shd; + bool result; + + memcpy(&shd, phd, sizeof(shd)); + + result = inter_homunculus->create(&shd); + mapif->homunculus_created(fd, account_id, &shd, result); +} + +void mapif_parse_homunculus_delete(int fd, int homun_id) +{ + bool result = inter_homunculus->delete(homun_id); + mapif->homunculus_deleted(fd, result); +} + +void mapif_parse_homunculus_load(int fd, int account_id, int homun_id) +{ + struct s_homunculus hd; + bool result = inter_homunculus->load(homun_id, &hd); + mapif->homunculus_loaded(fd, account_id, (result ? &hd : NULL)); +} + +void mapif_parse_homunculus_save(int fd, int len, int account_id, const struct s_homunculus *phd) +{ + bool result = inter_homunculus->save(phd); + mapif->homunculus_saved(fd, account_id, result); +} + +void mapif_parse_homunculus_rename(int fd, int account_id, int char_id, const char *name) +{ + bool result = inter_homunculus->rename(name); + mapif->homunculus_renamed(fd, account_id, char_id, result, name); +} + +void mapif_mail_sendinbox(int fd, int char_id, unsigned char flag, struct mail_data *md) +{ + nullpo_retv(md); + //FIXME: dumping the whole structure like this is unsafe [ultramage] + WFIFOHEAD(fd, sizeof(struct mail_data) + 9); + WFIFOW(fd, 0) = 0x3848; + WFIFOW(fd, 2) = sizeof(struct mail_data) + 9; + WFIFOL(fd, 4) = char_id; + WFIFOB(fd, 8) = flag; + memcpy(WFIFOP(fd, 9),md,sizeof(struct mail_data)); + WFIFOSET(fd,WFIFOW(fd, 2)); +} + +/*========================================== + * 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); +} + +/*========================================== + * Mark mail as 'Read' + *------------------------------------------*/ +void mapif_parse_mail_read(int fd) +{ + int mail_id = RFIFOL(fd, 2); + inter_mail->mark_read(mail_id); +} + +void mapif_mail_sendattach(int fd, int char_id, struct mail_message *msg) +{ + nullpo_retv(msg); + WFIFOHEAD(fd, sizeof(struct item) + 12); + WFIFOW(fd, 0) = 0x384a; + WFIFOW(fd, 2) = sizeof(struct item) + 12; + WFIFOL(fd, 4) = char_id; + WFIFOL(fd, 8) = (msg->zeny > 0) ? msg->zeny : 0; + memcpy(WFIFOP(fd, 12), &msg->item, sizeof(struct item)); + WFIFOSET(fd,WFIFOW(fd, 2)); +} + +void mapif_parse_mail_getattach(int fd) +{ + struct mail_message msg = { 0 }; + int char_id = RFIFOL(fd, 2); + int mail_id = RFIFOL(fd, 6); + + if (!inter_mail->get_attachment(char_id, mail_id, &msg)) + return; + + mapif->mail_sendattach(fd, char_id, &msg); +} + +/*========================================== + * Delete Mail + *------------------------------------------*/ +void mapif_mail_delete(int fd, int char_id, int mail_id, bool failed) +{ + WFIFOHEAD(fd, 11); + WFIFOW(fd, 0) = 0x384b; + WFIFOL(fd, 2) = char_id; + WFIFOL(fd, 6) = mail_id; + WFIFOB(fd, 10) = failed; + WFIFOSET(fd, 11); +} + +void mapif_parse_mail_delete(int fd) +{ + int char_id = RFIFOL(fd, 2); + int mail_id = RFIFOL(fd, 6); + bool failed = !inter_mail->delete(char_id, mail_id); + mapif->mail_delete(fd, char_id, mail_id, failed); +} + +/*========================================== + * Report New Mail to Map Server + *------------------------------------------*/ +void mapif_mail_new(struct mail_message *msg) +{ + unsigned char buf[74]; + + if (msg == NULL || msg->id == 0) + 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); + mapif->sendall(buf, 74); +} + +/*========================================== + * Return Mail + *------------------------------------------*/ +void mapif_mail_return(int fd, int char_id, int mail_id, int new_mail) +{ + WFIFOHEAD(fd, 11); + WFIFOW(fd, 0) = 0x384c; + WFIFOL(fd, 2) = char_id; + WFIFOL(fd, 6) = mail_id; + WFIFOB(fd, 10) = (new_mail == 0); + WFIFOSET(fd, 11); +} + +void mapif_parse_mail_return(int fd) +{ + int char_id = RFIFOL(fd, 2); + int mail_id = RFIFOL(fd, 6); + int new_mail = 0; + + if (!inter_mail->return_message(char_id, mail_id, &new_mail)) + return; + + mapif->mail_return(fd, char_id, mail_id, new_mail); +} + +/*========================================== + * Send Mail + *------------------------------------------*/ +void mapif_mail_send(int fd, struct mail_message* msg) +{ + int len = sizeof(struct mail_message) + 4; + + nullpo_retv(msg); + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = 0x384d; + WFIFOW(fd, 2) = len; + memcpy(WFIFOP(fd, 4), msg, sizeof(struct mail_message)); + WFIFOSET(fd,len); +} + +void mapif_parse_mail_send(int fd) +{ + struct mail_message msg; + int account_id = 0; + + if (RFIFOW(fd, 2) != 8 + sizeof(struct mail_message)) + return; + + account_id = RFIFOL(fd, 4); + memcpy(&msg, RFIFOP(fd, 8), sizeof(struct mail_message)); + + inter_mail->send(account_id, &msg); + + mapif->mail_send(fd, &msg); // notify sender + mapif->mail_new(&msg); // notify recipient +} + +void mapif_mercenary_send(int fd, struct s_mercenary *merc, unsigned char flag) +{ + int size = sizeof(struct s_mercenary) + 5; + + nullpo_retv(merc); + WFIFOHEAD(fd, size); + WFIFOW(fd, 0) = 0x3870; + WFIFOW(fd, 2) = size; + WFIFOB(fd, 4) = flag; + memcpy(WFIFOP(fd, 5), merc, sizeof(struct s_mercenary)); + WFIFOSET(fd,size); +} + +void mapif_parse_mercenary_create(int fd, const struct s_mercenary *merc) +{ + struct s_mercenary merc_; + bool result; + + memcpy(&merc_, merc, sizeof(merc_)); + + result = inter_mercenary->create(&merc_); + mapif->mercenary_send(fd, &merc_, result); +} + +void mapif_parse_mercenary_load(int fd, int merc_id, int char_id) +{ + struct s_mercenary merc; + bool result = inter_mercenary->load(merc_id, char_id, &merc); + mapif->mercenary_send(fd, &merc, result); +} + +void mapif_mercenary_deleted(int fd, unsigned char flag) +{ + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x3871; + WFIFOB(fd, 2) = flag; + WFIFOSET(fd, 3); +} + +void mapif_parse_mercenary_delete(int fd, int merc_id) +{ + bool result = inter_mercenary->delete(merc_id); + mapif->mercenary_deleted(fd, result); +} + +void mapif_mercenary_saved(int fd, unsigned char flag) +{ + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x3872; + WFIFOB(fd, 2) = flag; + WFIFOSET(fd, 3); +} + +void mapif_parse_mercenary_save(int fd, const struct s_mercenary *merc) +{ + bool result = inter_mercenary->save(merc); + mapif->mercenary_saved(fd, result); +} + +// Create a party whether or not +int mapif_party_created(int fd, int account_id, int char_id, struct party *p) +{ + WFIFOHEAD(fd, 39); + WFIFOW(fd, 0) = 0x3820; + WFIFOL(fd, 2) = account_id; + WFIFOL(fd, 6) = char_id; + if (p != NULL) { + WFIFOB(fd, 10) = 0; + WFIFOL(fd, 11) = p->party_id; + memcpy(WFIFOP(fd, 15), p->name, NAME_LENGTH); + ShowInfo("int_party: Party created (%d - %s)\n", p->party_id, p->name); + } else { + WFIFOB(fd, 10) = 1; + WFIFOL(fd, 11) = 0; + memset(WFIFOP(fd, 15), 0, NAME_LENGTH); + } + WFIFOSET(fd, 39); + + return 0; +} + +//Party information not found +void mapif_party_noinfo(int fd, int party_id, int char_id) +{ + WFIFOHEAD(fd, 12); + WFIFOW(fd, 0) = 0x3821; + WFIFOW(fd, 2) = 12; + WFIFOL(fd, 4) = char_id; + WFIFOL(fd, 8) = party_id; + WFIFOSET(fd, 12); + ShowWarning("int_party: info not found (party_id=%d char_id=%d)\n", party_id, char_id); +} + +//Digest party information +void mapif_party_info(int fd, struct party* p, int char_id) +{ + unsigned char buf[8 + sizeof(struct party)]; + nullpo_retv(p); + 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) + mapif->sendall(buf, WBUFW(buf, 2)); + else + mapif->send(fd, buf, WBUFW(buf, 2)); +} + +//Whether or not additional party members +int mapif_party_memberadded(int fd, int party_id, int account_id, int char_id, int flag) +{ + WFIFOHEAD(fd, 15); + WFIFOW(fd, 0) = 0x3822; + WFIFOL(fd, 2) = party_id; + WFIFOL(fd, 6) = account_id; + WFIFOL(fd, 10) = char_id; + WFIFOB(fd, 14) = flag; + WFIFOSET(fd, 15); + + return 0; +} + +// Party setting change notification +int mapif_party_optionchanged(int fd, struct party *p, int account_id, int flag) +{ + unsigned char buf[16]; + nullpo_ret(p); + 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) + mapif->sendall(buf, 15); + else + mapif->send(fd, buf, 15); + return 0; +} + +//Withdrawal notification party +int mapif_party_withdraw(int party_id, int account_id, int 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; + mapif->sendall(buf, 14); + return 0; +} + +//Party map update notification +int mapif_party_membermoved(struct party *p, int idx) +{ + unsigned char buf[20]; + + nullpo_ret(p); + Assert_ret(idx >= 0 && idx < MAX_PARTY); + 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; + mapif->sendall(buf, 19); + return 0; +} + +//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; + mapif->sendall(buf, 7); + //printf("int_party: broken %d\n",party_id); + return 0; +} + +//Remarks in the party +int mapif_party_message(int party_id, int account_id, const char *mes, int len, int sfd) +{ + unsigned char buf[512]; + nullpo_ret(mes); + WBUFW(buf, 0) = 0x3827; + WBUFW(buf, 2) = len + 12; + WBUFL(buf, 4) = party_id; + WBUFL(buf, 8) = account_id; + memcpy(WBUFP(buf, 12), mes, len); + mapif->sendallwos(sfd, buf, len + 12); + return 0; +} + +// Create Party +int mapif_parse_CreateParty(int fd, const char *name, int item, int item2, const struct party_member *leader) +{ + struct party_data *p; + + nullpo_ret(name); + nullpo_ret(leader); + + p = inter_party->create(name, item, item2, leader); + + if (p == NULL) { + mapif->party_created(fd, leader->account_id, leader->char_id, NULL); + return 0; + } + + mapif->party_info(fd, &p->party, 0); + mapif->party_created(fd, leader->account_id, leader->char_id, &p->party); + + return 0; +} + +// Party information request +void mapif_parse_PartyInfo(int fd, int party_id, int char_id) +{ + struct party_data *p; + p = inter_party->fromsql(party_id); + + if (p != NULL) + mapif->party_info(fd, &p->party, char_id); + else + mapif->party_noinfo(fd, party_id, char_id); +} + +// Add a player to party request +int mapif_parse_PartyAddMember(int fd, int party_id, const struct party_member *member) +{ + nullpo_ret(member); + + if (!inter_party->add_member(party_id, member)) { + mapif->party_memberadded(fd, party_id, member->account_id, member->char_id, 1); + return 0; + } + mapif->party_memberadded(fd, party_id, member->account_id, member->char_id, 0); + + return 0; +} + +//Party setting change request +int mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, int exp, int item) +{ + inter_party->change_option(party_id, account_id, exp, item, fd); + return 0; +} + +//Request leave party +int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) +{ + inter_party->leave(party_id, account_id, char_id); + return 0; +} + +// When member goes to other map or levels up. +int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv) +{ + inter_party->change_map(party_id, account_id, char_id, map, online, lv); + return 0; +} + +//Request party dissolution +int mapif_parse_BreakParty(int fd, int party_id) +{ + inter_party->disband(party_id); + return 0; +} + +//Party sending the message +int mapif_parse_PartyMessage(int fd, int party_id, int account_id, const char *mes, int len) +{ + return mapif->party_message(party_id, account_id, mes, len, fd); +} + +int mapif_parse_PartyLeaderChange(int fd, int party_id, int account_id, int char_id) +{ + if (!inter_party->change_leader(party_id, account_id, char_id)) + return 0; + return 1; +} + +int mapif_pet_created(int fd, int account_id, struct s_pet *p) +{ + WFIFOHEAD(fd, 12); + WFIFOW(fd, 0) = 0x3880; + WFIFOL(fd, 2) = account_id; + if (p != NULL){ + WFIFOW(fd, 6) = p->class_; + WFIFOL(fd, 8) = p->pet_id; + ShowInfo("int_pet: created pet %d - %s\n", p->pet_id, p->name); + } else { + WFIFOB(fd, 6) = 0; + WFIFOL(fd, 8) = 0; + } + WFIFOSET(fd, 12); + + return 0; +} + +int mapif_pet_info(int fd, int account_id, struct s_pet *p) +{ + nullpo_ret(p); + WFIFOHEAD(fd, sizeof(struct s_pet) + 9); + WFIFOW(fd, 0) = 0x3881; + WFIFOW(fd, 2) = sizeof(struct s_pet) + 9; + WFIFOL(fd, 4) = account_id; + WFIFOB(fd, 8) = 0; + memcpy(WFIFOP(fd, 9), p, sizeof(struct s_pet)); + WFIFOSET(fd, WFIFOW(fd, 2)); + + return 0; +} + +int mapif_pet_noinfo(int fd, int account_id) +{ + WFIFOHEAD(fd, sizeof(struct s_pet) + 9); + WFIFOW(fd, 0) = 0x3881; + WFIFOW(fd, 2) = sizeof(struct s_pet) + 9; + WFIFOL(fd, 4) = account_id; + WFIFOB(fd, 8) = 1; + memset(WFIFOP(fd, 9), 0, sizeof(struct s_pet)); + WFIFOSET(fd, WFIFOW(fd, 2)); + + return 0; +} + +int mapif_save_pet_ack(int fd, int account_id, int flag) +{ + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x3882; + WFIFOL(fd, 2) = account_id; + WFIFOB(fd, 6) = flag; + WFIFOSET(fd, 7); + + return 0; +} + +int mapif_delete_pet_ack(int fd, int flag) +{ + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x3883; + WFIFOB(fd, 2) = flag; + WFIFOSET(fd, 3); + + return 0; +} + +int mapif_save_pet(int fd, int account_id, const struct s_pet *data) +{ + //here process pet save request. + int len; + nullpo_ret(data); + RFIFOHEAD(fd); + len = RFIFOW(fd, 2); + if (sizeof(struct s_pet) != len-8) { + ShowError("inter pet: data size mismatch: %d != %"PRIuS"\n", len-8, sizeof(struct s_pet)); + return 0; + } + + inter_pet->tosql(data); + mapif->save_pet_ack(fd, account_id, 0); + + return 0; +} + +int mapif_delete_pet(int fd, int pet_id) +{ + mapif->delete_pet_ack(fd, inter_pet->delete_(pet_id)); + + return 0; +} + +int mapif_parse_CreatePet(int fd) +{ + int account_id; + struct s_pet *pet; + + RFIFOHEAD(fd); + account_id = RFIFOL(fd, 2); + pet = inter_pet->create(account_id, RFIFOL(fd, 6), RFIFOW(fd, 10), RFIFOW(fd, 12), RFIFOW(fd, 14), + RFIFOW(fd, 16), RFIFOW(fd, 18), RFIFOW(fd, 20), RFIFOB(fd, 22), RFIFOB(fd, 23), RFIFOP(fd, 24)); + + if (pet != NULL) + mapif->pet_created(fd, account_id, pet); + else + mapif->pet_created(fd, account_id, NULL); + + return 0; +} + +int mapif_parse_LoadPet(int fd) +{ + int account_id; + struct s_pet *pet; + + RFIFOHEAD(fd); + account_id = RFIFOL(fd, 2); + pet = inter_pet->load(account_id, RFIFOL(fd, 6), RFIFOL(fd, 10)); + + if (pet != NULL) + mapif->pet_info(fd, account_id, pet); + else + mapif->pet_noinfo(fd, account_id); + return 0; +} + +int mapif_parse_SavePet(int fd) +{ + RFIFOHEAD(fd); + mapif->save_pet(fd, RFIFOL(fd, 4), RFIFOP(fd, 8)); + return 0; +} + +int mapif_parse_DeletePet(int fd) +{ + RFIFOHEAD(fd); + mapif->delete_pet(fd, RFIFOL(fd, 2)); + return 0; +} + +void mapif_quest_save_ack(int fd, int char_id, bool success) +{ + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x3861; + WFIFOL(fd, 2) = char_id; + WFIFOB(fd, 6) = success ? 1 : 0; + WFIFOSET(fd, 7); +} + +/** + * Handles the save request from mapserver for a character's questlog. + * + * Received quests are saved, and an ack is sent back to the map server. + * + * @see inter_parse_frommap + */ +int mapif_parse_quest_save(int fd) +{ + int num = (RFIFOW(fd, 2) - 8) / sizeof(struct quest); + int char_id = RFIFOL(fd, 4); + const struct quest *qd = NULL; + bool success; + + if (num > 0) + qd = RFIFOP(fd,8); + + success = inter_quest->save(char_id, qd, num); + + // Send ack + mapif->quest_save_ack(fd, char_id, success); + + return 0; +} + +void mapif_send_quests(int fd, int char_id, struct quest *tmp_questlog, int num_quests) +{ + WFIFOHEAD(fd,num_quests*sizeof(struct quest) + 8); + WFIFOW(fd, 0) = 0x3860; + WFIFOW(fd, 2) = num_quests*sizeof(struct quest) + 8; + WFIFOL(fd, 4) = char_id; + + if (num_quests > 0) { + nullpo_retv(tmp_questlog); + memcpy(WFIFOP(fd, 8), tmp_questlog, sizeof(struct quest) * num_quests); + } + + WFIFOSET(fd, num_quests * sizeof(struct quest) + 8); +} + +/** + * Sends questlog to the map server + * + * Note: Completed quests (state == Q_COMPLETE) are guaranteed to be sent last + * and the map server relies on this behavior (once the first Q_COMPLETE quest, + * all of them are considered to be Q_COMPLETE) + * + * @see inter_parse_frommap + */ +int mapif_parse_quest_load(int fd) +{ + int char_id = RFIFOL(fd,2); + struct quest *tmp_questlog = NULL; + int num_quests; + + tmp_questlog = inter_quest->fromsql(char_id, &num_quests); + mapif->send_quests(fd, char_id, tmp_questlog, num_quests); + + if (tmp_questlog != NULL) + aFree(tmp_questlog); + + return 0; +} + /* RoDEX */ -int mapif_parse_rodex_requestinbox(int fd); -void mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails); -int mapif_parse_rodex_checkhasnew(int fd); -void mapif_rodex_sendhasnew(int fd, int char_id, bool has_new); -int mapif_parse_rodex_updatemail(int fd); -int mapif_parse_rodex_send(int fd); -void mapif_rodex_send(int fd, int sender_id, int receiver_id, int receiver_accountid, bool result); -int mapif_parse_rodex_checkname(int fd); -void mapif_rodex_checkname(int fd, int reqchar_id, int target_char_id, short target_class, int target_level, char *name); -int mapif_load_guild_storage(int fd,int account_id,int guild_id, char flag); -int mapif_save_guild_storage_ack(int fd, int account_id, int guild_id, int fail); -int mapif_parse_LoadGuildStorage(int fd); -int mapif_parse_SaveGuildStorage(int fd); -int mapif_account_storage_load(int fd, int account_id); -int mapif_parse_AccountStorageLoad(int fd); -int mapif_parse_AccountStorageSave(int fd); -void mapif_send_AccountStorageSaveAck(int fd, int account_id, bool save); -int mapif_itembound_ack(int fd, int aid, int guild_id); -int mapif_parse_ItemBoundRetrieve_sub(int fd); -void mapif_parse_ItemBoundRetrieve(int fd); -void mapif_parse_accinfo(int fd); -void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, - const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state); -int mapif_broadcast(const unsigned char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd); -int mapif_wis_message(struct WisData *wd); -void mapif_wis_response(int fd, const unsigned char *src, int flag); -int mapif_wis_end(struct WisData *wd, int flag); -int mapif_account_reg_reply(int fd,int account_id,int char_id, int type); -int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason); -int mapif_parse_broadcast(int fd); -int mapif_parse_WisRequest(int fd); -int mapif_parse_WisReply(int fd); -int mapif_parse_WisToGM(int fd); -int mapif_parse_Registry(int fd); -int mapif_parse_RegistryRequest(int fd); -void mapif_namechange_ack(int fd, int account_id, int char_id, int type, int flag, const char *const name); -int mapif_parse_NameChangeRequest(int fd); + +/*========================================== + * Inbox Request + *------------------------------------------*/ +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); +} + +void mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails) +{ + int per_packet = (UINT16_MAX - 24) / sizeof(struct rodex_message); + int sent = 0; + bool is_first = true; + nullpo_retv(mails); + Assert_retv(char_id > 0); + Assert_retv(count >= 0); + Assert_retv(mail_id >= 0); + + do { + int i = 24, j, size, limit; + int to_send = count - sent; + bool is_last = true; + + if (to_send <= per_packet) { + size = to_send * sizeof(struct rodex_message) + 24; + limit = to_send; + is_last = true; + } else { + limit = min(to_send, per_packet); + if (limit != to_send) { + is_last = false; + } + size = limit * sizeof(struct rodex_message) + 24; + } + + WFIFOHEAD(fd, size); + WFIFOW(fd, 0) = 0x3895; + WFIFOW(fd, 2) = size; + WFIFOL(fd, 4) = char_id; + WFIFOB(fd, 8) = opentype; + WFIFOB(fd, 9) = flag; + WFIFOB(fd, 10) = is_last; + WFIFOB(fd, 11) = is_first; + WFIFOL(fd, 12) = limit; + WFIFOQ(fd, 16) = mail_id; + for (j = 0; j < limit; ++j, ++sent, i += sizeof(struct rodex_message)) { + memcpy(WFIFOP(fd, i), &VECTOR_INDEX(*mails, sent), sizeof(struct rodex_message)); + } + WFIFOSET(fd, size); + + is_first = false; + } while (sent < count); +} + +/*========================================== + * Checks if there are new mails + *------------------------------------------*/ +void mapif_parse_rodex_checkhasnew(int fd) +{ + int char_id = RFIFOL(fd, 2); + int account_id = RFIFOL(fd, 6); + bool has_new; + + Assert_retv(account_id >= START_ACCOUNT_NUM && account_id <= END_ACCOUNT_NUM); + Assert_retv(char_id >= START_CHAR_NUM); + + has_new = inter_rodex->hasnew(char_id, account_id); + mapif->rodex_sendhasnew(fd, char_id, has_new); +} + +void mapif_rodex_sendhasnew(int fd, int char_id, bool has_new) +{ + Assert_retv(char_id > 0); + + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x3896; + WFIFOL(fd, 2) = char_id; + WFIFOB(fd, 6) = has_new; + WFIFOSET(fd, 7); +} + +/*========================================== + * Update/Delete mail + *------------------------------------------*/ +void mapif_parse_rodex_updatemail(int fd) +{ + int64 mail_id = RFIFOL(fd, 2); + int8 flag = RFIFOB(fd, 10); + + inter_rodex->updatemail(mail_id, flag); +} + +/*========================================== + * Send Mail + *------------------------------------------*/ +void mapif_parse_rodex_send(int fd) +{ + struct rodex_message msg = { 0 }; + + if (RFIFOW(fd,2) != 4 + sizeof(struct rodex_message)) + return; + + memcpy(&msg, RFIFOP(fd,4), sizeof(struct rodex_message)); + if (msg.receiver_id > 0 || msg.receiver_accountid > 0) + msg.id = inter_rodex->savemessage(&msg); + + mapif->rodex_send(fd, msg.sender_id, msg.receiver_id, msg.receiver_accountid, msg.id > 0 ? true : false); +} + +void mapif_rodex_send(int fd, int sender_id, int receiver_id, int receiver_accountid, bool result) +{ + Assert_retv(sender_id >= 0); + Assert_retv(receiver_id + receiver_accountid > 0); + + WFIFOHEAD(fd,15); + WFIFOW(fd,0) = 0x3897; + WFIFOL(fd,2) = sender_id; + WFIFOL(fd,6) = receiver_id; + WFIFOL(fd,10) = receiver_accountid; + WFIFOB(fd,14) = result; + WFIFOSET(fd,15); +} + +/*------------------------------------------ + * Check Player + *------------------------------------------*/ +void mapif_parse_rodex_checkname(int fd) +{ + int reqchar_id = RFIFOL(fd, 2); + char name[NAME_LENGTH]; + int target_char_id, target_level; + short target_class; + + safestrncpy(name, RFIFOP(fd, 6), NAME_LENGTH); + + if (inter_rodex->checkname(name, &target_char_id, &target_class, &target_level) == true) + mapif->rodex_checkname(fd, reqchar_id, target_char_id, target_class, target_level, name); + else + mapif->rodex_checkname(fd, reqchar_id, 0, 0, 0, name); +} + +void mapif_rodex_checkname(int fd, int reqchar_id, int target_char_id, short target_class, int target_level, char *name) +{ + nullpo_retv(name); + Assert_retv(reqchar_id > 0); + Assert_retv(target_char_id >= 0); + + WFIFOHEAD(fd, 16 + NAME_LENGTH); + WFIFOW(fd, 0) = 0x3898; + WFIFOL(fd, 2) = reqchar_id; + WFIFOL(fd, 6) = target_char_id; + WFIFOW(fd, 10) = target_class; + WFIFOL(fd, 12) = target_level; + safestrncpy(WFIFOP(fd, 16), name, NAME_LENGTH); + WFIFOSET(fd, 16 + NAME_LENGTH); +} + +int mapif_load_guild_storage(int fd, int account_id, int guild_id, char flag) +{ + if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id)) { + Sql_ShowDebug(inter->sql_handle); + } else if (SQL->NumRows(inter->sql_handle) > 0) { + // guild exists + WFIFOHEAD(fd, sizeof(struct guild_storage) + 13); + WFIFOW(fd, 0) = 0x3818; + WFIFOW(fd, 2) = sizeof(struct guild_storage)+13; + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = guild_id; + WFIFOB(fd, 12) = flag; //1 open storage, 0 don't open + inter_storage->guild_storage_fromsql(guild_id, WFIFOP(fd, 13)); + WFIFOSET(fd, WFIFOW(fd, 2)); + return 0; + } + // guild does not exist + SQL->FreeResult(inter->sql_handle); + WFIFOHEAD(fd, 12); + WFIFOW(fd, 0) = 0x3818; + WFIFOW(fd, 2) = 12; + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = 0; + WFIFOSET(fd, 12); + return 0; +} + +int mapif_save_guild_storage_ack(int fd, int account_id, int guild_id, int fail) +{ + WFIFOHEAD(fd, 11); + WFIFOW(fd, 0) = 0x3819; + WFIFOL(fd, 2) = account_id; + WFIFOL(fd, 6) = guild_id; + WFIFOB(fd, 10) = fail; + WFIFOSET(fd, 11); + return 0; +} + +/** + * Loads the account storage and send to the map server. + * @packet 0x3805 [out] <account_id>.L <struct item[]>.P + * @param fd [in] file/socket descriptor. + * @param account_id [in] account id of the session. + * @return 1 on success, 0 on failure. + */ +int mapif_account_storage_load(int fd, int account_id) +{ + struct storage_data stor = { 0 }; + int count = 0, i = 0, len = 0; + + Assert_ret(account_id > 0); + + VECTOR_INIT(stor.item); + count = inter_storage->fromsql(account_id, &stor); + + len = 8 + count * sizeof(struct item); + + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = 0x3805; + WFIFOW(fd, 2) = (uint16) len; + WFIFOL(fd, 4) = account_id; + for (i = 0; i < count; i++) + memcpy(WFIFOP(fd, 8 + i * sizeof(struct item)), &VECTOR_INDEX(stor.item, i), sizeof(struct item)); + WFIFOSET(fd, len); + + VECTOR_CLEAR(stor.item); + + return 1; +} + +/** + * Parses account storage load request from map server. + * @packet 0x3010 [in] <account_id>.L + * @param fd [in] file/socket descriptor + * @return 1 on success, 0 on failure. + */ +int mapif_parse_AccountStorageLoad(int fd) +{ + int account_id = RFIFOL(fd, 2); + + Assert_ret(fd > 0); + Assert_ret(account_id > 0); + + mapif->account_storage_load(fd, account_id); + + return 1; +} + +/** + * Parses an account storage save request from the map server. + * @packet 0x3011 [in] <packet_len>.W <account_id>.L <struct item[]>.P + * @param fd [in] file/socket descriptor. + * @return 1 on success, 0 on failure. + */ +int mapif_parse_AccountStorageSave(int fd) +{ + int payload_size = RFIFOW(fd, 2) - 8, account_id = RFIFOL(fd, 4); + int i = 0, count = 0; + struct storage_data p_stor = { 0 }; + + Assert_ret(fd > 0); + Assert_ret(account_id > 0); + + count = payload_size/sizeof(struct item); + + VECTOR_INIT(p_stor.item); + + if (count > 0) { + VECTOR_ENSURE(p_stor.item, count, 1); + + for (i = 0; i < count; i++) { + const struct item *it = RFIFOP(fd, 8 + i * sizeof(struct item)); + + VECTOR_PUSH(p_stor.item, *it); + } + + p_stor.aggregate = count; + } + + inter_storage->tosql(account_id, &p_stor); + + VECTOR_CLEAR(p_stor.item); + + mapif->sAccountStorageSaveAck(fd, account_id, true); + + return 1; +} + +/** + * Sends an acknowledgement for the save + * status of the account storage. + * @packet 0x3808 [out] <account_id>.L <save_flag>.B + * @param fd [in] File/Socket Descriptor. + * @param account_id [in] Account ID of the storage in question. + * @param flag [in] Save flag, true for success and false for failure. + */ +void mapif_send_AccountStorageSaveAck(int fd, int account_id, bool flag) +{ + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x3808; + WFIFOL(fd, 2) = account_id; + WFIFOB(fd, 6) = flag ? 1 : 0; + WFIFOSET(fd, 7); +} + +int mapif_parse_LoadGuildStorage(int fd) +{ + RFIFOHEAD(fd); + + mapif->load_guild_storage(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), 1); + + return 0; +} + +int mapif_parse_SaveGuildStorage(int fd) +{ + int guild_id; + int len; + + RFIFOHEAD(fd); + guild_id = RFIFOL(fd, 8); + len = RFIFOW(fd, 2); + + if (sizeof(struct guild_storage) != len - 12) { + ShowError("inter storage: data size mismatch: %d != %"PRIuS"\n", len - 12, sizeof(struct guild_storage)); + } else if (inter_storage->guild_storage_tosql(guild_id, RFIFOP(fd, 12))) { + mapif->save_guild_storage_ack(fd, RFIFOL(fd, 4), guild_id, 0); + return 0; + } + mapif->save_guild_storage_ack(fd, RFIFOL(fd, 4), guild_id, 1); + + return 0; +} + +int mapif_itembound_ack(int fd, int aid, int guild_id) +{ +#ifdef GP_BOUND_ITEMS + WFIFOHEAD(fd, 8); + WFIFOW(fd, 0) = 0x3856; + WFIFOL(fd, 2) = aid;/* the value is not being used, drop? */ + WFIFOW(fd, 6) = guild_id; + WFIFOSET(fd, 8); +#endif + return 0; +} + +void mapif_parse_ItemBoundRetrieve(int fd) +{ +#ifdef GP_BOUND_ITEMS + int char_id = RFIFOL(fd, 2); + int account_id = RFIFOL(fd, 6); + int guild_id = RFIFOW(fd, 10); + + inter_storage->retrieve_bound_items(char_id, account_id, guild_id); + + //Finally reload storage and tell map we're done + mapif->load_guild_storage(fd, account_id, guild_id, 0); + + // If character is logged in char, disconnect + chr->disconnect_player(account_id); +#endif // GP_BOUND_ITEMS + + /* tell map server the operation is over and it can unlock the storage */ + mapif->itembound_ack(fd, RFIFOL(fd, 6), RFIFOW(fd, 10)); +} + +void mapif_parse_accinfo(int fd) +{ + char query[NAME_LENGTH]; + int u_fd = RFIFOL(fd, 2), aid = RFIFOL(fd, 6), castergroup = RFIFOL(fd, 10); + + safestrncpy(query, RFIFOP(fd, 14), NAME_LENGTH); + + inter->accinfo(u_fd, aid, castergroup, query, fd); +} + +// broadcast sending +int mapif_broadcast(const unsigned char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd) +{ + unsigned char *buf = (unsigned char*)aMalloc((len)*sizeof(unsigned char)); + + nullpo_ret(mes); + Assert_ret(len >= 16); + WBUFW(buf, 0) = 0x3800; + WBUFW(buf, 2) = len; + WBUFL(buf, 4) = fontColor; + WBUFW(buf, 8) = fontType; + WBUFW(buf, 10) = fontSize; + WBUFW(buf, 12) = fontAlign; + WBUFW(buf, 14) = fontY; + memcpy(WBUFP(buf, 16), mes, len - 16); + mapif->sendallwos(sfd, buf, len); + + aFree(buf); + return 0; +} + +// Wis sending +int mapif_wis_message(struct WisData *wd) +{ + unsigned char buf[2048]; + nullpo_ret(wd); + //if (wd->len > 2047-56) wd->len = 2047-56; //Force it to fit to avoid crashes. [Skotlex] + if (wd->len < 0) + wd->len = 0; + if (wd->len >= (int)sizeof(wd->msg) - 1) + wd->len = (int)sizeof(wd->msg) - 1; + + 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 = mapif->sendall(buf, WBUFW(buf, 2)); + + return 0; +} + +void mapif_wis_response(int fd, const unsigned char *src, int flag) +{ + unsigned char buf[27]; + nullpo_retv(src); + WBUFW(buf, 0) = 0x3802; + memcpy(WBUFP(buf, 2), src, 24); + WBUFB(buf, 26) = flag; + mapif->send(fd, buf, 27); +} + +// Wis sending result +int mapif_wis_end(struct WisData *wd, int flag) +{ + nullpo_ret(wd); + mapif->wis_response(wd->fd, wd->src, flag); + return 0; +} + +#if 0 +// Account registry transfer to map-server +static void mapif_account_reg(int fd, unsigned char *src) +{ + nullpo_retv(src); + WBUFW(src, 0) = 0x3804; //NOTE: writing to RFIFO + mapif->sendallwos(fd, src, WBUFW(src, 2)); +} +#endif // 0 + +// Send the requested account_reg +int mapif_account_reg_reply(int fd,int account_id,int char_id, int type) +{ + inter->accreg_fromsql(account_id, char_id, fd, type); + return 0; +} + +//Request to kick char from a certain map server. [Skotlex] +int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason) +{ + if (fd < 0) + return -1; + + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x2b1f; + WFIFOL(fd, 2) = account_id; + WFIFOB(fd, 6) = reason; + WFIFOSET(fd, 7); + return 0; +} + +// broadcast sending +int mapif_parse_broadcast(int fd) +{ + mapif->broadcast(RFIFOP(fd, 16), RFIFOW(fd, 2), RFIFOL(fd, 4), RFIFOW(fd, 8), RFIFOW(fd, 10), RFIFOW(fd, 12), RFIFOW(fd, 14), fd); + return 0; +} + +// Wisp/page request to send +int mapif_parse_WisRequest(int fd) +{ + struct WisData* wd; + char name[NAME_LENGTH]; + char *data; + size_t len; + + if (fd <= 0) // check if we have a valid fd + return 0; + + if (RFIFOW(fd, 2) - 52 >= sizeof(wd->msg)) { + ShowWarning("inter: Wis message size too long.\n"); + return 0; + } else if (RFIFOW(fd, 2) - 52 <= 0) { // normally, impossible, but who knows... + ShowError("inter: Wis message doesn't exist.\n"); + return 0; + } + + safestrncpy(name, RFIFOP(fd, 28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex] + + // search if character exists before to ask all map-servers + if (!chr->name_exists(name, NULL)) { + mapif->wis_response(fd, RFIFOP(fd, 4), 1); + } else { + // Character exists. So, ask all map-servers + + // to be sure of the correct name, rewrite it + SQL->GetData(inter->sql_handle, 0, &data, &len); + memset(name, 0, NAME_LENGTH); + memcpy(name, data, min(len, NAME_LENGTH)); + // if source is destination, don't ask other servers. + if (strncmp(RFIFOP(fd, 4), name, NAME_LENGTH) == 0) { + mapif->wis_response(fd, RFIFOP(fd, 4), 1); + } else { + wd = inter->add_wisdata(fd, RFIFOP(fd, 4), RFIFOP(fd, 28), RFIFOP(fd, 52), RFIFOW(fd, 2) - 52); + mapif->wis_message(wd); + } + } + + SQL->FreeResult(inter->sql_handle); + return 0; +} + +// Wisp/page transmission result +int mapif_parse_WisReply(int fd) +{ + int id, flag; + struct WisData *wd; + + id = RFIFOL(fd,2); + flag = RFIFOB(fd,6); + wd = inter->get_wisdata(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 whisper, 1: target character is not logged in?, 2: ignored by target + inter->remove_wisdata(id); + } + + 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 <min_gm_level>.w <message>.?B + + memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2)); // Message contains the NUL terminator (see intif_wis_message_to_gm()) + WBUFW(buf, 0) = 0x3803; + mapif->sendall(buf, RFIFOW(fd,2)); + + return 0; +} + +// Save account_reg into sql (type=2) +int mapif_parse_Registry(int fd) +{ + int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12); + + if (count != 0) { + int cursor = 14, i; + char key[SCRIPT_VARNAME_LENGTH+1], sval[254]; + bool isLoginActive = sockt->session_is_active(chr->login_fd); + + if (isLoginActive) + chr->global_accreg_to_login_start(account_id, char_id); + + for (i = 0; i < count; i++) { + unsigned int index; + int len = RFIFOB(fd, cursor); + safestrncpy(key, RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); + cursor += len + 1; + + index = RFIFOL(fd, cursor); + cursor += 4; + + switch (RFIFOB(fd, cursor++)) { + /* int */ + case 0: + inter->savereg(account_id, char_id, key, index, RFIFOL(fd, cursor), false); + cursor += 4; + break; + case 1: + inter->savereg(account_id, char_id, key, index, 0, false); + break; + /* str */ + case 2: + len = RFIFOB(fd, cursor); + safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); + cursor += len + 1; + inter->savereg(account_id, char_id, key, index, (intptr_t)sval, true); + break; + case 3: + inter->savereg(account_id, char_id, key, index, 0, true); + break; + default: + ShowError("mapif->parse_Registry: unknown type %d\n", RFIFOB(fd, cursor - 1)); + return 1; + } + } + + if (isLoginActive) + chr->global_accreg_to_login_send(); + } + return 0; +} + +// Request the value of all registries. +int mapif_parse_RegistryRequest(int fd) +{ + //Load Char Registry + if (RFIFOB(fd, 12)) + mapif->account_reg_reply(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), 3); // 3: char reg + //Load Account Registry + if (RFIFOB(fd, 11) != 0) + mapif->account_reg_reply(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), 2); // 2: account reg + //Ask Login Server for Account2 values. + if (RFIFOB(fd, 10) != 0) + chr->request_accreg2(RFIFOL(fd, 2), RFIFOL(fd, 6)); + return 1; +} + +void mapif_namechange_ack(int fd, int account_id, int char_id, int type, int flag, const char *const name) +{ + nullpo_retv(name); + WFIFOHEAD(fd, NAME_LENGTH+13); + WFIFOW(fd, 0) = 0x3806; + WFIFOL(fd, 2) = account_id; + WFIFOL(fd, 6) = char_id; + WFIFOB(fd, 10) = type; + WFIFOB(fd, 11) = flag; + memcpy(WFIFOP(fd, 12), name, NAME_LENGTH); + WFIFOSET(fd, NAME_LENGTH + 13); +} + +int mapif_parse_NameChangeRequest(int fd) +{ + int account_id, char_id, type; + const char *name; + int i; + + account_id = RFIFOL(fd, 2); + char_id = RFIFOL(fd, 6); + type = RFIFOB(fd, 10); + name = RFIFOP(fd, 11); + + // Check Authorized letters/symbols in the name + if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorized + for (i = 0; i < NAME_LENGTH && name[i]; i++) + if (strchr(char_name_letters, name[i]) == NULL) { + mapif->namechange_ack(fd, account_id, char_id, type, 0, name); + return 0; + } + } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden + for (i = 0; i < NAME_LENGTH && name[i]; i++) + if (strchr(char_name_letters, name[i]) != NULL) { + mapif->namechange_ack(fd, account_id, char_id, type, 0, name); + return 0; + } + } + //TODO: type holds the type of object to rename. + //If it were a player, it needs to have the guild information and db information + //updated here, because changing it on the map won't make it be saved [Skotlex] + + //name allowed. + mapif->namechange_ack(fd, account_id, char_id, type, 1, name); + return 0; +} + // Clan System -int mapif_parse_ClanMemberKick(int fd, int clan_id, int kick_interval); -int mapif_parse_ClanMemberCount(int fd, int clan_id, int kick_interval); +int mapif_parse_ClanMemberKick(int fd, int clan_id, int kick_interval) +{ + int count = 0; + + if (inter_clan->kick_inactive_members(clan_id, kick_interval) == 1) + count = inter_clan->count_members(clan_id, kick_interval); + + WFIFOHEAD(fd, 10); + WFIFOW(fd, 0) = 0x3858; + WFIFOL(fd, 2) = clan_id; + WFIFOL(fd, 6) = count; + WFIFOSET(fd, 10); + return 0; +} + +int mapif_parse_ClanMemberCount(int fd, int clan_id, int kick_interval) +{ + WFIFOHEAD(fd, 10); + WFIFOW(fd, 0) = 0x3858; + WFIFOL(fd, 2) = clan_id; + WFIFOL(fd, 6) = inter_clan->count_members(clan_id, kick_interval); + WFIFOSET(fd, 10); + return 0; +} struct mapif_interface mapif_s; struct mapif_interface *mapif; @@ -253,10 +2366,6 @@ void mapif_defaults(void) { mapif->parse_auction_close = mapif_parse_auction_close; mapif->auction_bid = mapif_auction_bid; mapif->parse_auction_bid = mapif_parse_auction_bid; - mapif->elemental_create = mapif_elemental_create; - mapif->elemental_save = mapif_elemental_save; - mapif->elemental_load = mapif_elemental_load; - mapif->elemental_delete = mapif_elemental_delete; mapif->elemental_send = mapif_elemental_send; mapif->parse_elemental_create = mapif_parse_elemental_create; mapif->parse_elemental_load = mapif_parse_elemental_load; @@ -292,7 +2401,6 @@ void mapif_defaults(void) { mapif->parse_GuildMemberInfoChange = mapif_parse_GuildMemberInfoChange; mapif->parse_GuildPosition = mapif_parse_GuildPosition; mapif->parse_GuildSkillUp = mapif_parse_GuildSkillUp; - mapif->parse_GuildDeleteAlliance = mapif_parse_GuildDeleteAlliance; mapif->parse_GuildAlliance = mapif_parse_GuildAlliance; mapif->parse_GuildNotice = mapif_parse_GuildNotice; mapif->parse_GuildEmblem = mapif_parse_GuildEmblem; @@ -304,11 +2412,6 @@ void mapif_defaults(void) { mapif->homunculus_loaded = mapif_homunculus_loaded; mapif->homunculus_saved = mapif_homunculus_saved; mapif->homunculus_renamed = mapif_homunculus_renamed; - mapif->homunculus_create = mapif_homunculus_create; - mapif->homunculus_save = mapif_homunculus_save; - mapif->homunculus_load = mapif_homunculus_load; - mapif->homunculus_delete = mapif_homunculus_delete; - mapif->homunculus_rename = mapif_homunculus_rename; mapif->parse_homunculus_create = mapif_parse_homunculus_create; mapif->parse_homunculus_delete = mapif_parse_homunculus_delete; mapif->parse_homunculus_load = mapif_parse_homunculus_load; @@ -318,7 +2421,6 @@ void mapif_defaults(void) { mapif->parse_mail_requestinbox = mapif_parse_mail_requestinbox; mapif->parse_mail_read = mapif_parse_mail_read; mapif->mail_sendattach = mapif_mail_sendattach; - mapif->mail_getattach = mapif_mail_getattach; mapif->parse_mail_getattach = mapif_parse_mail_getattach; mapif->mail_delete = mapif_mail_delete; mapif->parse_mail_delete = mapif_parse_mail_delete; @@ -327,10 +2429,6 @@ void mapif_defaults(void) { mapif->parse_mail_return = mapif_parse_mail_return; mapif->mail_send = mapif_mail_send; mapif->parse_mail_send = mapif_parse_mail_send; - mapif->mercenary_create = mapif_mercenary_create; - mapif->mercenary_save = mapif_mercenary_save; - mapif->mercenary_load = mapif_mercenary_load; - mapif->mercenary_delete = mapif_mercenary_delete; mapif->mercenary_send = mapif_mercenary_send; mapif->parse_mercenary_create = mapif_parse_mercenary_create; mapif->parse_mercenary_load = mapif_parse_mercenary_load; @@ -361,18 +2459,12 @@ void mapif_defaults(void) { mapif->pet_noinfo = mapif_pet_noinfo; mapif->save_pet_ack = mapif_save_pet_ack; mapif->delete_pet_ack = mapif_delete_pet_ack; - mapif->create_pet = mapif_create_pet; - mapif->load_pet = mapif_load_pet; mapif->save_pet = mapif_save_pet; mapif->delete_pet = mapif_delete_pet; mapif->parse_CreatePet = mapif_parse_CreatePet; mapif->parse_LoadPet = mapif_parse_LoadPet; mapif->parse_SavePet = mapif_parse_SavePet; mapif->parse_DeletePet = mapif_parse_DeletePet; - mapif->quests_fromsql = mapif_quests_fromsql; - mapif->quest_delete = mapif_quest_delete; - mapif->quest_add = mapif_quest_add; - mapif->quest_update = mapif_quest_update; mapif->quest_save_ack = mapif_quest_save_ack; mapif->parse_quest_save = mapif_parse_quest_save; mapif->send_quests = mapif_send_quests; @@ -396,10 +2488,8 @@ void mapif_defaults(void) { mapif->sAccountStorageSaveAck = mapif_send_AccountStorageSaveAck; mapif->account_storage_load = mapif_account_storage_load; mapif->itembound_ack = mapif_itembound_ack; - mapif->parse_ItemBoundRetrieve_sub = mapif_parse_ItemBoundRetrieve_sub; mapif->parse_ItemBoundRetrieve = mapif_parse_ItemBoundRetrieve; mapif->parse_accinfo = mapif_parse_accinfo; - mapif->parse_accinfo2 = mapif_parse_accinfo2; mapif->broadcast = mapif_broadcast; mapif->wis_message = mapif_wis_message; mapif->wis_response = mapif_wis_response; diff --git a/src/char/mapif.h b/src/char/mapif.h index 9cac2be85..d67ce1c79 100644 --- a/src/char/mapif.h +++ b/src/char/mapif.h @@ -51,10 +51,6 @@ struct mapif_interface { void (*parse_auction_close) (int fd); void (*auction_bid) (int fd, int char_id, int bid, unsigned char result); void (*parse_auction_bid) (int fd); - bool (*elemental_create) (struct s_elemental *ele); - bool (*elemental_save) (const struct s_elemental *ele); - bool (*elemental_load) (int ele_id, int char_id, struct s_elemental *ele); - bool (*elemental_delete) (int ele_id); void (*elemental_send) (int fd, struct s_elemental *ele, unsigned char flag); void (*parse_elemental_create) (int fd, const struct s_elemental *ele); void (*parse_elemental_load) (int fd, int ele_id, int char_id); @@ -90,7 +86,6 @@ struct mapif_interface { int (*parse_GuildMemberInfoChange) (int fd, int guild_id, int account_id, int char_id, int type, const char *data, int len); int (*parse_GuildPosition) (int fd, int guild_id, int idx, const struct guild_position *p); int (*parse_GuildSkillUp) (int fd, int guild_id, uint16 skill_id, int account_id, int max); - int (*parse_GuildDeleteAlliance) (struct guild *g, int guild_id, int account_id1, int account_id2, int flag); int (*parse_GuildAlliance) (int fd, int guild_id1, int guild_id2, int account_id1, int account_id2, int flag); int (*parse_GuildNotice) (int fd, int guild_id, const char *mes1, const char *mes2); int (*parse_GuildEmblem) (int fd, int len, int guild_id, int dummy, const char *data); @@ -102,11 +97,6 @@ struct mapif_interface { void (*homunculus_loaded) (int fd, int account_id, struct s_homunculus *hd); void (*homunculus_saved) (int fd, int account_id, bool flag); void (*homunculus_renamed) (int fd, int account_id, int char_id, unsigned char flag, const char *name); - bool (*homunculus_create) (struct s_homunculus *hd); - bool (*homunculus_save) (const struct s_homunculus *hd); - bool (*homunculus_load) (int homun_id, struct s_homunculus* hd); - bool (*homunculus_delete) (int homun_id); - bool (*homunculus_rename) (const char *name); void (*parse_homunculus_create) (int fd, int len, int account_id, const struct s_homunculus *phd); void (*parse_homunculus_delete) (int fd, int homun_id); void (*parse_homunculus_load) (int fd, int account_id, int homun_id); @@ -116,7 +106,6 @@ struct mapif_interface { void (*parse_mail_requestinbox) (int fd); void (*parse_mail_read) (int fd); void (*mail_sendattach) (int fd, int char_id, struct mail_message *msg); - void (*mail_getattach) (int fd, int char_id, int mail_id); void (*parse_mail_getattach) (int fd); void (*mail_delete) (int fd, int char_id, int mail_id, bool failed); void (*parse_mail_delete) (int fd); @@ -125,10 +114,6 @@ struct mapif_interface { void (*parse_mail_return) (int fd); void (*mail_send) (int fd, struct mail_message* msg); void (*parse_mail_send) (int fd); - bool (*mercenary_create) (struct s_mercenary *merc); - bool (*mercenary_save) (const struct s_mercenary *merc); - bool (*mercenary_load) (int merc_id, int char_id, struct s_mercenary *merc); - bool (*mercenary_delete) (int merc_id); void (*mercenary_send) (int fd, struct s_mercenary *merc, unsigned char flag); void (*parse_mercenary_create) (int fd, const struct s_mercenary *merc); void (*parse_mercenary_load) (int fd, int merc_id, int char_id); @@ -159,32 +144,25 @@ struct mapif_interface { int (*pet_noinfo) (int fd, int account_id); int (*save_pet_ack) (int fd, int account_id, int flag); int (*delete_pet_ack) (int fd, int flag); - int (*create_pet) (int fd, int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id, - short pet_equip, short intimate, short hungry, char rename_flag, char incubate, const char *pet_name); - int (*load_pet) (int fd, int account_id, int char_id, int pet_id); int (*save_pet) (int fd, int account_id, const struct s_pet *data); int (*delete_pet) (int fd, int pet_id); int (*parse_CreatePet) (int fd); int (*parse_LoadPet) (int fd); int (*parse_SavePet) (int fd); int (*parse_DeletePet) (int fd); - struct quest *(*quests_fromsql) (int char_id, int *count); - bool (*quest_delete) (int char_id, int quest_id); - bool (*quest_add) (int char_id, struct quest qd); - bool (*quest_update) (int char_id, struct quest qd); void (*quest_save_ack) (int fd, int char_id, bool success); int (*parse_quest_save) (int fd); void (*send_quests) (int fd, int char_id, struct quest *tmp_questlog, int num_quests); int (*parse_quest_load) (int fd); - int(*parse_rodex_requestinbox) (int fd); - void(*rodex_sendinbox) (int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails); - int(*parse_rodex_checkhasnew) (int fd); - void(*rodex_sendhasnew) (int fd, int char_id, bool has_new); - int(*parse_rodex_updatemail) (int fd); - int(*parse_rodex_send) (int fd); - void(*rodex_send) (int fd, int sender_id, int receiver_id, int receiver_accountid, bool result); - int(*parse_rodex_checkname) (int fd); - void(*rodex_checkname) (int fd, int reqchar_id, int target_char_id, short target_class, int target_level, char *name); + void (*parse_rodex_requestinbox) (int fd); + void (*rodex_sendinbox) (int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails); + void (*parse_rodex_checkhasnew) (int fd); + void (*rodex_sendhasnew) (int fd, int char_id, bool has_new); + void (*parse_rodex_updatemail) (int fd); + void (*parse_rodex_send) (int fd); + void (*rodex_send) (int fd, int sender_id, int receiver_id, int receiver_accountid, bool result); + void (*parse_rodex_checkname) (int fd); + void (*rodex_checkname) (int fd, int reqchar_id, int target_char_id, short target_class, int target_level, char *name); int (*load_guild_storage) (int fd, int account_id, int guild_id, char flag); int (*save_guild_storage_ack) (int fd, int account_id, int guild_id, int fail); int (*parse_LoadGuildStorage) (int fd); @@ -194,11 +172,8 @@ struct mapif_interface { int (*pAccountStorageSave) (int fd); void (*sAccountStorageSaveAck) (int fd, int account_id, bool save); int (*itembound_ack) (int fd, int aid, int guild_id); - int (*parse_ItemBoundRetrieve_sub) (int fd); void (*parse_ItemBoundRetrieve) (int fd); void (*parse_accinfo) (int fd); - void (*parse_accinfo2) (bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, - const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state); int (*broadcast) (const unsigned char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd); int (*wis_message) (struct WisData *wd); void (*wis_response) (int fd, const unsigned char *src, int flag); |