summaryrefslogtreecommitdiff
path: root/src/char/mapif.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/char/mapif.c')
-rw-r--r--src/char/mapif.c2508
1 files changed, 2299 insertions, 209 deletions
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;