Skip to content
Permalink
Browse files

Merge pull request #2437 from 4144/rodexfixes

Different rodex fixes
  • Loading branch information...
MishimaHaruna committed Apr 17, 2019
2 parents ab81d40 + 9ae815c commit 0013040c4ed763eb4359a56ee106449fea5f2a83
@@ -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);

@@ -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);
@@ -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;
}
@@ -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
@@ -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*
@@ -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);
}

/*==========================================
@@ -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;
@@ -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;
@@ -24,6 +24,7 @@
#include "common/mmo.h"

struct WisData;
struct rodex_item;

/**
* mapif interface
@@ -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);
@@ -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 },
@@ -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;
@@ -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;
@@ -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;
}
@@ -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.
@@ -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;
@@ -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;
@@ -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 */
@@ -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);
Oops, something went wrong.

0 comments on commit 0013040

Please sign in to comment.
You can’t perform that action at this time.