Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 132 additions & 4 deletions src/char/int_rodex.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,128 @@ static int64 inter_rodex_savemessage(struct rodex_message *msg)
return msg->id;
}

static int64 inter_rodex_getzeny(int64 mail_id)
{
Assert_retr(-1, mail_id > 0);

if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `zeny`, `type` FROM `%s` WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) {
Sql_ShowDebug(inter->sql_handle);
} else {
if (SQL_SUCCESS == SQL->NextRow(inter->sql_handle)) {
char *data;
SQL->GetData(inter->sql_handle, 0, &data, NULL);
int64 zeny = atoi(data);
SQL->GetData(inter->sql_handle, 1, &data, NULL);
uint8 type = atoi(data);
SQL->FreeResult(inter->sql_handle);
if ((type & MAIL_TYPE_ZENY) == 0)
return -1;
return zeny;
}
}
SQL->FreeResult(inter->sql_handle);

return -1;
}

static int inter_rodex_getitems(int64 mail_id, struct rodex_item *items)
{
Assert_retr(-1, mail_id > 0);
nullpo_retr(-1, items);

if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `type` FROM `%s` WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) {
Sql_ShowDebug(inter->sql_handle);
return -1;
} else {
if (SQL_SUCCESS == SQL->NextRow(inter->sql_handle)) {
char *data;
SQL->GetData(inter->sql_handle, 0, &data, NULL);
uint8 type = atoi(data);
SQL->FreeResult(inter->sql_handle);
if ((type & MAIL_TYPE_ITEM) == 0)
return -1;
} else {
SQL->FreeResult(inter->sql_handle);
return -1;
}
}


int itemsCount = 0;

struct SqlStmt *stmt_items = SQL->StmtMalloc(inter->sql_handle);

if (stmt_items == NULL) {
return -1;
}

StringBuf buf;
StrBuf->Init(&buf);

StrBuf->AppendStr(&buf, "SELECT `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
for (int i = 0; i < MAX_SLOTS; i++) {
StrBuf->Printf(&buf, ", `card%d`", i);
}
for (int i = 0; i < MAX_ITEM_OPTIONS; i++) {
StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", i, i);
}
StrBuf->Printf(&buf, "FROM `%s` WHERE mail_id = ? ORDER BY `mail_id` ASC", rodex_item_db);

struct item it = { 0 };

if (SQL_ERROR == SQL->StmtPrepareStr(stmt_items, StrBuf->Value(&buf))
|| SQL_ERROR == SQL->StmtBindParam(stmt_items, 0, SQLDT_INT64, &mail_id, sizeof mail_id)
) {
SqlStmt_ShowDebug(stmt_items);
}

if (SQL_ERROR == SQL->StmtExecute(stmt_items)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 0, SQLDT_INT, &it.nameid, sizeof it.nameid, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 1, SQLDT_SHORT, &it.amount, sizeof it.amount, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 2, SQLDT_UINT, &it.equip, sizeof it.equip, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 3, SQLDT_CHAR, &it.identify, sizeof it.identify, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 4, SQLDT_CHAR, &it.refine, sizeof it.refine, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 5, SQLDT_CHAR, &it.attribute, sizeof it.attribute, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 6, SQLDT_UINT, &it.expire_time, sizeof it.expire_time, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 7, SQLDT_UCHAR, &it.bound, sizeof it.bound, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 8, SQLDT_UINT64, &it.unique_id, sizeof it.unique_id, NULL, NULL)
) {
SqlStmt_ShowDebug(stmt_items);
}
for (int i = 0; i < MAX_SLOTS; i++) {
if (SQL_ERROR == SQL->StmtBindColumn(stmt_items, 9 + i, SQLDT_INT, &it.card[i], sizeof it.card[i], NULL, NULL))
SqlStmt_ShowDebug(stmt_items);
}
for (int i = 0; i < MAX_ITEM_OPTIONS; i++) {
if (SQL_ERROR == SQL->StmtBindColumn(stmt_items, 9 + MAX_SLOTS + i * 2, SQLDT_INT16, &it.option[i].index, sizeof it.option[i].index, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt_items, 10 + MAX_SLOTS + i * 2, SQLDT_INT16, &it.option[i].value, sizeof it.option[i].value, NULL, NULL)
) {
SqlStmt_ShowDebug(stmt_items);
}
}

for (int i = 0; i < RODEX_MAX_ITEM && SQL_SUCCESS == SQL->StmtNextRow(stmt_items); ++i) {
items[i].item = it;
items[i].idx = itemsCount;
itemsCount++;
}

