/** * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * * Copyright (C) 2017 Hercules Dev Team * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define HERCULES_CORE #include "int_rodex.h" #include "char/char.h" #include "char/inter.h" #include "char/mapif.h" #include "common/db.h" #include "common/memmgr.h" #include "common/mmo.h" #include "common/nullpo.h" #include "common/showmsg.h" #include "common/socket.h" #include "common/sql.h" #include "common/strlib.h" #include "common/timer.h" #include #include struct inter_rodex_interface inter_rodex_s; struct inter_rodex_interface *inter_rodex; // Loads new mails of this char_id/account_id static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64 mail_id, struct rodex_maillist *mails) { int count = 0; struct rodex_message msg = { 0 }; struct SqlStmt *stmt; nullpo_retr(-1, mails); stmt = SQL->StmtMalloc(inter->sql_handle); switch (opentype) { case RODEX_OPENTYPE_MAIL: if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE `expire_date` > '%d' AND `receiver_id` = '%d' AND `mail_id` > '%"PRId64"'" "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), char_id, mail_id) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } break; case RODEX_OPENTYPE_ACCOUNT: if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE " "`expire_date` > '%d' AND `receiver_accountid` = '%d' AND `mail_id` > '%"PRId64"'" "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), account_id, mail_id) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } break; case RODEX_OPENTYPE_RETURN: if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE (`is_read` = 0 AND `sender_id` = '%d' AND `expire_date` <= '%d' AND `expire_date` + '%d' > '%d' AND `mail_id` > '%"PRId64"')" "ORDER BY `mail_id` ASC", rodex_db, char_id, (int)time(NULL), RODEX_EXPIRE, (int)time(NULL), mail_id) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } break; case RODEX_OPENTYPE_UNSET: if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE " "((`expire_date` > '%d' AND (`receiver_id` = '%d' OR `receiver_accountid` = '%d'))" "OR (`is_read` = 0 AND `sender_id` = '%d' AND `expire_date` <= '%d' AND `expire_date` + '%d' > '%d'))" "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), char_id, account_id, char_id, (int)time(NULL), RODEX_EXPIRE, (int)time(NULL)) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } break; } if (SQL_ERROR == SQL->StmtExecute(stmt) || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT64, &msg.id, sizeof msg.id, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_STRING, &msg.sender_name, sizeof msg.sender_name, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_INT, &msg.sender_id, sizeof msg.sender_id, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_STRING, &msg.receiver_name, sizeof msg.receiver_name, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_INT, &msg.receiver_id, sizeof msg.receiver_id, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_INT, &msg.receiver_accountid, sizeof msg.receiver_accountid, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_STRING, &msg.title, sizeof msg.title, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_STRING, &msg.body, sizeof msg.body, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_INT64, &msg.zeny, sizeof msg.zeny, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_UINT8, &msg.type, sizeof msg.type, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 10, SQLDT_BOOL, &msg.is_read, sizeof msg.is_read, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 11, SQLDT_BOOL, &msg.sender_read, sizeof msg.sender_read, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 12, SQLDT_INT, &msg.send_date, sizeof msg.send_date, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 13, SQLDT_INT, &msg.expire_date, sizeof msg.expire_date, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 14, SQLDT_INT, &msg.weight, sizeof msg.weight, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } { struct item it = { 0 }; StringBuf buf; struct SqlStmt *stmt_items = SQL->StmtMalloc(inter->sql_handle); int i; if (stmt_items == NULL) { SQL->StmtFreeResult(stmt); SQL->StmtFree(stmt); return -1; } StrBuf->Init(&buf); StrBuf->AppendStr(&buf, "SELECT `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`"); for (i = 0; i < MAX_SLOTS; i++) { StrBuf->Printf(&buf, ", `card%d`", i); } for (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); if (SQL_ERROR == SQL->StmtPrepareStr(stmt_items, StrBuf->Value(&buf)) || SQL_ERROR == SQL->StmtBindParam(stmt_items, 0, SQLDT_INT64, &msg.id, sizeof msg.id) ) { SqlStmt_ShowDebug(stmt_items); } // Read mails while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) { if (msg.type & MAIL_TYPE_ITEM) { if (SQL_ERROR == SQL->StmtExecute(stmt_items) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 0, SQLDT_SHORT, &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 (i = 0; i < MAX_SLOTS; i++) { if (SQL_ERROR == SQL->StmtBindColumn(stmt_items, 9 + i, SQLDT_SHORT, &it.card[i], sizeof it.card[i], NULL, NULL)) SqlStmt_ShowDebug(stmt_items); } for (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 (i = 0; i < RODEX_MAX_ITEM && SQL_SUCCESS == SQL->StmtNextRow(stmt_items); ++i) { msg.items[i].item = it; msg.items_count++; } } if (msg.items_count == 0) { msg.type &= ~MAIL_TYPE_ITEM; } if (msg.zeny == 0) { msg.type &= ~MAIL_TYPE_ZENY; } #if PACKETVER >= 20170419 if (opentype == RODEX_OPENTYPE_UNSET) { if (msg.receiver_id == 0) msg.opentype = RODEX_OPENTYPE_ACCOUNT; else if (msg.expire_date < time(NULL)) msg.opentype = RODEX_OPENTYPE_RETURN; else msg.opentype = RODEX_OPENTYPE_MAIL; } else { msg.opentype = opentype; } #else msg.opentype = opentype; #endif #if PACKETVER < 20160601 // NPC Message Type isn't supported in old clients msg.type &= ~MAIL_TYPE_NPC; #endif ++count; VECTOR_ENSURE(*mails, 1, 1); VECTOR_PUSH(*mails, msg); memset(&msg, 0, sizeof(struct rodex_message)); SQL->StmtFreeResult(stmt_items); } StrBuf->Destroy(&buf); SQL->StmtFree(stmt_items); } SQL->StmtFreeResult(stmt); SQL->StmtFree(stmt); ShowInfo("rodex load complete from DB - id: %d (total: %d)\n", char_id, count); return count; } // Checks if user has non-read mails static bool inter_rodex_hasnew(int char_id, int account_id) { int count = 0; char *data; if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT count(*) FROM `%s` WHERE (" "(`expire_date` > '%d' AND (`receiver_id` = '%d' OR `receiver_accountid` = '%d')) OR" "(`sender_id` = '%d' AND `expire_date` <= '%d' AND `send_date` + '%d' > '%d' AND `is_read` = 0)" // is_read is required in this line because of the OR in next condition ") AND ((`is_read` = 0 AND `sender_read` = 0) OR (`type` > 0 AND `type` != 8))", rodex_db, (int)time(NULL), char_id, account_id, char_id, (int)time(NULL), 2 * RODEX_EXPIRE, (int)time(NULL)) ) { Sql_ShowDebug(inter->sql_handle); return -1; } if (SQL_SUCCESS != SQL->NextRow(inter->sql_handle)) return false; SQL->GetData(inter->sql_handle, 0, &data, NULL); count = atoi(data); SQL->FreeResult(inter->sql_handle); return count > 0; } /// Checks player name and retrieves some data static bool inter_rodex_checkname(const char *name, int *target_char_id, short *target_class, int *target_level) { char esc_name[NAME_LENGTH * 2 + 1]; bool found = false; nullpo_retr(false, name); nullpo_retr(false, target_char_id); nullpo_retr(false, target_class); nullpo_retr(false, target_level); // Try to find the Dest Char by Name SQL->EscapeStringLen(inter->sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `char_id`, `class`, `base_level` FROM `%s` WHERE `name` = '%s'", char_db, esc_name)) { Sql_ShowDebug(inter->sql_handle); } else { if (SQL_SUCCESS == SQL->NextRow(inter->sql_handle)) { char *data; SQL->GetData(inter->sql_handle, 0, &data, NULL); *target_char_id = atoi(data); SQL->GetData(inter->sql_handle, 1, &data, NULL); *target_class = (short)atoi(data); SQL->GetData(inter->sql_handle, 2, &data, NULL); *target_level = atoi(data); found = true; } } SQL->FreeResult(inter->sql_handle); return found; } /// Stores a single message in the database. /// Returns the message's ID if successful (or 0 if it fails). int64 inter_rodex_savemessage(struct rodex_message* msg) { char sender_name[NAME_LENGTH * 2 + 1]; char receiver_name[NAME_LENGTH * 2 + 1]; char body[RODEX_BODY_LENGTH * 2 + 1]; char title[RODEX_TITLE_LENGTH * 2 + 1]; int i; nullpo_retr(false, msg); SQL->EscapeStringLen(inter->sql_handle, sender_name, msg->sender_name, strnlen(msg->sender_name, NAME_LENGTH)); SQL->EscapeStringLen(inter->sql_handle, receiver_name, msg->receiver_name, strnlen(msg->receiver_name, NAME_LENGTH)); SQL->EscapeStringLen(inter->sql_handle, body, msg->body, strnlen(msg->body, RODEX_BODY_LENGTH)); SQL->EscapeStringLen(inter->sql_handle, title, msg->title, strnlen(msg->title, RODEX_TITLE_LENGTH)); if (SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` (`sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`, `title`, `body`," "`zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`) VALUES " "('%s', '%d', '%s', '%d', '%d', '%s', '%s', '%"PRId64"', '%d', '%d', '%d', '%d', '%d', '%d')", rodex_db, sender_name, msg->sender_id, receiver_name, msg->receiver_id, msg->receiver_accountid, title, body, msg->zeny, msg->type, msg->is_read == true ? 1 : 0, msg->sender_read == true ? 1 : 0, msg->send_date, msg->expire_date, msg->weight)) { Sql_ShowDebug(inter->sql_handle); return 0; } msg->id = (int64)SQL->LastInsertId(inter->sql_handle); for (i = 0; i < RODEX_MAX_ITEM; ++i) { // Should we use statement here? [KIRIEZ] struct item *it = &msg->items[i].item; if (it->nameid == 0) continue; if (SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` (`mail_id`, `nameid`, `amount`, `equip`, `identify`," "`refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `opt_idx0`, `opt_val0`, `opt_idx1`, `opt_val1`, `opt_idx2`," "`opt_val2`, `opt_idx3`, `opt_val3`, `opt_idx4`, `opt_val4`,`expire_time`, `bound`, `unique_id`) VALUES " "('%"PRId64"', '%d', '%d', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%u', '%"PRIu64"')", rodex_item_db, msg->id, it->nameid, it->amount, it->equip, it->identify, it->refine, it->attribute, it->card[0], it->card[1], it->card[2], it->card[3], it->option[0].index, it->option[0].value, it->option[1].index, it->option[1].value, it->option[2].index, it->option[2].value, it->option[3].index, it->option[3].value, it->option[4].index, it->option[4].value, it->expire_time, it->bound, it->unique_id) ) { Sql_ShowDebug(inter->sql_handle); continue; } } return msg->id; } /*========================================== * Inbox Request *------------------------------------------*/ void mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails) { int per_packet = (UINT16_MAX - 24) / sizeof(struct rodex_message); int sent = 0; bool is_first = true; nullpo_retv(mails); Assert_retv(char_id > 0); Assert_retv(count >= 0); Assert_retv(mail_id >= 0); do { int i = 24, j, size, limit; int to_send = count - sent; bool is_last = true; if (to_send <= per_packet) { size = to_send * sizeof(struct rodex_message) + 24; limit = to_send; is_last = true; } else { limit = min(to_send, per_packet); if (limit != to_send) { is_last = false; } size = limit * sizeof(struct rodex_message) + 24; } WFIFOHEAD(fd, size); WFIFOW(fd, 0) = 0x3895; WFIFOW(fd, 2) = size; WFIFOL(fd, 4) = char_id; WFIFOB(fd, 8) = opentype; WFIFOB(fd, 9) = flag; WFIFOB(fd, 10) = is_last; WFIFOB(fd, 11) = is_first; WFIFOL(fd, 12) = limit; WFIFOQ(fd, 16) = mail_id; for (j = 0; j < limit; ++j, ++sent, i += sizeof(struct rodex_message)) { memcpy(WFIFOP(fd, i), &VECTOR_INDEX(*mails, sent), sizeof(struct rodex_message)); } WFIFOSET(fd, size); is_first = false; } while (sent < count); } void mapif_parse_rodex_requestinbox(int fd) { int count; int char_id = RFIFOL(fd,2); int account_id = RFIFOL(fd, 6); int8 flag = RFIFOB(fd, 10); int8 opentype = RFIFOB(fd, 11); int64 mail_id = RFIFOQ(fd, 12); struct rodex_maillist mails = { 0 }; VECTOR_INIT(mails); if (flag == 0) count = inter_rodex->fromsql(char_id, account_id, opentype, 0, &mails); else count = inter_rodex->fromsql(char_id, account_id, opentype, mail_id, &mails); mapif->rodex_sendinbox(fd, char_id, opentype, flag, count, mail_id, &mails); VECTOR_CLEAR(mails); } /*========================================== * Checks if there are new mails *------------------------------------------*/ void mapif_rodex_sendhasnew(int fd, int char_id, bool has_new) { Assert_retv(char_id > 0); WFIFOHEAD(fd, 7); WFIFOW(fd, 0) = 0x3896; WFIFOL(fd, 2) = char_id; WFIFOB(fd, 6) = has_new; WFIFOSET(fd, 7); } void mapif_parse_rodex_checkhasnew(int fd) { int char_id = RFIFOL(fd, 2); int account_id = RFIFOL(fd, 6); bool has_new; Assert_retv(account_id >= START_ACCOUNT_NUM && account_id <= END_ACCOUNT_NUM); Assert_retv(char_id >= START_CHAR_NUM); has_new = inter_rodex->hasnew(char_id, account_id); mapif->rodex_sendhasnew(fd, char_id, has_new); } /*========================================== * Update/Delete mail *------------------------------------------*/ void mapif_parse_rodex_updatemail(int fd) { int64 mail_id = RFIFOL(fd, 2); int8 flag = RFIFOB(fd, 10); Assert_retv(mail_id > 0); Assert_retv(flag >= 0 && flag <= 4); switch (flag) { case 0: // Read if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `is_read` = 1 WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) Sql_ShowDebug(inter->sql_handle); 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)) Sql_ShowDebug(inter->sql_handle); break; case 2: // Get Items 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); 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); 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); break; case 4: // Sender Read if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `sender_read` = 1 WHERE `mail_id` = '%"PRId64"'", rodex_db, mail_id)) Sql_ShowDebug(inter->sql_handle); break; } } /*========================================== * Send Mail *------------------------------------------*/ void mapif_rodex_send(int fd, int sender_id, int receiver_id, int receiver_accountid, bool result) { Assert_retv(sender_id >= 0); Assert_retv(receiver_id + receiver_accountid > 0); WFIFOHEAD(fd,15); WFIFOW(fd,0) = 0x3897; WFIFOL(fd,2) = sender_id; WFIFOL(fd,6) = receiver_id; WFIFOL(fd,10) = receiver_accountid; WFIFOB(fd,14) = result; WFIFOSET(fd,15); } void mapif_parse_rodex_send(int fd) { struct rodex_message msg = { 0 }; if (RFIFOW(fd,2) != 4 + sizeof(struct rodex_message)) return; memcpy(&msg, RFIFOP(fd,4), sizeof(struct rodex_message)); if (msg.receiver_id > 0 || msg.receiver_accountid > 0) msg.id = inter_rodex->savemessage(&msg); mapif->rodex_send(fd, msg.sender_id, msg.receiver_id, msg.receiver_accountid, msg.id > 0 ? true : false); } /*------------------------------------------ * Check Player *------------------------------------------*/ void mapif_rodex_checkname(int fd, int reqchar_id, int target_char_id, short target_class, int target_level, char *name) { nullpo_retv(name); Assert_retv(reqchar_id > 0); Assert_retv(target_char_id >= 0); WFIFOHEAD(fd, 16 + NAME_LENGTH); WFIFOW(fd, 0) = 0x3898; WFIFOL(fd, 2) = reqchar_id; WFIFOL(fd, 6) = target_char_id; WFIFOW(fd, 10) = target_class; WFIFOL(fd, 12) = target_level; safestrncpy(WFIFOP(fd, 16), name, NAME_LENGTH); WFIFOSET(fd, 16 + NAME_LENGTH); } void mapif_parse_rodex_checkname(int fd) { int reqchar_id = RFIFOL(fd, 2); char name[NAME_LENGTH]; int target_char_id, target_level; short target_class; safestrncpy(name, RFIFOP(fd, 6), NAME_LENGTH); if (inter_rodex->checkname(name, &target_char_id, &target_class, &target_level) == true) mapif->rodex_checkname(fd, reqchar_id, target_char_id, target_class, target_level, name); else mapif->rodex_checkname(fd, reqchar_id, 0, 0, 0, name); } /*========================================== * Packets From Map Server *------------------------------------------*/ int inter_rodex_parse_frommap(int fd) { switch(RFIFOW(fd,0)) { case 0x3095: mapif->parse_rodex_requestinbox(fd); break; case 0x3096: mapif->parse_rodex_checkhasnew(fd); break; case 0x3097: mapif->parse_rodex_updatemail(fd); break; case 0x3098: mapif->parse_rodex_send(fd); break; case 0x3099: mapif->parse_rodex_checkname(fd); break; default: return 0; } return 1; } int inter_rodex_sql_init(void) { return 1; } void inter_rodex_sql_final(void) { return; } void inter_rodex_defaults(void) { inter_rodex = &inter_rodex_s; inter_rodex->savemessage = inter_rodex_savemessage; inter_rodex->parse_frommap = inter_rodex_parse_frommap; inter_rodex->sql_init = inter_rodex_sql_init; inter_rodex->sql_final = inter_rodex_sql_final; inter_rodex->fromsql = inter_rodex_fromsql; inter_rodex->hasnew = inter_rodex_hasnew; inter_rodex->checkname = inter_rodex_checkname; }