SQL->StmtFreeResult(stmt_items);

StrBuf->Destroy(&buf);
SQL->StmtFree(stmt_items);

return itemsCount;
}

/*==========================================
* Update/Delete mail
*------------------------------------------*/
static bool inter_rodex_updatemail(int64 mail_id, int8 flag)
static bool inter_rodex_updatemail(int fd, int account_id, int char_id, int64 mail_id, uint8 opentype, int8 flag)
{
Assert_retr(false, fd >= 0);
Assert_retr(false, account_id > 0);
Assert_retr(false, char_id > 0);
Assert_retr(false, mail_id > 0);
Assert_retr(false, flag >= 0 && flag <= 4);

Expand All @@ -361,17 +478,26 @@ static bool inter_rodex_updatemail(int64 mail_id, int8 flag)
break;

case 1: // Get Zeny
if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `zeny` = 0, `type` = `type` & (~2) WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id))
{
const int64 zeny = inter_rodex->getzeny(mail_id);
if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `zeny` = 0, `type` = `type` & (~2) WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) {
Sql_ShowDebug(inter->sql_handle);
break;
}
mapif->rodex_getzenyack(fd, char_id, mail_id, opentype, zeny);
break;

}
case 2: // Get Items
{
struct rodex_item items[RODEX_MAX_ITEM];
const int count = inter_rodex->getitems(mail_id, &items[0]);
if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `mail_id` = '%"PRId64"'", rodex_item_db, mail_id))
Sql_ShowDebug(inter->sql_handle);
if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `zeny` = 0, `type` = `type` & (~4) WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id))
Sql_ShowDebug(inter->sql_handle);
mapif->rodex_getitemsack(fd, char_id, mail_id, opentype, count, &items[0]);
break;

}
case 3: // Delete Mail
if (SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id))
Sql_ShowDebug(inter->sql_handle);
Expand Down Expand Up @@ -429,4 +555,6 @@ void inter_rodex_defaults(void)
inter_rodex->hasnew = inter_rodex_hasnew;
inter_rodex->checkname = inter_rodex_checkname;
inter_rodex->updatemail = inter_rodex_updatemail;
inter_rodex->getzeny = inter_rodex_getzeny;
inter_rodex->getitems = inter_rodex_getitems;
}
4 changes: 3 additions & 1 deletion src/char/int_rodex.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ struct inter_rodex_interface {
bool (*hasnew) (int char_id, int account_id);
bool (*checkname) (const char *name, int *target_char_id, int *target_class, int *target_level);
int64 (*savemessage) (struct rodex_message* msg);
bool (*updatemail) (int64 mail_id, int8 flag);
bool (*updatemail) (int fd, int account_id, int char_id, int64 mail_id, uint8 opentype, int8 flag);
int64 (*getzeny) (int64 mail_id);
int (*getitems) (int64 mail_id, struct rodex_item *items);
};

#ifdef HERCULES_CORE
Expand Down
2 changes: 1 addition & 1 deletion src/char/inter.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static int inter_recv_packet_length[] = {
6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish]
-1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil]
56,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080-
-1,10,-1, 6, 0, 20,10,11, -1,6 + NAME_LENGTH, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator], RoDEX packets
-1,10,-1, 6, 0, 20,10,20, -1,6 + NAME_LENGTH, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator], RoDEX packets
};

static struct DBMap *wis_db = NULL; // int wis_id -> struct WisData*
Expand Down
34 changes: 31 additions & 3 deletions src/char/mapif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1744,10 +1744,13 @@ static void mapif_rodex_sendhasnew(int fd, int char_id, bool has_new)
*------------------------------------------*/
static void mapif_parse_rodex_updatemail(int fd)
{
int64 mail_id = RFIFOL(fd, 2);
int8 flag = RFIFOB(fd, 10);
int account_id = RFIFOL(fd, 2);
int char_id = RFIFOL(fd, 6);
int64 mail_id = RFIFOQ(fd, 10);
uint8 opentype = RFIFOB(fd, 18);
int8 flag = RFIFOB(fd, 19);

inter_rodex->updatemail(mail_id, flag);
inter_rodex->updatemail(fd, account_id, char_id, mail_id, opentype, flag);
}

/*==========================================
Expand Down Expand Up @@ -2461,6 +2464,29 @@ static void mapif_achievement_save(int char_id, struct char_achievements *p)
inter_achievement->tosql(char_id, cp, p);
}

static void mapif_rodex_getzenyack(int fd, int char_id, int64 mail_id, uint8 opentype, int64 zeny)
{
WFIFOHEAD(fd, 23);
WFIFOW(fd, 0) = 0x3899;
WFIFOL(fd, 2) = char_id;
WFIFOQ(fd, 6) = zeny;
WFIFOQ(fd, 14) = mail_id;
WFIFOB(fd, 22) = opentype;
WFIFOSET(fd, 23);
}

static void mapif_rodex_getitemsack(int fd, int char_id, int64 mail_id, uint8 opentype, int count, const struct rodex_item *items)
{
WFIFOHEAD(fd, 15 + sizeof(struct rodex_item) * RODEX_MAX_ITEM);
WFIFOW(fd, 0) = 0x389a;
WFIFOL(fd, 2) = char_id;
WFIFOQ(fd, 6) = mail_id;
WFIFOB(fd, 14) = opentype;
WFIFOB(fd, 15) = count;
memcpy(WFIFOP(fd, 16), items, sizeof(struct rodex_item) * RODEX_MAX_ITEM);
WFIFOSET(fd, 16 + sizeof(struct rodex_item) * RODEX_MAX_ITEM);
}

void mapif_defaults(void)
{
mapif = &mapif_s;
Expand Down Expand Up @@ -2605,6 +2631,8 @@ void mapif_defaults(void)
mapif->rodex_send = mapif_rodex_send;
mapif->parse_rodex_checkname = mapif_parse_rodex_checkname;
mapif->rodex_checkname = mapif_rodex_checkname;
mapif->rodex_getzenyack = mapif_rodex_getzenyack;
mapif->rodex_getitemsack = mapif_rodex_getitemsack;
mapif->load_guild_storage = mapif_load_guild_storage;
mapif->save_guild_storage_ack = mapif_save_guild_storage_ack;
mapif->parse_LoadGuildStorage = mapif_parse_LoadGuildStorage;
Expand Down
3 changes: 3 additions & 0 deletions src/char/mapif.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "common/mmo.h"

struct WisData;
struct rodex_item;

/**
* mapif interface
Expand Down Expand Up @@ -168,6 +169,8 @@ struct mapif_interface {
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, int target_class, int target_level, char *name);
void (*rodex_getzenyack) (int fd, int char_id, int64 mail_id, uint8 opentype, int64 zeny);
void (*rodex_getitemsack) (int fd, int char_id, int64 mail_id, uint8 opentype, int count, const struct rodex_item *items);
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);
Expand Down
1 change: 1 addition & 0 deletions src/common/HPMDataCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "party_member", sizeof(struct party_member), SERVER_TYPE_ALL },
{ "point", sizeof(struct point), SERVER_TYPE_ALL },
{ "quest", sizeof(struct quest), SERVER_TYPE_ALL },
{ "rodex_item", sizeof(struct rodex_item), SERVER_TYPE_ALL },
{ "rodex_maillist", sizeof(struct rodex_maillist), SERVER_TYPE_ALL },
{ "rodex_message", sizeof(struct rodex_message), SERVER_TYPE_ALL },
{ "s_elemental", sizeof(struct s_elemental), SERVER_TYPE_ALL },
Expand Down
10 changes: 6 additions & 4 deletions src/common/mmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,11 @@ enum fame_list_type {
RANKTYPE_PK = 3, //Not supported yet
};

struct rodex_item {
struct item item;
int idx;
};

struct rodex_message {
int64 id;
int sender_id;
Expand All @@ -987,10 +992,7 @@ struct rodex_message {
char receiver_name[NAME_LENGTH];
char title[RODEX_TITLE_LENGTH];
char body[RODEX_BODY_LENGTH];
struct {
struct item item;
int idx;
} items[RODEX_MAX_ITEM];
struct rodex_item items[RODEX_MAX_ITEM];
int64 zeny;
uint8 type;
int8 opentype;
Expand Down
50 changes: 44 additions & 6 deletions src/map/intif.c
Original file line number Diff line number Diff line change
Expand Up @@ -2754,16 +2754,21 @@ static void intif_parse_RodexNotifications(int fd)
/// 2 - user got Items
/// 3 - delete
/// 4 - sender Read (returned mail)
static int intif_rodex_updatemail(int64 mail_id, int8 flag)
static int intif_rodex_updatemail(struct map_session_data *sd, int64 mail_id, uint8 opentype, int8 flag)
{
nullpo_ret(sd);

if (intif->CheckForCharServer())
return 0;

WFIFOHEAD(inter_fd, 11);
WFIFOHEAD(inter_fd, 20);
WFIFOW(inter_fd, 0) = 0x3097;
WFIFOQ(inter_fd, 2) = mail_id;
WFIFOB(inter_fd, 10) = flag;
WFIFOSET(inter_fd, 11);
WFIFOL(inter_fd, 2) = sd->status.account_id;
WFIFOL(inter_fd, 6) = sd->status.char_id;
WFIFOQ(inter_fd, 10) = mail_id;
WFIFOB(inter_fd, 18) = opentype;
WFIFOB(inter_fd, 19) = flag;
WFIFOSET(inter_fd, 20);

return 0;
}
Expand Down Expand Up @@ -2855,6 +2860,35 @@ static void intif_parse_RodexCheckName(int fd)
clif->rodex_checkname_result(sd, target_char_id, target_class, target_level, name);
}

static void intif_parse_GetZenyAck(int fd)
{
int char_id = RFIFOL(fd, 2);
int64 zeny = RFIFOL(fd, 6);
int64 mail_id = RFIFOQ(fd, 14);
uint8 opentype = RFIFOB(fd, 22);
struct map_session_data *sd = map->charid2sd(char_id);

if (sd == NULL) // User is not online anymore
return;
rodex->getZenyAck(sd, mail_id, opentype, zeny);
}

static void intif_parse_GetItemsAck(int fd)
{
int char_id = RFIFOL(fd, 2);

struct map_session_data *sd = map->charid2sd(char_id);
if (sd == NULL) // User is not online anymore
return;

int64 mail_id = RFIFOQ(fd, 6);
uint8 opentype = RFIFOB(fd, 14);
int count = RFIFOB(fd, 15);
struct rodex_item items[RODEX_MAX_ITEM];
memcpy(&items[0], RFIFOP(fd, 16), sizeof(struct rodex_item) * RODEX_MAX_ITEM);
rodex->getItemsAck(sd, mail_id, opentype, count, &items[0]);
}

//-----------------------------------------------------------------
// Communication from the inter server
// Return a 0 (false) if there were any errors.
Expand Down Expand Up @@ -2972,6 +3006,8 @@ static int intif_parse(int fd)
case 0x3896: intif->pRodexHasNew(fd); break;
case 0x3897: intif->pRodexSendMail(fd); break;
case 0x3898: intif->pRodexCheckName(fd); break;
case 0x3899: intif->pGetZenyAck(fd); break;
case 0x389a: intif->pGetItemsAck(fd); break;

// Clan System
case 0x3858: intif->pRecvClanMemberAction(fd); break;
Expand Down Expand Up @@ -3001,7 +3037,7 @@ void intif_defaults(void)
-1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish]
-1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil]
14,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
-1,-1, 7, 3, 0,-1, 7, 15,18 + NAME_LENGTH, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator] / RoDEX [KirieZ]
-1,-1, 7, 3, 0,-1, 7, 15,18 + NAME_LENGTH, 23, 16 + sizeof(struct rodex_item) * RODEX_MAX_ITEM, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator] / RoDEX [KirieZ]
};

intif = &intif_s;
Expand Down Expand Up @@ -3171,6 +3207,8 @@ void intif_defaults(void)
intif->pRodexHasNew = intif_parse_RodexNotifications;
intif->pRodexSendMail = intif_parse_RodexSendMail;
intif->pRodexCheckName = intif_parse_RodexCheckName;
intif->pGetZenyAck = intif_parse_GetZenyAck;
intif->pGetItemsAck = intif_parse_GetItemsAck;
/* Clan System */
intif->pRecvClanMemberAction = intif_parse_RecvClanMemberAction;
/* Achievement System */
Expand Down
4 changes: 3 additions & 1 deletion src/map/intif.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,11 @@ struct intif_interface {
// RoDEX
int(*rodex_requestinbox) (int char_id, int account_id, int8 flag, int8 opentype, int64 mail_id);
int(*rodex_checkhasnew) (struct map_session_data *sd);
int(*rodex_updatemail) (int64 mail_id, int8 flag);
int(*rodex_updatemail) (struct map_session_data *sd, int64 mail_id, uint8 opentype, int8 flag);
int(*rodex_sendmail) (struct rodex_message *msg);
int(*rodex_checkname) (struct map_session_data *sd, const char *name);
void (*pGetZenyAck) (int fd);
void (*pGetItemsAck) (int fd);
/* Clan System */
int (*clan_kickoffline) (int clan_id, int kick_interval);
int (*clan_membercount) (int clan_id, int kick_interval);
Expand Down
Loading