summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c7
-rw-r--r--src/char/int_clan.c14
-rw-r--r--src/char/int_rodex.c62
-rw-r--r--src/char/inter.c3
-rw-r--r--src/char/mapif.c2
-rw-r--r--src/char/mapif.h2
-rw-r--r--src/char/pincode.c17
-rw-r--r--src/common/HPMDataCheck.h20
-rw-r--r--src/common/HPMSymbols.inc.h28
-rw-r--r--src/common/md5calc.c2
-rw-r--r--src/common/mmo.h20
-rw-r--r--src/common/socket.c4
-rw-r--r--src/login/HPMlogin.c4
-rw-r--r--src/login/Makefile.in2
-rw-r--r--src/login/account.c (renamed from src/login/account_sql.c)123
-rw-r--r--src/login/account.h70
-rw-r--r--src/login/ipban.c (renamed from src/login/ipban_sql.c)120
-rw-r--r--src/login/ipban.h46
-rw-r--r--src/login/lclif.c26
-rw-r--r--src/login/lclif.p.h2
-rw-r--r--src/login/login.c210
-rw-r--r--src/login/login.h20
-rw-r--r--src/login/loginlog.c (renamed from src/login/loginlog_sql.c)107
-rw-r--r--src/login/loginlog.h38
-rw-r--r--src/map/atcommand.c50
-rw-r--r--src/map/battle.c4
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/clan.c94
-rw-r--r--src/map/clif.c323
-rw-r--r--src/map/clif.h4
-rw-r--r--src/map/intif.c26
-rw-r--r--src/map/map.c223
-rw-r--r--src/map/map.h32
-rw-r--r--src/map/packets.h80
-rw-r--r--src/map/packets_keys_main.h38
-rw-r--r--src/map/packets_keys_zero.h39
-rw-r--r--src/map/packets_shuffle_main.h178
-rw-r--r--src/map/packets_shuffle_zero.h207
-rw-r--r--src/map/pc.c48
-rw-r--r--src/map/rodex.c46
-rw-r--r--src/map/script.c25
-rw-r--r--src/map/script.h1
-rw-r--r--src/map/skill.h2
-rw-r--r--src/map/status.c4
-rw-r--r--src/map/status.h4
-rw-r--r--src/map/unit.c18
-rw-r--r--src/plugins/HPMHooking.c3
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc104
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.Hooks.inc12
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc160
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc43
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.Hooks.inc1045
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.sources.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc12
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc3
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc91
-rw-r--r--src/plugins/mapcache.c490
-rw-r--r--src/tool/Makefile.in23
-rw-r--r--src/tool/mapcache.c377
59 files changed, 3589 insertions, 1175 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 2532ca154..93fb1be75 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1616,7 +1616,7 @@ int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int
case JOB_NOVICE:
break;
default:
- return -2; // Char Creation Denied
+ return -2; // Char Creation Denied
}
//check other inputs
@@ -3328,7 +3328,12 @@ void char_char_name_ack(int fd, int char_id)
WFIFOHEAD(fd,30);
WFIFOW(fd,0) = 0x2b09;
WFIFOL(fd,2) = char_id;
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
+ if (chr->loadName(char_id, WFIFOP(fd,6)) == 0)
+ WFIFOL(fd, 6) = 0;
+#else
chr->loadName(char_id, WFIFOP(fd,6));
+#endif
WFIFOSET(fd,30);
}
diff --git a/src/char/int_clan.c b/src/char/int_clan.c
index 76a9639c5..e68f6a655 100644
--- a/src/char/int_clan.c
+++ b/src/char/int_clan.c
@@ -43,10 +43,10 @@ struct inter_clan_interface *inter_clan;
/**
* Kick offline members of a clan
- *
+ *
* Perform the update on the DB to reset clan id to 0
* of the members that are inactive for too long
- *
+ *
* @param clan_id Id of the clan
* @param kick_interval Time needed to consider a player inactive and kick it
* @return 0 on failure, 1 on success
@@ -55,11 +55,11 @@ int inter_clan_kick_inactive_members(int clan_id, int kick_interval)
{
if (clan_id <= 0) {
ShowError("inter_clan_kick_inactive_members: Invalid clan id received '%d'\n", clan_id);
- Assert_retr(0, 0);
+ Assert_report(clan_id > 0);
return 0;
} else if (kick_interval <= 0) {
ShowError("inter_clan_kick_inactive_members: Invalid kick_interval received '%d'", kick_interval);
- Assert_retr(0, 0);
+ Assert_report(kick_interval > 0);
return 0;
}
@@ -77,7 +77,7 @@ int inter_clan_kick_inactive_members(int clan_id, int kick_interval)
/**
* Count members of a clan
- *
+ *
* @param clan_id Id of the clan
* @param kick_interval Time needed to consider a player inactive and ignore it on the count
*/
@@ -88,11 +88,11 @@ int inter_clan_count_members(int clan_id, int kick_interval)
if (clan_id <= 0) {
ShowError("inter_clan_count_members: Invalid clan id received '%d'\n", clan_id);
- Assert_retr(0, 0);
+ Assert_report(clan_id > 0);
return 0;
} else if (kick_interval <= 0) {
ShowError("inter_clan_count_member: Invalid kick_interval received '%d'", kick_interval);
- Assert_retr(0, 0);
+ Assert_report(kick_interval > 0);
return 0;
}
diff --git a/src/char/int_rodex.c b/src/char/int_rodex.c
index b7314e726..2001ddc43 100644
--- a/src/char/int_rodex.c
+++ b/src/char/int_rodex.c
@@ -55,7 +55,7 @@ static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64
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`, `send_date`, `expire_date`, `weight`"
+ "`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)
) {
@@ -68,7 +68,7 @@ static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64
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`, `send_date`, `expire_date`, `weight`"
+ "`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)
@@ -82,8 +82,8 @@ static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64
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`, `send_date`, `expire_date`, `weight`"
- "FROM `%s` WHERE (`sender_id` = '%d' AND `expire_date` <= '%d' AND `send_date` + '%d' > '%d' AND `mail_id` > '%"PRId64"')"
+ "`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 `send_date` + '%d' > '%d' AND `mail_id` > '%"PRId64"')"
"ORDER BY `mail_id` ASC", rodex_db, char_id, (int)time(NULL), 2 * RODEX_EXPIRE, (int)time(NULL), mail_id)
) {
SqlStmt_ShowDebug(stmt);
@@ -95,9 +95,11 @@ static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64
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`, `send_date`, `expire_date`, `weight`"
- "FROM `%s` WHERE `expire_date` > '%d' AND (`receiver_id` = '%d' or `receiver_accountid` = '%d') AND `mail_id` > '%"PRId64"'"
- "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), char_id, account_id, mail_id)
+ "`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 `send_date` + '%d' > '%d'))"
+ "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), char_id, account_id, char_id, (int)time(NULL), 2 * RODEX_EXPIRE, (int)time(NULL))
) {
SqlStmt_ShowDebug(stmt);
SQL->StmtFree(stmt);
@@ -118,9 +120,10 @@ static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64
|| 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_INT, &msg.send_date, sizeof msg.send_date, NULL, NULL)
- || SQL_ERROR == SQL->StmtBindColumn(stmt, 12, SQLDT_INT, &msg.expire_date, sizeof msg.expire_date, NULL, NULL)
- || SQL_ERROR == SQL->StmtBindColumn(stmt, 13, SQLDT_INT, &msg.weight, sizeof msg.weight, 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);
@@ -201,10 +204,12 @@ static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64
#if PACKETVER >= 20170419
if (opentype == RODEX_OPENTYPE_UNSET) {
- if (msg.receiver_id != 0)
- msg.opentype = RODEX_OPENTYPE_MAIL;
- else
+ 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;
}
@@ -243,8 +248,8 @@ static bool inter_rodex_hasnew(int char_id, int account_id)
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 OR (`type` > 0 AND `type` != 8))",
+ "(`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))
) {
@@ -309,10 +314,10 @@ int64 inter_rodex_savemessage(struct rodex_message* msg)
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`, `send_date`, `expire_date`, `weight`) VALUES "
- "('%s', '%d', '%s', '%d', '%d', '%s', '%s', '%"PRId64"', '%d', '%d', '%d', '%d', '%d')",
+ "`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->send_date, msg->expire_date, msg->weight)) {
+ 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;
}
@@ -344,22 +349,23 @@ int64 inter_rodex_savemessage(struct rodex_message* msg)
/*==========================================
* Inbox Request
*------------------------------------------*/
-void mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int count, struct rodex_maillist *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 - 16) / sizeof(struct rodex_message);
+ 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 = 16, j, size, limit;
+ 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) + 16;
+ size = to_send * sizeof(struct rodex_message) + 24;
limit = to_send;
is_last = true;
} else {
@@ -367,7 +373,7 @@ void mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int co
if (limit != to_send) {
is_last = false;
}
- size = limit * sizeof(struct rodex_message) + 16;
+ size = limit * sizeof(struct rodex_message) + 24;
}
WFIFOHEAD(fd, size);
@@ -379,6 +385,7 @@ void mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int co
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));
}
@@ -403,7 +410,7 @@ void mapif_parse_rodex_requestinbox(int fd)
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, &mails);
+ mapif->rodex_sendinbox(fd, char_id, opentype, flag, count, mail_id, &mails);
VECTOR_CLEAR(mails);
}
@@ -443,7 +450,7 @@ void mapif_parse_rodex_updatemail(int fd)
int8 flag = RFIFOB(fd, 10);
Assert_retv(mail_id > 0);
- Assert_retv(flag >= 0 && flag <= 3);
+ Assert_retv(flag >= 0 && flag <= 4);
switch (flag) {
case 0: // Read
@@ -469,6 +476,11 @@ void mapif_parse_rodex_updatemail(int fd)
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;
}
}
diff --git a/src/char/inter.c b/src/char/inter.c
index baa000d82..b095a046d 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -527,12 +527,15 @@ void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int acc
inter->msg_to_fd(map_fd, u_fd, u_aid, "-- Account %d --", account_id);
inter->msg_to_fd(map_fd, u_fd, u_aid, "User: %s | GM Group: %d | State: %d", userid, group_id, state);
+// enable this if you really know what you doing.
+#if 0
if (*user_pass != '\0') { /* password is only received if your gm level is greater than the one you're searching for */
if (pin_code && *pin_code != '\0')
inter->msg_to_fd(map_fd, u_fd, u_aid, "Password: %s (PIN:%s)", user_pass, pin_code);
else
inter->msg_to_fd(map_fd, u_fd, u_aid, "Password: %s", user_pass );
}
+#endif
inter->msg_to_fd(map_fd, u_fd, u_aid, "Account e-mail: %s | Birthdate: %s", email, birthdate);
inter->msg_to_fd(map_fd, u_fd, u_aid, "Last IP: %s (%s)", last_ip, geoip->getcountry(sockt->str2ip(last_ip)));
diff --git a/src/char/mapif.c b/src/char/mapif.c
index 241edc925..f80e38fe7 100644
--- a/src/char/mapif.c
+++ b/src/char/mapif.c
@@ -185,7 +185,7 @@ void mapif_send_quests(int fd, int char_id, struct quest *tmp_questlog, int num_
int mapif_parse_quest_load(int fd);
/* RoDEX */
int mapif_parse_rodex_requestinbox(int fd);
-void mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int count, struct rodex_maillist *mails);
+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);
diff --git a/src/char/mapif.h b/src/char/mapif.h
index f03f1ad9a..7fc79f661 100644
--- a/src/char/mapif.h
+++ b/src/char/mapif.h
@@ -177,7 +177,7 @@ struct mapif_interface {
void (*send_quests) (int fd, int char_id, struct quest *tmp_questlog, int num_quests);
int (*parse_quest_load) (int fd);
int(*parse_rodex_requestinbox) (int fd);
- void(*rodex_sendinbox) (int fd, int char_id, int8 opentype, int8 flag, int count, struct rodex_maillist *mails);
+ void(*rodex_sendinbox) (int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails);
int(*parse_rodex_checkhasnew) (int fd);
void(*rodex_sendhasnew) (int fd, int char_id, bool has_new);
int(*parse_rodex_updatemail) (int fd);
diff --git a/src/char/pincode.c b/src/char/pincode.c
index fc1a4c037..bca1b4394 100644
--- a/src/char/pincode.c
+++ b/src/char/pincode.c
@@ -68,6 +68,8 @@ void pincode_check(int fd, struct char_session_data* sd) {
char pin[5] = "\0\0\0\0";
nullpo_retv(sd);
+ if (strlen(sd->pincode) != 4)
+ return;
safestrncpy(pin, RFIFOP(fd, 6), sizeof(pin));
pincode->decrypt(sd->pincode_seed, pin);
if( pincode->compare( fd, sd, pin ) ){
@@ -87,7 +89,9 @@ int pincode_compare(int fd, struct char_session_data* sd, char* pin) {
} else {
pincode->sendstate( fd, sd, PINCODE_WRONG );
if( pincode->maxtry && ++sd->pincode_try >= pincode->maxtry ){
- pincode->error( sd->account_id );
+ pincode->error(sd->account_id);
+ chr->authfail_fd(fd, 0);
+ chr->disconnect_player(sd->account_id);
}
return 0;
}
@@ -97,6 +101,8 @@ void pincode_change(int fd, struct char_session_data* sd) {
char oldpin[5] = "\0\0\0\0", newpin[5] = "\0\0\0\0";
nullpo_retv(sd);
+ if (strlen(sd->pincode) != 4)
+ return;
safestrncpy(oldpin, RFIFOP(fd,6), sizeof(oldpin));
pincode->decrypt(sd->pincode_seed,oldpin);
if( !pincode->compare( fd, sd, oldpin ) )
@@ -113,6 +119,8 @@ void pincode_setnew(int fd, struct char_session_data* sd) {
char newpin[5] = "\0\0\0\0";
nullpo_retv(sd);
+ if (strlen(sd->pincode) == 4)
+ return;
safestrncpy(newpin, RFIFOP(fd,6), sizeof(newpin));
pincode->decrypt(sd->pincode_seed,newpin);
pincode->update( sd->account_id, newpin );
@@ -172,8 +180,11 @@ void pincode_decrypt(unsigned int userSeed, char* pin) {
}
}
- for( i = 0; i < 4; i++ ){
- pin[i] = tab[pin[i] - '0'];
+ for (i = 0; i < 4; i++ ) {
+ if (pin[i] < '0' || pin[i] > '9')
+ pin[i] = '0';
+ else
+ pin[i] = tab[pin[i] - '0'];
}
sprintf(pin, "%d%d%d%d", pin[0], pin[1], pin[2], pin[3]);
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index f2812a275..4bcb33e23 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -309,11 +309,20 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
#ifdef LOGIN_ACCOUNT_H
{ "Account_engine", sizeof(struct Account_engine), SERVER_TYPE_LOGIN },
{ "AccountDB", sizeof(struct AccountDB), SERVER_TYPE_LOGIN },
+ { "AccountDB_SQL", sizeof(struct AccountDB_SQL), SERVER_TYPE_LOGIN },
{ "AccountDBIterator", sizeof(struct AccountDBIterator), SERVER_TYPE_LOGIN },
+ { "AccountDBIterator_SQL", sizeof(struct AccountDBIterator_SQL), SERVER_TYPE_LOGIN },
+ { "account_interface", sizeof(struct account_interface), SERVER_TYPE_LOGIN },
{ "mmo_account", sizeof(struct mmo_account), SERVER_TYPE_LOGIN },
#else
#define LOGIN_ACCOUNT_H
#endif // LOGIN_ACCOUNT_H
+ #ifdef LOGIN_IPBAN_H
+ { "ipban_interface", sizeof(struct ipban_interface), SERVER_TYPE_LOGIN },
+ { "s_ipban_dbs", sizeof(struct s_ipban_dbs), SERVER_TYPE_LOGIN },
+ #else
+ #define LOGIN_IPBAN_H
+ #endif // LOGIN_IPBAN_H
#ifdef LOGIN_LCLIF_H
{ "lclif_interface", sizeof(struct lclif_interface), SERVER_TYPE_LOGIN },
{ "login_packet_db", sizeof(struct login_packet_db), SERVER_TYPE_LOGIN },
@@ -341,14 +350,22 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
#else
#define LOGIN_LCLIF_P_H
#endif // LOGIN_LCLIF_P_H
+ #ifdef LOGIN_LOGINLOG_H
+ { "loginlog_interface", sizeof(struct loginlog_interface), SERVER_TYPE_LOGIN },
+ { "s_loginlog_dbs", sizeof(struct s_loginlog_dbs), SERVER_TYPE_LOGIN },
+ #else
+ #define LOGIN_LOGINLOG_H
+ #endif // LOGIN_LOGINLOG_H
#ifdef LOGIN_LOGIN_H
{ "Login_Config", sizeof(struct Login_Config), SERVER_TYPE_LOGIN },
{ "client_hash_node", sizeof(struct client_hash_node), SERVER_TYPE_LOGIN },
+ { "lchrif_interface", sizeof(struct lchrif_interface), SERVER_TYPE_LOGIN },
{ "login_auth_node", sizeof(struct login_auth_node), SERVER_TYPE_LOGIN },
{ "login_interface", sizeof(struct login_interface), SERVER_TYPE_LOGIN },
{ "login_session_data", sizeof(struct login_session_data), SERVER_TYPE_LOGIN },
{ "mmo_char_server", sizeof(struct mmo_char_server), SERVER_TYPE_LOGIN },
{ "online_login_data", sizeof(struct online_login_data), SERVER_TYPE_LOGIN },
+ { "s_login_dbs", sizeof(struct s_login_dbs), SERVER_TYPE_LOGIN },
#else
#define LOGIN_LOGIN_H
#endif // LOGIN_LOGIN_H
@@ -507,8 +524,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "charid_request", sizeof(struct charid_request), SERVER_TYPE_MAP },
{ "flooritem_data", sizeof(struct flooritem_data), SERVER_TYPE_MAP },
{ "iwall_data", sizeof(struct iwall_data), SERVER_TYPE_MAP },
- { "map_cache_main_header", sizeof(struct map_cache_main_header), SERVER_TYPE_MAP },
- { "map_cache_map_info", sizeof(struct map_cache_map_info), SERVER_TYPE_MAP },
+ { "map_cache_header", sizeof(struct map_cache_header), SERVER_TYPE_MAP },
{ "map_data", sizeof(struct map_data), SERVER_TYPE_MAP },
{ "map_data_other_server", sizeof(struct map_data_other_server), SERVER_TYPE_MAP },
{ "map_drop_list", sizeof(struct map_drop_list), SERVER_TYPE_MAP },
diff --git a/src/common/HPMSymbols.inc.h b/src/common/HPMSymbols.inc.h
index 6be9d547c..70de5cdef 100644
--- a/src/common/HPMSymbols.inc.h
+++ b/src/common/HPMSymbols.inc.h
@@ -29,6 +29,9 @@
#ifdef COMMON_UTILS_H /* HCache */
struct HCache_interface *HCache;
#endif // COMMON_UTILS_H
+#ifdef LOGIN_ACCOUNT_H /* account */
+struct account_interface *account;
+#endif // LOGIN_ACCOUNT_H
#ifdef MAP_ATCOMMAND_H /* atcommand */
struct atcommand_interface *atcommand;
#endif // MAP_ATCOMMAND_H
@@ -140,12 +143,18 @@ struct inter_storage_interface *inter_storage;
#ifdef MAP_INTIF_H /* intif */
struct intif_interface *intif;
#endif // MAP_INTIF_H
+#ifdef LOGIN_IPBAN_H /* ipban */
+struct ipban_interface *ipban;
+#endif // LOGIN_IPBAN_H
#ifdef MAP_IRC_BOT_H /* ircbot */
struct irc_bot_interface *ircbot;
#endif // MAP_IRC_BOT_H
#ifdef MAP_ITEMDB_H /* itemdb */
struct itemdb_interface *itemdb;
#endif // MAP_ITEMDB_H
+#ifdef LOGIN_LOGIN_H /* lchrif */
+struct lchrif_interface *lchrif;
+#endif // LOGIN_LOGIN_H
#ifdef LOGIN_LCLIF_H /* lclif */
struct lclif_interface *lclif;
#endif // LOGIN_LCLIF_H
@@ -161,6 +170,9 @@ struct login_interface *login;
#ifdef CHAR_LOGINIF_H /* loginif */
struct loginif_interface *loginif;
#endif // CHAR_LOGINIF_H
+#ifdef LOGIN_LOGINLOG_H /* loginlog */
+struct loginlog_interface *loginlog;
+#endif // LOGIN_LOGINLOG_H
#ifdef MAP_MAIL_H /* mail */
struct mail_interface *mail;
#endif // MAP_MAIL_H
@@ -289,6 +301,10 @@ HPExport const char *HPM_shared_symbols(int server_type)
if ((server_type&(SERVER_TYPE_ALL)) != 0 && !HPM_SYMBOL("HCache", HCache))
return "HCache";
#endif // COMMON_UTILS_H
+#ifdef LOGIN_ACCOUNT_H /* account */
+ if ((server_type&(SERVER_TYPE_LOGIN)) != 0 && !HPM_SYMBOL("account", account))
+ return "account";
+#endif // LOGIN_ACCOUNT_H
#ifdef MAP_ATCOMMAND_H /* atcommand */
if ((server_type&(SERVER_TYPE_MAP)) != 0 && !HPM_SYMBOL("atcommand", atcommand))
return "atcommand";
@@ -437,6 +453,10 @@ HPExport const char *HPM_shared_symbols(int server_type)
if ((server_type&(SERVER_TYPE_MAP)) != 0 && !HPM_SYMBOL("intif", intif))
return "intif";
#endif // MAP_INTIF_H
+#ifdef LOGIN_IPBAN_H /* ipban */
+ if ((server_type&(SERVER_TYPE_LOGIN)) != 0 && !HPM_SYMBOL("ipban", ipban))
+ return "ipban";
+#endif // LOGIN_IPBAN_H
#ifdef MAP_IRC_BOT_H /* ircbot */
if ((server_type&(SERVER_TYPE_MAP)) != 0 && !HPM_SYMBOL("ircbot", ircbot))
return "ircbot";
@@ -445,6 +465,10 @@ HPExport const char *HPM_shared_symbols(int server_type)
if ((server_type&(SERVER_TYPE_MAP)) != 0 && !HPM_SYMBOL("itemdb", itemdb))
return "itemdb";
#endif // MAP_ITEMDB_H
+#ifdef LOGIN_LOGIN_H /* lchrif */
+ if ((server_type&(SERVER_TYPE_LOGIN)) != 0 && !HPM_SYMBOL("lchrif", lchrif))
+ return "lchrif";
+#endif // LOGIN_LOGIN_H
#ifdef LOGIN_LCLIF_H /* lclif */
if ((server_type&(SERVER_TYPE_LOGIN)) != 0 && !HPM_SYMBOL("lclif", lclif))
return "lclif";
@@ -465,6 +489,10 @@ HPExport const char *HPM_shared_symbols(int server_type)
if ((server_type&(SERVER_TYPE_CHAR)) != 0 && !HPM_SYMBOL("loginif", loginif))
return "loginif";
#endif // CHAR_LOGINIF_H
+#ifdef LOGIN_LOGINLOG_H /* loginlog */
+ if ((server_type&(SERVER_TYPE_LOGIN)) != 0 && !HPM_SYMBOL("loginlog", loginlog))
+ return "loginlog";
+#endif // LOGIN_LOGINLOG_H
#ifdef MAP_MAIL_H /* mail */
if ((server_type&(SERVER_TYPE_MAP)) != 0 && !HPM_SYMBOL("mail", mail))
return "mail";
diff --git a/src/common/md5calc.c b/src/common/md5calc.c
index d2fc32371..d5ce8b5a8 100644
--- a/src/common/md5calc.c
+++ b/src/common/md5calc.c
@@ -202,7 +202,7 @@ static void md5_buf2binary(const uint8 *buf, const int buf_size, uint8 *output)
//1-3
copy_len = buf_size % 64; //The number of bytes which remained is computed.
- strncpy((char *)padding_message, (const char *)pbuf, copy_len); // A message is copied to an extended bit sequence.
+ memcpy((char *)padding_message, (const char *)pbuf, copy_len); // A message is copied to an extended bit sequence.
memset(padding_message+copy_len, 0, 64 - copy_len); //It buries by 0 until it becomes extended bit length.
padding_message[copy_len] |= 0x80; //The next of a message is 1.
diff --git a/src/common/mmo.h b/src/common/mmo.h
index d7d0820b3..5e7f22e6e 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -81,6 +81,22 @@
#undef ENABLE_PACKETVER_ZERO
#endif // DISABLE_PACKETVER_ZERO
+#if !defined(PACKETVER_RE) && !defined(PACKETVER_ZERO)
+ #define PACKETVER_MAIN_NUM PACKETVER
+#else
+ #define PACKETVER_MAIN_NUM 0
+#endif
+#ifdef PACKETVER_RE
+ #define PACKETVER_RE_NUM PACKETVER
+#else
+ #define PACKETVER_RE_NUM 0
+#endif
+#ifdef PACKETVER_ZERO
+ #define PACKETVER_ZERO_NUM PACKETVER
+#else
+ #define PACKETVER_ZERO_NUM 0
+#endif
+
// Client support for experimental RagexeRE UI present in 2012-04-10 and 2012-04-18
#if defined(PACKETVER_RE) && ( PACKETVER == 20120410 || PACKETVER == 20120418 )
#define PARTY_RECRUIT
@@ -360,7 +376,7 @@ struct item {
char favorite;
unsigned char bound;
uint64 unique_id;
-
+
struct {
int16 index;
int16 value;
@@ -899,12 +915,12 @@ struct rodex_message {
struct {
struct item item;
int idx;
-
} items[RODEX_MAX_ITEM];
int64 zeny;
uint8 type;
int8 opentype;
bool is_read;
+ bool sender_read;
bool is_deleted;
int send_date;
int expire_date;
diff --git a/src/common/socket.c b/src/common/socket.c
index d4b8bb43f..c74cd4661 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -1537,7 +1537,7 @@ void socket_close(int fd)
// Epoll based Event Dispatcher
epevent.data.fd = fd;
epevent.events = EPOLLIN;
- epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &epevent); // removing the socket from epoll when it's being closed is not required but recommended
+ epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &epevent); // removing the socket from epoll when it's being closed is not required but recommended
#endif // SOCKET_EPOLL
sShutdown(fd, SHUT_RDWR); // Disallow further reads/writes
@@ -1694,7 +1694,7 @@ void socket_init(void)
#else // SOCKET_EPOLL
// Epoll based Event Dispatcher:
- epfd = epoll_create(FD_SETSIZE); // 2.6.8 or newer ignores the expected socket amount argument
+ epfd = epoll_create(FD_SETSIZE); // 2.6.8 or newer ignores the expected socket amount argument
if(epfd == SOCKET_ERROR){
ShowError("Failed to Create Epoll Event Dispatcher: %s\n", error_msg());
exit(EXIT_FAILURE);
diff --git a/src/login/HPMlogin.c b/src/login/HPMlogin.c
index b35ac13cb..4f63da6ac 100644
--- a/src/login/HPMlogin.c
+++ b/src/login/HPMlogin.c
@@ -25,9 +25,11 @@
#include "common/cbasetypes.h"
#include "login/account.h"
+#include "login/ipban.h"
#include "login/lclif.h"
#include "login/lclif.p.h"
#include "login/login.h"
+#include "login/loginlog.h"
#include "common/HPMi.h"
#include "common/conf.h"
#include "common/console.h"
@@ -69,7 +71,7 @@ bool HPM_login_data_store_validate(enum HPluginDataTypes type, struct hplugin_da
}
void HPM_login_plugin_load_sub(struct hplugin *plugin) {
- plugin->hpi->sql_handle = account_db_sql_up(login->accounts);
+ plugin->hpi->sql_handle = account->db_sql_up(login->accounts);
}
void HPM_login_do_init(void) {
diff --git a/src/login/Makefile.in b/src/login/Makefile.in
index 69cc6a897..d0258deb0 100644
--- a/src/login/Makefile.in
+++ b/src/login/Makefile.in
@@ -40,7 +40,7 @@ MT19937AR_D = $(THIRDPARTY_D)/mt19937ar
MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o
MT19937AR_H = $(MT19937AR_D)/mt19937ar.h
-LOGIN_C = account_sql.c HPMlogin.c ipban_sql.c lclif.c login.c loginlog_sql.c
+LOGIN_C = account.c HPMlogin.c ipban.c lclif.c login.c loginlog.c
LOGIN_OBJ = $(addprefix obj_sql/, $(patsubst %.c,%.o,$(LOGIN_C)))
LOGIN_H = login.h account.h HPMlogin.h ipban.h lclif.h loginlog.h
LOGIN_PH = lclif.p.h
diff --git a/src/login/account_sql.c b/src/login/account.c
index 66ede6cfa..cd480def9 100644
--- a/src/login/account_sql.c
+++ b/src/login/account.c
@@ -39,54 +39,8 @@
/// global defines
#define ACCOUNT_SQL_DB_VERSION 20110114
-/// internal structure
-typedef struct AccountDB_SQL
-{
- AccountDB vtable; // public interface
-
- struct Sql *accounts; // SQL accounts storage
-
- // Sql settings
- char db_hostname[32];
- uint16 db_port;
- char db_username[32];
- char db_password[100];
- char db_database[32];
- char codepage[32];
- // other settings
- bool case_sensitive;
- char account_db[32];
- char global_acc_reg_num_db[32];
- char global_acc_reg_str_db[32];
-
-
-} AccountDB_SQL;
-
-/// internal structure
-typedef struct AccountDBIterator_SQL
-{
- AccountDBIterator vtable; // public interface
-
- AccountDB_SQL* db;
- int last_account_id;
-} AccountDBIterator_SQL;
-
-/// internal functions
-static bool account_db_sql_init(AccountDB* self);
-static void account_db_sql_destroy(AccountDB* self);
-static bool account_db_sql_get_property(AccountDB* self, const char* key, char* buf, size_t buflen);
-static bool account_db_sql_set_property(AccountDB* self, struct config_t *config, bool imported);
-static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc);
-static bool account_db_sql_remove(AccountDB* self, const int account_id);
-static bool account_db_sql_save(AccountDB* self, const struct mmo_account* acc);
-static bool account_db_sql_load_num(AccountDB* self, struct mmo_account* acc, const int account_id);
-static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, const char* userid);
-static AccountDBIterator* account_db_sql_iterator(AccountDB* self);
-static void account_db_sql_iter_destroy(AccountDBIterator* self);
-static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account* acc);
-
-static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id);
-static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new);
+struct account_interface account_s;
+struct account_interface *account;
/// public constructor
AccountDB* account_db_sql(void)
@@ -94,16 +48,16 @@ AccountDB* account_db_sql(void)
AccountDB_SQL* db = (AccountDB_SQL*)aCalloc(1, sizeof(AccountDB_SQL));
// set up the vtable
- db->vtable.init = &account_db_sql_init;
- db->vtable.destroy = &account_db_sql_destroy;
- db->vtable.get_property = &account_db_sql_get_property;
- db->vtable.set_property = &account_db_sql_set_property;
- db->vtable.save = &account_db_sql_save;
- db->vtable.create = &account_db_sql_create;
- db->vtable.remove = &account_db_sql_remove;
- db->vtable.load_num = &account_db_sql_load_num;
- db->vtable.load_str = &account_db_sql_load_str;
- db->vtable.iterator = &account_db_sql_iterator;
+ db->vtable.init = account->db_sql_init;
+ db->vtable.destroy = account->db_sql_destroy;
+ db->vtable.get_property = account->db_sql_get_property;
+ db->vtable.set_property = account->db_sql_set_property;
+ db->vtable.save = account->db_sql_save;
+ db->vtable.create = account->db_sql_create;
+ db->vtable.remove = account->db_sql_remove;
+ db->vtable.load_num = account->db_sql_load_num;
+ db->vtable.load_str = account->db_sql_load_str;
+ db->vtable.iterator = account->db_sql_iterator;
// initialize to default values
db->accounts = NULL;
@@ -123,10 +77,8 @@ AccountDB* account_db_sql(void)
return &db->vtable;
}
-
/* ------------------------------------------------------------------------- */
-
/// establishes database connection
static bool account_db_sql_init(AccountDB* self)
{
@@ -323,7 +275,7 @@ static bool account_db_sql_set_property(AccountDB* self, struct config_t *config
libconfig->setting_lookup_uint16(setting, "db_port", &db->db_port);
libconfig->setting_lookup_bool_real(setting, "case_sensitive", &db->case_sensitive);
- account_db_read_inter(db, "conf/common/inter-server.conf", imported);
+ account->db_read_inter(db, "conf/common/inter-server.conf", imported);
return true;
}
@@ -381,7 +333,7 @@ static bool account_db_sql_create(AccountDB* self, struct mmo_account* acc)
// insert the data into the database
acc->account_id = account_id;
- return mmo_auth_tosql(db, acc, true);
+ return account->mmo_auth_tosql(db, acc, true);
}
/// delete an existing account entry + its regs
@@ -411,14 +363,14 @@ static bool account_db_sql_remove(AccountDB* self, const int account_id)
static bool account_db_sql_save(AccountDB* self, const struct mmo_account* acc)
{
AccountDB_SQL* db = (AccountDB_SQL*)self;
- return mmo_auth_tosql(db, acc, false);
+ return account->mmo_auth_tosql(db, acc, false);
}
/// retrieve data from db and store it in the provided data structure
static bool account_db_sql_load_num(AccountDB* self, struct mmo_account* acc, const int account_id)
{
AccountDB_SQL* db = (AccountDB_SQL*)self;
- return mmo_auth_fromsql(db, acc, account_id);
+ return account->mmo_auth_fromsql(db, acc, account_id);
}
/// retrieve data from db and store it in the provided data structure
@@ -458,7 +410,7 @@ static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, co
SQL->GetData(sql_handle, 0, &data, NULL);
account_id = atoi(data);
- return account_db_sql_load_num(self, acc, account_id);
+ return account->db_sql_load_num(self, acc, account_id);
}
@@ -471,8 +423,8 @@ static AccountDBIterator* account_db_sql_iterator(AccountDB* self)
nullpo_retr(NULL, db);
iter = (AccountDBIterator_SQL*)aCalloc(1, sizeof(AccountDBIterator_SQL));
// set up the vtable
- iter->vtable.destroy = &account_db_sql_iter_destroy;
- iter->vtable.next = &account_db_sql_iter_next;
+ iter->vtable.destroy = account->db_sql_iter_destroy;
+ iter->vtable.next = account->db_sql_iter_next;
// fill data
iter->db = db;
@@ -516,8 +468,7 @@ static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account
{// get account data
int account_id;
account_id = atoi(data);
- if( mmo_auth_fromsql(db, acc, account_id) )
- {
+ if (account->mmo_auth_fromsql(db, acc, account_id)) {
iter->last_account_id = account_id;
SQL->FreeResult(sql_handle);
return true;
@@ -528,7 +479,7 @@ static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account
}
-static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id)
+static bool account_mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int account_id)
{
struct Sql *sql_handle;
char* data;
@@ -573,7 +524,7 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
return true;
}
-static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new)
+static bool account_mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new)
{
struct Sql *sql_handle;
struct SqlStmt *stmt;
@@ -673,7 +624,8 @@ struct Sql *account_db_sql_up(AccountDB* self)
AccountDB_SQL* db = (AccountDB_SQL*)self;
return db ? db->accounts : NULL;
}
-void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id)
+
+void account_mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id)
{
struct Sql *sql_handle;
AccountDB_SQL* db = (AccountDB_SQL*)self;
@@ -725,7 +677,7 @@ void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id)
}
}
-void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id)
+void account_mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id)
{
struct Sql *sql_handle;
AccountDB_SQL* db = (AccountDB_SQL*)self;
@@ -869,3 +821,28 @@ void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id)
SQL->FreeResult(sql_handle);
}
+
+void account_defaults(void) {
+ account = &account_s;
+
+ account->db_sql_up = account_db_sql_up;
+ account->mmo_send_accreg2 = account_mmo_send_accreg2;
+ account->mmo_save_accreg2 = account_mmo_save_accreg2;
+ account->mmo_auth_fromsql = account_mmo_auth_fromsql;
+ account->mmo_auth_tosql = account_mmo_auth_tosql;
+
+ account->db_sql = account_db_sql;
+ account->db_sql_init = account_db_sql_init;
+ account->db_sql_destroy = account_db_sql_destroy;
+ account->db_sql_get_property = account_db_sql_get_property;
+ account->db_sql_set_property = account_db_sql_set_property;
+ account->db_sql_create = account_db_sql_create;
+ account->db_sql_remove = account_db_sql_remove;
+ account->db_sql_save = account_db_sql_save;
+ account->db_sql_load_num = account_db_sql_load_num;
+ account->db_sql_load_str = account_db_sql_load_str;
+ account->db_sql_iterator = account_db_sql_iterator;
+ account->db_sql_iter_destroy = account_db_sql_iter_destroy;
+ account->db_sql_iter_next = account_db_sql_iter_next;
+ account->db_read_inter = account_db_read_inter;
+}
diff --git a/src/login/account.h b/src/login/account.h
index 9bb07fda3..8199ce3ba 100644
--- a/src/login/account.h
+++ b/src/login/account.h
@@ -33,12 +33,6 @@ struct config_t; // common/conf.h
typedef struct AccountDB AccountDB;
typedef struct AccountDBIterator AccountDBIterator;
-
-#ifdef HERCULES_CORE
-// standard engines
-AccountDB* account_db_sql(void);
-#endif // HERCULES_CORE
-
struct mmo_account
{
int account_id;
@@ -59,7 +53,6 @@ struct mmo_account
char birthdate[10+1]; // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00)
};
-
struct AccountDBIterator
{
/// Destroys this iterator, releasing all allocated memory (including itself).
@@ -161,11 +154,66 @@ struct AccountDB
AccountDBIterator* (*iterator)(AccountDB* self);
};
-#ifdef HERCULES_CORE
-struct Sql *account_db_sql_up(AccountDB* self);
+typedef struct AccountDB_SQL
+{
+ AccountDB vtable; // public interface
+
+ struct Sql *accounts; // SQL accounts storage
+
+ // Sql settings
+ char db_hostname[32];
+ uint16 db_port;
+ char db_username[32];
+ char db_password[100];
+ char db_database[32];
+ char codepage[32];
+ // other settings
+ bool case_sensitive;
+ char account_db[32];
+ char global_acc_reg_num_db[32];
+ char global_acc_reg_str_db[32];
+} AccountDB_SQL;
+
+/// internal structure
+typedef struct AccountDBIterator_SQL
+{
+ AccountDBIterator vtable; // public interface
+
+ AccountDB_SQL* db;
+ int last_account_id;
+} AccountDBIterator_SQL;
-void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id);
-void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id);
+/**
+ * Account.c Interface
+ **/
+struct account_interface {
+ struct Sql* (*db_sql_up) (AccountDB* self);
+ void (*mmo_send_accreg2) (AccountDB* self, int fd, int account_id, int char_id);
+ void (*mmo_save_accreg2) (AccountDB* self, int fd, int account_id, int char_id);
+ bool (*mmo_auth_fromsql) (AccountDB_SQL* db, struct mmo_account* acc, int account_id);
+ bool (*mmo_auth_tosql) (AccountDB_SQL* db, const struct mmo_account* acc, bool is_new);
+
+ AccountDB* (*db_sql) (void);
+ bool (*db_sql_init) (AccountDB* self);
+ void (*db_sql_destroy) (AccountDB* self);
+ bool (*db_sql_get_property) (AccountDB* self, const char* key, char* buf, size_t buflen);
+ bool (*db_sql_set_property) (AccountDB* self, struct config_t *config, bool imported);
+ bool (*db_sql_create) (AccountDB* self, struct mmo_account* acc);
+ bool (*db_sql_remove) (AccountDB* self, const int account_id);
+ bool (*db_sql_save) (AccountDB* self, const struct mmo_account* acc);
+ bool (*db_sql_load_num) (AccountDB* self, struct mmo_account* acc, const int account_id);
+ bool (*db_sql_load_str) (AccountDB* self, struct mmo_account* acc, const char* userid);
+ AccountDBIterator* (*db_sql_iterator) (AccountDB* self);
+ void (*db_sql_iter_destroy) (AccountDBIterator* self);
+ bool (*db_sql_iter_next) (AccountDBIterator* self, struct mmo_account* acc);
+
+ bool (*db_read_inter) (AccountDB_SQL *db, const char *filename, bool imported);
+};
+
+#ifdef HERCULES_CORE
+void account_defaults(void);
#endif // HERCULES_CORE
+HPShared struct account_interface *account;
+
#endif /* LOGIN_ACCOUNT_H */
diff --git a/src/login/ipban_sql.c b/src/login/ipban.c
index d74e6c4fa..60a90fec9 100644
--- a/src/login/ipban_sql.c
+++ b/src/login/ipban.c
@@ -34,49 +34,36 @@
#include <stdlib.h>
-// Sql settings
-static char ipban_db_hostname[32] = "127.0.0.1";
-static uint16 ipban_db_port = 3306;
-static char ipban_db_username[32] = "ragnarok";
-static char ipban_db_password[100] = "ragnarok";
-static char ipban_db_database[32] = "ragnarok";
-static char ipban_codepage[32] = "";
-static char ipban_table[32] = "ipbanlist";
-
-// globals
-static struct Sql *sql_handle = NULL;
-static int cleanup_timer_id = INVALID_TIMER;
-static bool ipban_inited = false;
-
-int ipban_cleanup(int tid, int64 tick, int id, intptr_t data);
-
+struct ipban_interface ipban_s;
+struct ipban_interface *ipban;
+struct s_ipban_dbs ipbandbs;
// initialize
void ipban_init(void)
{
- ipban_inited = true;
+ ipban->inited = true;
if (!login->config->ipban)
return;// ipban disabled
// establish connections
- sql_handle = SQL->Malloc();
- if (SQL_ERROR == SQL->Connect(sql_handle, ipban_db_username, ipban_db_password,
- ipban_db_hostname, ipban_db_port, ipban_db_database)) {
- Sql_ShowDebug(sql_handle);
- SQL->Free(sql_handle);
+ ipban->sql_handle = SQL->Malloc();
+ if (SQL_ERROR == SQL->Connect(ipban->sql_handle, ipban->dbs->db_username, ipban->dbs->db_password,
+ ipban->dbs->db_hostname, ipban->dbs->db_port, ipban->dbs->db_database)) {
+ Sql_ShowDebug(ipban->sql_handle);
+ SQL->Free(ipban->sql_handle);
exit(EXIT_FAILURE);
}
- if (ipban_codepage[0] != '\0' && SQL_ERROR == SQL->SetEncoding(sql_handle, ipban_codepage))
- Sql_ShowDebug(sql_handle);
+ if (ipban->dbs->codepage[0] != '\0' && SQL_ERROR == SQL->SetEncoding(ipban->sql_handle, ipban->dbs->codepage))
+ Sql_ShowDebug(ipban->sql_handle);
if (login->config->ipban_cleanup_interval > 0) {
// set up periodic cleanup of connection history and active bans
- timer->add_func_list(ipban_cleanup, "ipban_cleanup");
- cleanup_timer_id = timer->add_interval(timer->gettick()+10, ipban_cleanup, 0, 0, login->config->ipban_cleanup_interval*1000);
+ timer->add_func_list(ipban->cleanup, "ipban_cleanup");
+ ipban->cleanup_timer_id = timer->add_interval(timer->gettick()+10, ipban->cleanup, 0, 0, login->config->ipban_cleanup_interval*1000);
} else {
// make sure it gets cleaned up on login-server start regardless of interval-based cleanups
- ipban_cleanup(0,0,0,0);
+ ipban->cleanup(0,0,0,0);
}
}
@@ -88,13 +75,13 @@ void ipban_final(void)
if (login->config->ipban_cleanup_interval > 0)
// release data
- timer->delete(cleanup_timer_id, ipban_cleanup);
+ timer->delete(ipban->cleanup_timer_id, ipban->cleanup);
- ipban_cleanup(0,0,0,0); // always clean up on login-server stop
+ ipban->cleanup(0,0,0,0); // always clean up on login-server stop
// close connections
- SQL->Free(sql_handle);
- sql_handle = NULL;
+ SQL->Free(ipban->sql_handle);
+ ipban->sql_handle = NULL;
}
/**
@@ -126,14 +113,14 @@ bool ipban_config_read_inter(const char *filename, bool imported)
ShowError("ipban_config_read: inter_configuration/database_names was not found!\n");
return false;
}
- libconfig->setting_lookup_mutable_string(setting, "ipban_table", ipban_table, sizeof(ipban_table));
+ libconfig->setting_lookup_mutable_string(setting, "ipban_table", ipban->dbs->table, sizeof(ipban->dbs->table));
// import should overwrite any previous configuration, so it should be called last
if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
if (strcmp(import, filename) == 0 || strcmp(import, "conf/common/inter-server.conf") == 0) {
ShowWarning("ipban_config_read_inter: Loop detected! Skipping 'import'...\n");
} else {
- if (!ipban_config_read_inter(import, true))
+ if (!ipban->config_read_inter(import, true))
retval = false;
}
}
@@ -165,13 +152,13 @@ bool ipban_config_read_connection(const char *filename, struct config_t *config,
return false;
}
- libconfig->setting_lookup_mutable_string(setting, "db_hostname", ipban_db_hostname, sizeof(ipban_db_hostname));
- libconfig->setting_lookup_mutable_string(setting, "db_database", ipban_db_database, sizeof(ipban_db_database));
+ libconfig->setting_lookup_mutable_string(setting, "db_hostname", ipban->dbs->db_hostname, sizeof(ipban->dbs->db_hostname));
+ libconfig->setting_lookup_mutable_string(setting, "db_database", ipban->dbs->db_database, sizeof(ipban->dbs->db_database));
- libconfig->setting_lookup_mutable_string(setting, "db_username", ipban_db_username, sizeof(ipban_db_username));
- libconfig->setting_lookup_mutable_string(setting, "db_password", ipban_db_password, sizeof(ipban_db_password));
- libconfig->setting_lookup_mutable_string(setting, "codepage", ipban_codepage, sizeof(ipban_codepage));
- libconfig->setting_lookup_uint16(setting, "db_port", &ipban_db_port);
+ libconfig->setting_lookup_mutable_string(setting, "db_username", ipban->dbs->db_username, sizeof(ipban->dbs->db_username));
+ libconfig->setting_lookup_mutable_string(setting, "db_password", ipban->dbs->db_password, sizeof(ipban->dbs->db_password));
+ libconfig->setting_lookup_mutable_string(setting, "codepage", ipban->dbs->codepage, sizeof(ipban->dbs->codepage));
+ libconfig->setting_lookup_uint16(setting, "db_port", &ipban->dbs->db_port);
return true;
}
@@ -224,7 +211,7 @@ bool ipban_config_read(const char *filename, struct config_t *config, bool impor
nullpo_retr(false, filename);
nullpo_retr(false, config);
- if (ipban_inited)
+ if (ipban->inited)
return false; // settings can only be changed before init
if ((setting = libconfig->lookup(config, "login_configuration/account/ipban")) == NULL) {
@@ -256,20 +243,20 @@ bool ipban_check(uint32 ip)
if (!login->config->ipban)
return false;// ipban disabled
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `rtime` > NOW() AND (`list` = '%u.*.*.*' OR `list` = '%u.%u.*.*' OR `list` = '%u.%u.%u.*' OR `list` = '%u.%u.%u.%u')",
- ipban_table, p[3], p[3], p[2], p[3], p[2], p[1], p[3], p[2], p[1], p[0]) )
+ if( SQL_ERROR == SQL->Query(ipban->sql_handle, "SELECT count(*) FROM `%s` WHERE `rtime` > NOW() AND (`list` = '%u.*.*.*' OR `list` = '%u.%u.*.*' OR `list` = '%u.%u.%u.*' OR `list` = '%u.%u.%u.%u')",
+ ipban->dbs->table, p[3], p[3], p[2], p[3], p[2], p[1], p[3], p[2], p[1], p[0]) )
{
- Sql_ShowDebug(sql_handle);
+ Sql_ShowDebug(ipban->sql_handle);
// close connection because we can't verify their connectivity.
return true;
}
- if( SQL_SUCCESS != SQL->NextRow(sql_handle) )
+ if( SQL_SUCCESS != SQL->NextRow(ipban->sql_handle) )
return false;
- SQL->GetData(sql_handle, 0, &data, NULL);
+ SQL->GetData(ipban->sql_handle, 0, &data, NULL);
matches = atoi(data);
- SQL->FreeResult(sql_handle);
+ SQL->FreeResult(ipban->sql_handle);
return( matches > 0 );
}
@@ -282,16 +269,16 @@ void ipban_log(uint32 ip)
if (!login->config->ipban)
return;// ipban disabled
- failures = loginlog_failedattempts(ip, login->config->dynamic_pass_failure_ban_interval);// how many times failed account? in one ip.
+ failures = loginlog->failedattempts(ip, login->config->dynamic_pass_failure_ban_interval);// how many times failed account? in one ip.
// if over the limit, add a temporary ban entry
if (failures >= login->config->dynamic_pass_failure_ban_limit)
{
uint8* p = (uint8*)&ip;
- if (SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s`(`list`,`btime`,`rtime`,`reason`) VALUES ('%u.%u.%u.*', NOW() , NOW() + INTERVAL %u MINUTE ,'Password error ban')",
- ipban_table, p[3], p[2], p[1], login->config->dynamic_pass_failure_ban_duration))
+ if (SQL_ERROR == SQL->Query(ipban->sql_handle, "INSERT INTO `%s`(`list`,`btime`,`rtime`,`reason`) VALUES ('%u.%u.%u.*', NOW() , NOW() + INTERVAL %u MINUTE ,'Password error ban')",
+ ipban->dbs->table, p[3], p[2], p[1], login->config->dynamic_pass_failure_ban_duration))
{
- Sql_ShowDebug(sql_handle);
+ Sql_ShowDebug(ipban->sql_handle);
}
}
}
@@ -301,8 +288,37 @@ int ipban_cleanup(int tid, int64 tick, int id, intptr_t data) {
if (!login->config->ipban)
return 0;// ipban disabled
- if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `rtime` <= NOW()", ipban_table) )
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == SQL->Query(ipban->sql_handle, "DELETE FROM `%s` WHERE `rtime` <= NOW()", ipban->dbs->table) )
+ Sql_ShowDebug(ipban->sql_handle);
return 0;
}
+
+void ipban_defaults(void) {
+ ipban = &ipban_s;
+
+ ipban->dbs = &ipbandbs;
+
+ ipban->sql_handle = NULL;
+ ipban->cleanup_timer_id = INVALID_TIMER;
+ ipban->inited = false;
+
+ // Sql settings
+ strcpy(ipban->dbs->db_hostname, "127.0.0.1");
+ ipban->dbs->db_port = 3306;
+ strcpy(ipban->dbs->db_username, "ragnarok");
+ strcpy(ipban->dbs->db_password, "ragnarok");
+ strcpy(ipban->dbs->db_database, "ragnarok");
+ *ipban->dbs->codepage = 0;
+ strcpy(ipban->dbs->table, "ipbanlist");
+
+ ipban->init = ipban_init;
+ ipban->final = ipban_final;
+ ipban->cleanup = ipban_cleanup;
+ ipban->config_read_inter = ipban_config_read_inter;
+ ipban->config_read_connection = ipban_config_read_connection;
+ ipban->config_read_dynamic = ipban_config_read_dynamic;
+ ipban->config_read = ipban_config_read;
+ ipban->check = ipban_check;
+ ipban->log = ipban_log;
+}
diff --git a/src/login/ipban.h b/src/login/ipban.h
index 104e3a8a3..29aafba9d 100644
--- a/src/login/ipban.h
+++ b/src/login/ipban.h
@@ -22,26 +22,44 @@
#define LOGIN_IPBAN_H
#include "common/cbasetypes.h"
+#include "common/hercules.h"
/* Forward Declarations */
struct config_t; // common/conf.h
-#ifdef HERCULES_CORE
-// TODO: Interface
-// initialize
-void ipban_init(void);
-
-// finalize
-void ipban_final(void);
-
-// check ip against ban list
-bool ipban_check(uint32 ip);
+struct s_ipban_dbs {
+ char db_hostname[32];
+ uint16 db_port;
+ char db_username[32];
+ char db_password[100];
+ char db_database[32];
+ char codepage[32];
+ char table[32];
+};
-// increases failure count for the specified IP
-void ipban_log(uint32 ip);
+/**
+ * Ipban.c Interface
+ **/
+struct ipban_interface {
+ struct s_ipban_dbs *dbs;
+ struct Sql *sql_handle;
+ int cleanup_timer_id;
+ bool inited;
+ void (*init) (void);
+ void (*final) (void);
+ int (*cleanup) (int tid, int64 tick, int id, intptr_t data);
+ bool (*config_read_inter) (const char *filename, bool imported);
+ bool (*config_read_connection) (const char *filename, struct config_t *config, bool imported);
+ bool (*config_read_dynamic) (const char *filename, struct config_t *config, bool imported);
+ bool (*config_read) (const char *filename, struct config_t *config, bool imported);
+ bool (*check) (uint32 ip);
+ void (*log) (uint32 ip);
+};
-// parses configuration options
-bool ipban_config_read(const char *filename, struct config_t *config, bool imported);
+#ifdef HERCULES_CORE
+void ipban_defaults(void);
#endif // HERCULES_CORE
+HPShared struct ipban_interface *ipban;
+
#endif /* LOGIN_IPBAN_H */
diff --git a/src/login/lclif.c b/src/login/lclif.c
index 1870f9bc9..ae9f035e3 100644
--- a/src/login/lclif.c
+++ b/src/login/lclif.c
@@ -257,8 +257,8 @@ bool lclif_send_server_list(struct login_session_data *sd)
uint32 ip;
struct packet_AC_ACCEPT_LOGIN *packet = NULL;
- for (i = 0; i < ARRAYLENGTH(server); ++i) {
- if (sockt->session_is_active(server[i].fd))
+ for (i = 0; i < ARRAYLENGTH(login->dbs->server); ++i) {
+ if (sockt->session_is_active(login->dbs->server[i].fd))
server_num++;
}
if (server_num == 0)
@@ -283,24 +283,24 @@ bool lclif_send_server_list(struct login_session_data *sd)
packet->last_login_ip = 0; // Not used anymore
memset(packet->last_login_time, '\0', sizeof(packet->last_login_time)); // Not used anymore
packet->sex = sex_str2num(sd->sex);
- for (i = 0, n = 0; i < ARRAYLENGTH(server); ++i) {
+ for (i = 0, n = 0; i < ARRAYLENGTH(login->dbs->server); ++i) {
uint32 subnet_char_ip;
- if (!sockt->session_is_valid(server[i].fd))
+ if (!sockt->session_is_valid(login->dbs->server[i].fd))
continue;
subnet_char_ip = login->lan_subnet_check(ip);
- packet->server_list[n].ip = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
- packet->server_list[n].port = sockt->ntows(htons(server[i].port)); // [!] LE byte order here [!]
- safestrncpy(packet->server_list[n].name, server[i].name, 20);
- packet->server_list[n].usercount = login->convert_users_to_colors(server[i].users);
+ packet->server_list[n].ip = htonl((subnet_char_ip) ? subnet_char_ip : login->dbs->server[i].ip);
+ packet->server_list[n].port = sockt->ntows(htons(login->dbs->server[i].port)); // [!] LE byte order here [!]
+ safestrncpy(packet->server_list[n].name, login->dbs->server[i].name, 20);
+ packet->server_list[n].usercount = login->convert_users_to_colors(login->dbs->server[i].users);
- if (server[i].type == CST_PAYING && sd->expiration_time > time(NULL))
+ if (login->dbs->server[i].type == CST_PAYING && sd->expiration_time > time(NULL))
packet->server_list[n].property = CST_NORMAL;
else
- packet->server_list[n].property = server[i].type;
+ packet->server_list[n].property = login->dbs->server[i].type;
- packet->server_list[n].state = server[i].new_;
+ packet->server_list[n].state = login->dbs->server[i].new_;
++n;
}
WFIFOSET(sd->fd, length);
@@ -373,9 +373,9 @@ int lclif_parse(int fd)
if ((sd = sockt->session[fd]->session_data) == NULL) {
// Perform ip-ban check
- if (login->config->ipban && !sockt->trusted_ip_check(ipl) && ipban_check(ipl)) {
+ if (login->config->ipban && !sockt->trusted_ip_check(ipl) && ipban->check(ipl)) {
ShowStatus("Connection refused: IP isn't authorized (deny/allow, ip: %s).\n", ip);
- login_log(ipl, "unknown", -3, "ip banned");
+ loginlog->log(ipl, "unknown", -3, "ip banned");
lclif->login_error(fd, 3); // 3 = Rejected from Server
sockt->eof(fd);
return 0;
diff --git a/src/login/lclif.p.h b/src/login/lclif.p.h
index 024280b37..5c5c062d3 100644
--- a/src/login/lclif.p.h
+++ b/src/login/lclif.p.h
@@ -122,7 +122,7 @@ struct packet_CA_LOGIN4 {
*/
struct packet_CA_LOGIN_PCBANG {
int16 packet_id; ///< Packet ID (#PACKET_ID_CA_LOGIN_PCBANG)
- uint32 version; ///< Client Version
+ uint32 version; ///< Client Version
char id[24]; ///< Username
char password[24]; ///< Password
uint8 clienttype; ///< Client Type
diff --git a/src/login/login.c b/src/login/login.c
index a78276051..9fe9de0d3 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -52,12 +52,12 @@
struct login_interface login_s;
struct login_interface *login;
+struct s_login_dbs logindbs;
+struct lchrif_interface lchrif_s;
+struct lchrif_interface *lchrif;
struct Login_Config login_config_;
-struct mmo_char_server server[MAX_SERVERS]; // char server data
-struct Account_engine account_engine[] = {
- {account_db_sql, NULL}
-};
+struct Account_engine account_engine;
// account database
AccountDB* accounts = NULL;
@@ -164,9 +164,9 @@ int charif_sendallwos(int sfd, uint8* buf, size_t len)
int i, c;
nullpo_ret(buf);
- for( i = 0, c = 0; i < ARRAYLENGTH(server); ++i )
+ for (i = 0, c = 0; i < ARRAYLENGTH(login->dbs->server); ++i)
{
- int fd = server[i].fd;
+ int fd = login->dbs->server[i].fd;
if (sockt->session_is_valid(fd) && fd != sfd) {
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
@@ -180,41 +180,41 @@ int charif_sendallwos(int sfd, uint8* buf, size_t len)
/// Initializes a server structure.
-void chrif_server_init(int id)
+void lchrif_server_init(int id)
{
Assert_retv(id >= 0 && id < MAX_SERVERS);
- memset(&server[id], 0, sizeof(server[id]));
- server[id].fd = -1;
+ memset(&login->dbs->server[id], 0, sizeof(login->dbs->server[id]));
+ login->dbs->server[id].fd = -1;
}
/// Destroys a server structure.
-void chrif_server_destroy(int id)
+void lchrif_server_destroy(int id)
{
Assert_retv(id >= 0 && id < MAX_SERVERS);
- if (server[id].fd != -1)
+ if (login->dbs->server[id].fd != -1)
{
- sockt->close(server[id].fd);
- server[id].fd = -1;
+ sockt->close(login->dbs->server[id].fd);
+ login->dbs->server[id].fd = -1;
}
}
/// Resets all the data related to a server.
-void chrif_server_reset(int id)
+void lchrif_server_reset(int id)
{
login->online_db->foreach(login->online_db, login->online_db_setoffline, id); //Set all chars from this char server to offline.
- chrif_server_destroy(id);
- chrif_server_init(id);
+ lchrif->server_destroy(id);
+ lchrif->server_init(id);
}
/// Called when the connection to Char Server is disconnected.
-void chrif_on_disconnect(int id)
+void lchrif_on_disconnect(int id)
{
Assert_retv(id >= 0 && id < MAX_SERVERS);
- ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
- chrif_server_reset(id);
+ ShowStatus("Char-server '%s' has disconnected.\n", login->dbs->server[id].name);
+ lchrif->server_reset(id);
}
@@ -324,7 +324,7 @@ void login_fromchar_parse_auth(int fd, int id, const char *const ip)
node->sex == sex_num2str(sex) /*&&
node->ip == ip_*/ )
{// found
- //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
+ //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", login->dbs->server[id].name, account_id, ip);
// send ack
login->fromchar_auth_ack(fd, account_id, login_id1, login_id2, sex, request_id, node);
@@ -334,7 +334,7 @@ void login_fromchar_parse_auth(int fd, int id, const char *const ip)
else
{// authentication not found
nullpo_retv(ip);
- ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
+ ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", login->dbs->server[id].name, account_id, ip);
login->fromchar_auth_ack(fd, account_id, login_id1, login_id2, sex, request_id, NULL);
}
}
@@ -345,11 +345,11 @@ void login_fromchar_parse_update_users(int fd, int id)
RFIFOSKIP(fd,6);
// how many users on world? (update)
- if( server[id].users != users )
+ if (login->dbs->server[id].users != users)
{
- ShowStatus("set users %s : %d\n", server[id].name, users);
+ ShowStatus("set users %s : %d\n", login->dbs->server[id].name, users);
- server[id].users = (uint16)users;
+ login->dbs->server[id].users = (uint16)users;
}
}
@@ -363,13 +363,13 @@ void login_fromchar_parse_request_change_email(int fd, int id, const char *const
RFIFOSKIP(fd,46);
if( e_mail_check(email) == 0 )
- ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n", login->dbs->server[id].name, account_id, ip);
else
if( !accounts->load_num(accounts, &acc, account_id) || strcmp(acc.email, "a@a.com") == 0 || acc.email[0] == '\0' )
- ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
else {
memcpy(acc.email, email, sizeof(acc.email));
- ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, account_id, email, ip);
+ ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", login->dbs->server[id].name, account_id, email, ip);
// Save
accounts->save(accounts, &acc);
}
@@ -428,7 +428,7 @@ void login_fromchar_parse_account_data(int fd, int id, const char *const ip)
if( !accounts->load_num(accounts, &acc, account_id) )
{
- ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", login->dbs->server[id].name, account_id, ip);
login->fromchar_account(fd, account_id, NULL);
}
else {
@@ -461,22 +461,22 @@ void login_fromchar_parse_change_email(int fd, int id, const char *const ip)
RFIFOSKIP(fd, 86);
if( e_mail_check(actual_email) == 0 )
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", login->dbs->server[id].name, account_id, ip);
else
if( e_mail_check(new_email) == 0 )
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n", login->dbs->server[id].name, account_id, ip);
else
if( strcmpi(new_email, "a@a.com") == 0 )
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", login->dbs->server[id].name, account_id, ip);
else
if( !accounts->load_num(accounts, &acc, account_id) )
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
else
if( strcmpi(acc.email, actual_email) != 0 )
- ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", login->dbs->server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
else {
safestrncpy(acc.email, new_email, sizeof(acc.email));
- ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, new_email, ip);
+ ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", login->dbs->server[id].name, account_id, acc.userid, new_email, ip);
// Save
accounts->save(accounts, &acc);
}
@@ -501,12 +501,12 @@ void login_fromchar_parse_account_update(int fd, int id, const char *const ip)
RFIFOSKIP(fd,10);
if( !accounts->load_num(accounts, &acc, account_id) )
- ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %u, ip: %s).\n", server[id].name, account_id, state, ip);
+ ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %u, ip: %s).\n", login->dbs->server[id].name, account_id, state, ip);
else
if( acc.state == state )
- ShowNotice("Char-server '%s': Error of Status change - actual status is already the good status (account: %d, status %u, ip: %s).\n", server[id].name, account_id, state, ip);
+ ShowNotice("Char-server '%s': Error of Status change - actual status is already the good status (account: %d, status %u, ip: %s).\n", login->dbs->server[id].name, account_id, state, ip);
else {
- ShowNotice("Char-server '%s': Status change (account: %d, new status %u, ip: %s).\n", server[id].name, account_id, state, ip);
+ ShowNotice("Char-server '%s': Status change (account: %d, new status %u, ip: %s).\n", login->dbs->server[id].name, account_id, state, ip);
acc.state = state;
// Save
@@ -543,7 +543,7 @@ void login_fromchar_parse_ban(int fd, int id, const char *const ip)
RFIFOSKIP(fd,18);
if (!accounts->load_num(accounts, &acc, account_id)) {
- ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
} else {
time_t timestamp;
struct tm *tmtime;
@@ -560,14 +560,14 @@ void login_fromchar_parse_ban(int fd, int id, const char *const ip)
tmtime->tm_sec += sec;
timestamp = mktime(tmtime);
if (timestamp == -1) {
- ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
} else if( timestamp <= time(NULL) || timestamp == 0 ) {
- ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
} else {
char tmpstr[24];
timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login->config->date_format);
ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %ld (%s), ip: %s).\n",
- server[id].name, account_id, (long)timestamp, tmpstr, ip);
+ login->dbs->server[id].name, account_id, (long)timestamp, tmpstr, ip);
acc.unban_time = timestamp;
@@ -596,15 +596,15 @@ void login_fromchar_parse_change_sex(int fd, int id, const char *const ip)
RFIFOSKIP(fd,6);
if( !accounts->load_num(accounts, &acc, account_id) )
- ShowNotice("Char-server '%s': Error of sex change (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Error of sex change (account: %d not found, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
else
if( acc.sex == 'S' )
- ShowNotice("Char-server '%s': Error of sex change - account to change is a Server account (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Error of sex change - account to change is a Server account (account: %d, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
else
{
char sex = ( acc.sex == 'M' ) ? 'F' : 'M'; //Change gender
- ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", server[id].name, account_id, sex, ip);
+ ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", login->dbs->server[id].name, account_id, sex, ip);
acc.sex = sex;
// Save
@@ -622,9 +622,9 @@ void login_fromchar_parse_account_reg2(int fd, int id, const char *const ip)
int account_id = RFIFOL(fd,4);
if( !accounts->load_num(accounts, &acc, account_id) )
- ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+ ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
else {
- mmo_save_accreg2(accounts,fd,account_id,RFIFOL(fd, 8));
+ account->mmo_save_accreg2(accounts,fd,account_id,RFIFOL(fd, 8));
}
RFIFOSKIP(fd,RFIFOW(fd,2));
}
@@ -637,13 +637,13 @@ void login_fromchar_parse_unban(int fd, int id, const char *const ip)
RFIFOSKIP(fd,6);
if( !accounts->load_num(accounts, &acc, account_id) )
- ShowNotice("Char-server '%s': Error of Unban request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Error of Unban request (account: %d not found, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
else
if( acc.unban_time == 0 )
- ShowNotice("Char-server '%s': Error of Unban request (account: %d, no change for unban date, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Error of Unban request (account: %d, no change for unban date, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
else
{
- ShowNotice("Char-server '%s': Unban request (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+ ShowNotice("Char-server '%s': Unban request (account: %d, ip: %s).\n", login->dbs->server[id].name, account_id, ip);
acc.unban_time = 0;
accounts->save(accounts, &acc);
}
@@ -684,13 +684,13 @@ void login_fromchar_parse_request_account_reg2(int fd)
int char_id = RFIFOL(fd,6);
RFIFOSKIP(fd,10);
- mmo_send_accreg2(accounts,fd,account_id,char_id);
+ account->mmo_send_accreg2(accounts,fd,account_id,char_id);
}
void login_fromchar_parse_update_wan_ip(int fd, int id)
{
- server[id].ip = ntohl(RFIFOL(fd,2));
- ShowInfo("Updated IP of Server #%d to %u.%u.%u.%u.\n",id, CONVIP(server[id].ip));
+ login->dbs->server[id].ip = ntohl(RFIFOL(fd,2));
+ ShowInfo("Updated IP of Server #%d to %u.%u.%u.%u.\n",id, CONVIP(login->dbs->server[id].ip));
RFIFOSKIP(fd,6);
}
@@ -725,7 +725,7 @@ bool login_fromchar_parse_wrong_pincode(int fd)
return true;
}
- login_log(sockt->host2ip(acc.last_ip), acc.userid, 100, "PIN Code check failed"); // FIXME: Do we really want to log this with the same code as successful logins?
+ loginlog->log(sockt->host2ip(acc.last_ip), acc.userid, 100, "PIN Code check failed"); // FIXME: Do we really want to log this with the same code as successful logins?
}
login->remove_online_user(acc.account_id);
@@ -794,8 +794,8 @@ int login_parse_fromchar(int fd)
uint32 ipl;
char ip[16];
- ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
- if( id == ARRAYLENGTH(server) )
+ ARR_FIND(0, ARRAYLENGTH(login->dbs->server), id, login->dbs->server[id].fd == fd);
+ if (id == ARRAYLENGTH(login->dbs->server))
{// not a char server
ShowDebug("login_parse_fromchar: Disconnecting invalid session #%d (is not a char-server)\n", fd);
sockt->eof(fd);
@@ -806,12 +806,12 @@ int login_parse_fromchar(int fd)
if( sockt->session[fd]->flag.eof )
{
sockt->close(fd);
- server[id].fd = -1;
- chrif_on_disconnect(id);
+ login->dbs->server[id].fd = -1;
+ lchrif->on_disconnect(id);
return 0;
}
- ipl = server[id].ip;
+ ipl = login->dbs->server[id].ip;
sockt->ip2str(ipl, ip);
while (RFIFOREST(fd) >= 2) {
@@ -1258,7 +1258,7 @@ void login_auth_ok(struct login_session_data* sd)
return;
}
- login_log(ip, sd->userid, 100, "login ok");
+ loginlog->log(ip, sd->userid, 100, "login ok");
ShowStatus("Connection of the account '%s' accepted.\n", sd->userid);
// create temporary auth entry
@@ -1322,11 +1322,11 @@ void login_auth_failed(struct login_session_data *sd, int result)
default : error = "Unknown Error."; break;
}
- login_log(ip, sd->userid, result, error); // FIXME: result can be 100, conflicting with the value 100 we use for successful login...
+ loginlog->log(ip, sd->userid, result, error); // FIXME: result can be 100, conflicting with the value 100 we use for successful login...
}
if (result == 1 && login->config->dynamic_pass_failure_ban && !sockt->trusted_ip_check(ip))
- ipban_log(ip); // log failed password attempt
+ ipban->log(ip); // log failed password attempt
if (result == 6) {
struct mmo_account acc = { 0 };
@@ -1430,25 +1430,25 @@ void login_parse_request_connection(int fd, struct login_session_data* sd, const
ShowInfo("Connection request of the char-server '%s' @ %u.%u.%u.%u:%u (account: '%s', pass: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, sd->userid, sd->passwd, ip);
sprintf(message, "charserver - %s@%u.%u.%u.%u:%u", server_name, CONVIP(server_ip), server_port);
- login_log(sockt->session[fd]->client_addr, sd->userid, 100, message);
+ loginlog->log(sockt->session[fd]->client_addr, sd->userid, 100, message);
result = login->mmo_auth(sd, true);
if (core->runflag == LOGINSERVER_ST_RUNNING &&
result == -1 &&
sd->sex == 'S' &&
sd->account_id >= 0 &&
- sd->account_id < ARRAYLENGTH(server) &&
- !sockt->session_is_valid(server[sd->account_id].fd) &&
+ sd->account_id < ARRAYLENGTH(login->dbs->server) &&
+ !sockt->session_is_valid(login->dbs->server[sd->account_id].fd) &&
sockt->allowed_ip_check(ipl))
{
ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
- safestrncpy(server[sd->account_id].name, server_name, sizeof(server[sd->account_id].name));
- server[sd->account_id].fd = fd;
- server[sd->account_id].ip = server_ip;
- server[sd->account_id].port = server_port;
- server[sd->account_id].users = 0;
- server[sd->account_id].type = type;
- server[sd->account_id].new_ = new_;
+ safestrncpy(login->dbs->server[sd->account_id].name, server_name, sizeof(login->dbs->server[sd->account_id].name));
+ login->dbs->server[sd->account_id].fd = fd;
+ login->dbs->server[sd->account_id].ip = server_ip;
+ login->dbs->server[sd->account_id].port = server_port;
+ login->dbs->server[sd->account_id].users = 0;
+ login->dbs->server[sd->account_id].type = type;
+ login->dbs->server[sd->account_id].new_ = new_;
sockt->session[fd]->func_parse = login->parse_fromchar;
sockt->session[fd]->flag.server = 1;
@@ -1607,7 +1607,7 @@ bool login_config_read_log(const char *filename, struct config_t *config, bool i
bool login_config_read_account(const char *filename, struct config_t *config, bool imported)
{
struct config_setting_t *setting = NULL;
- AccountDB *db = account_engine[0].db;
+ AccountDB *db = login->dbs->account_engine->db;
bool retval = true;
nullpo_retr(false, filename);
@@ -1630,7 +1630,7 @@ bool login_config_read_account(const char *filename, struct config_t *config, bo
if (!db->set_property(db, config, imported))
retval = false;
- if (!ipban_config_read(filename, config, imported))
+ if (!ipban->config_read(filename, config, imported))
retval = false;
return retval;
@@ -1913,7 +1913,7 @@ bool login_config_read(const char *filename, bool imported)
if (!login->config_read_users(filename, &config, imported))
retval = false;
- if (!loginlog_config_read("conf/common/inter-server.conf", imported)) // Only inter-server
+ if (!loginlog->config_read("conf/common/inter-server.conf", imported)) // Only inter-server
retval = false;
if (!HPM->parse_conf(&config, filename, HPCT_LOGIN, imported))
@@ -1973,24 +1973,25 @@ int do_final(void)
login->clear_client_hash_nodes();
login->clear_dnsbl_servers();
- login_log(0, "login server", 100, "login server shutdown");
+ loginlog->log(0, "login server", 100, "login server shutdown");
if (login->config->log_login)
- loginlog_final();
+ loginlog->final();
- ipban_final();
+ ipban->final();
- if( account_engine[0].db )
+ if (login->dbs->account_engine->db)
{// destroy account engine
- account_engine[0].db->destroy(account_engine[0].db);
- account_engine[0].db = NULL;
+ login->dbs->account_engine->db->destroy(login->dbs->account_engine->db);
+ login->dbs->account_engine->db = NULL;
}
- accounts = NULL; // destroyed in account_engine
+ login->accounts = NULL; // destroyed in account_engine
+ accounts = NULL;
login->online_db->destroy(login->online_db, NULL);
login->auth_db->destroy(login->auth_db, NULL);
- for( i = 0; i < ARRAYLENGTH(server); ++i )
- chrif_server_destroy(i);
+ for (i = 0; i < ARRAYLENGTH(login->dbs->server); ++i)
+ lchrif->server_destroy(i);
if( login->fd != -1 )
{
@@ -2033,8 +2034,8 @@ void do_shutdown_login(void)
core->runflag = LOGINSERVER_ST_SHUTDOWN;
ShowStatus("Shutting down...\n");
// TODO proper shutdown procedure; kick all characters, wait for acks, ... [FlavioJS]
- for( id = 0; id < ARRAYLENGTH(server); ++id )
- chrif_server_reset(id);
+ for (id = 0; id < ARRAYLENGTH(login->dbs->server); ++id)
+ lchrif->server_reset(id);
sockt->flush_fifos();
core->runflag = CORE_ST_STOP;
}
@@ -2094,16 +2095,23 @@ int do_init(int argc, char** argv)
{
int i;
+ account_defaults();
+ login_defaults();
+
// initialize engine (to accept config settings)
- account_engine[0].db = account_engine[0].constructor();
- accounts = account_engine[0].db;
+ login->dbs->account_engine->constructor = account->db_sql;
+ login->dbs->account_engine->db = login->dbs->account_engine->constructor();
+ accounts = login->dbs->account_engine->db;
+ login->accounts = accounts;
if( accounts == NULL ) {
ShowFatalError("do_init: account engine 'sql' not found.\n");
exit(EXIT_FAILURE);
}
- login_defaults();
+ ipban_defaults();
+ lchrif_defaults();
lclif_defaults();
+ loginlog_defaults();
// read login-server configuration
login->config_set_defaults();
@@ -2142,15 +2150,15 @@ int do_init(int argc, char** argv)
login->config_read(login->LOGIN_CONF_NAME, false);
sockt->net_config_read(login->NET_CONF_NAME);
- for( i = 0; i < ARRAYLENGTH(server); ++i )
- chrif_server_init(i);
+ for (i = 0; i < ARRAYLENGTH(login->dbs->server); ++i)
+ lchrif->server_init(i);
// initialize logging
if (login->config->log_login)
- loginlog_init();
+ loginlog->init();
// initialize static and dynamic ipban system
- ipban_init();
+ ipban->init();
// Online user database init
login->online_db = idb_alloc(DB_OPT_RELEASE_DATA);
@@ -2196,18 +2204,23 @@ int do_init(int argc, char** argv)
#endif // CONSOLE_INPUT
ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login->config->login_port);
- login_log(0, "login server", 100, "login server started");
+ loginlog->log(0, "login server", 100, "login server started");
HPM->event(HPET_READY);
return 0;
}
-void login_defaults(void) {
+void login_defaults(void)
+{
login = &login_s;
login->config = &login_config_;
login->accounts = accounts;
+ login->dbs = &logindbs;
+ login->dbs->account_engine = &account_engine;
+ login->dbs->account_engine->constructor = NULL;
+ login->dbs->account_engine->db = NULL;
login->mmo_auth = login_mmo_auth;
login->mmo_auth_new = login_mmo_auth_new;
@@ -2279,3 +2292,12 @@ void login_defaults(void) {
login->LOGIN_CONF_NAME = NULL;
login->NET_CONF_NAME = NULL;
}
+
+void lchrif_defaults(void)
+{
+ lchrif = &lchrif_s;
+ lchrif->server_init = lchrif_server_init;
+ lchrif->server_destroy = lchrif_server_destroy;
+ lchrif->server_reset = lchrif_server_reset;
+ lchrif->on_disconnect = lchrif_on_disconnect;
+}
diff --git a/src/login/login.h b/src/login/login.h
index 3af54ef50..1a4a6d0a3 100644
--- a/src/login/login.h
+++ b/src/login/login.h
@@ -157,6 +157,11 @@ struct online_login_data {
#define MAX_SERVERS 30
+struct s_login_dbs {
+ struct mmo_char_server server[MAX_SERVERS];
+ struct Account_engine *account_engine;
+};
+
/**
* Login.c Interface
**/
@@ -166,6 +171,7 @@ struct login_interface {
int fd;
struct Login_Config *config;
struct AccountDB* accounts;
+ struct s_login_dbs *dbs;
int (*mmo_auth) (struct login_session_data* sd, bool isServer);
int (*mmo_auth_new) (const char* userid, const char* pass, const char sex, const char* last_ip);
@@ -234,12 +240,22 @@ struct login_interface {
char *NET_CONF_NAME; ///< Network configuration filename
};
-#ifdef HERCULES_CORE
-extern struct mmo_char_server server[MAX_SERVERS];
+/**
+ * Login.c Interface
+ **/
+struct lchrif_interface {
+ void (*server_init) (int id);
+ void (*server_destroy) (int id);
+ void (*server_reset) (int id);
+ void (*on_disconnect) (int id);
+};
+#ifdef HERCULES_CORE
void login_defaults(void);
+void lchrif_defaults(void);
#endif // HERCULES_CORE
HPShared struct login_interface *login;
+HPShared struct lchrif_interface *lchrif;
#endif /* LOGIN_LOGIN_H */
diff --git a/src/login/loginlog_sql.c b/src/login/loginlog.c
index 7dff14990..0e4cc79f0 100644
--- a/src/login/loginlog_sql.c
+++ b/src/login/loginlog.c
@@ -33,17 +33,10 @@
#include <stdlib.h> // exit
-// Sql settings
-static char log_db_hostname[32] = "127.0.0.1";
-static uint16 log_db_port = 3306;
-static char log_db_username[32] = "ragnarok";
-static char log_db_password[100] = "ragnarok";
-static char log_db_database[32] = "ragnarok";
-static char log_codepage[32] = "";
-static char log_login_db[256] = "loginlog";
-static struct Sql *sql_handle = NULL;
-static bool enabled = false;
+struct loginlog_interface loginlog_s;
+struct loginlog_interface *loginlog;
+struct s_loginlog_dbs loginlogdbs;
// Returns the number of failed login attempts by the ip in the last minutes.
@@ -51,19 +44,19 @@ unsigned long loginlog_failedattempts(uint32 ip, unsigned int minutes)
{
unsigned long failures = 0;
- if( !enabled )
+ if( !loginlog->enabled )
return 0;
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `ip` = '%s' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %u MINUTE",
- log_login_db, sockt->ip2str(ip,NULL), minutes) )// how many times failed account? in one ip.
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == SQL->Query(loginlog->sql_handle, "SELECT count(*) FROM `%s` WHERE `ip` = '%s' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %u MINUTE",
+ loginlog->dbs->log_login_db, sockt->ip2str(ip,NULL), minutes) )// how many times failed account? in one ip.
+ Sql_ShowDebug(loginlog->sql_handle);
- if( SQL_SUCCESS == SQL->NextRow(sql_handle) )
+ if( SQL_SUCCESS == SQL->NextRow(loginlog->sql_handle) )
{
char* data;
- SQL->GetData(sql_handle, 0, &data, NULL);
+ SQL->GetData(loginlog->sql_handle, 0, &data, NULL);
failures = strtoul(data, NULL, 10);
- SQL->FreeResult(sql_handle);
+ SQL->FreeResult(loginlog->sql_handle);
}
return failures;
}
@@ -73,7 +66,7 @@ unsigned long loginlog_failedattempts(uint32 ip, unsigned int minutes)
* Records an event in the login log
*---------------------------------------------*/
// TODO: add an enum of rcode values
-void login_log(uint32 ip, const char* username, int rcode, const char* message)
+void loginlog_log(uint32 ip, const char* username, int rcode, const char* message)
{
char esc_username[NAME_LENGTH*2+1];
char esc_message[255*2+1];
@@ -81,43 +74,43 @@ void login_log(uint32 ip, const char* username, int rcode, const char* message)
nullpo_retv(username);
nullpo_retv(message);
- if( !enabled )
+ if( !loginlog->enabled )
return;
- SQL->EscapeStringLen(sql_handle, esc_username, username, strnlen(username, NAME_LENGTH));
- SQL->EscapeStringLen(sql_handle, esc_message, message, strnlen(message, 255));
+ SQL->EscapeStringLen(loginlog->sql_handle, esc_username, username, strnlen(username, NAME_LENGTH));
+ SQL->EscapeStringLen(loginlog->sql_handle, esc_message, message, strnlen(message, 255));
- retcode = SQL->Query(sql_handle,
+ retcode = SQL->Query(loginlog->sql_handle,
"INSERT INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%s', '%s', '%d', '%s')",
- log_login_db, sockt->ip2str(ip,NULL), esc_username, rcode, esc_message);
+ loginlog->dbs->log_login_db, sockt->ip2str(ip,NULL), esc_username, rcode, esc_message);
if( retcode != SQL_SUCCESS )
- Sql_ShowDebug(sql_handle);
+ Sql_ShowDebug(loginlog->sql_handle);
}
bool loginlog_init(void)
{
- sql_handle = SQL->Malloc();
+ loginlog->sql_handle = SQL->Malloc();
- if (SQL_ERROR == SQL->Connect(sql_handle, log_db_username, log_db_password,
- log_db_hostname, log_db_port, log_db_database)) {
- Sql_ShowDebug(sql_handle);
- SQL->Free(sql_handle);
+ if (SQL_ERROR == SQL->Connect(loginlog->sql_handle, loginlog->dbs->log_db_username, loginlog->dbs->log_db_password,
+ loginlog->dbs->log_db_hostname, loginlog->dbs->log_db_port, loginlog->dbs->log_db_database)) {
+ Sql_ShowDebug(loginlog->sql_handle);
+ SQL->Free(loginlog->sql_handle);
exit(EXIT_FAILURE);
}
- if (log_codepage[0] != '\0' && SQL_ERROR == SQL->SetEncoding(sql_handle, log_codepage))
- Sql_ShowDebug(sql_handle);
+ if (loginlog->dbs->log_codepage[0] != '\0' && SQL_ERROR == SQL->SetEncoding(loginlog->sql_handle, loginlog->dbs->log_codepage))
+ Sql_ShowDebug(loginlog->sql_handle);
- enabled = true;
+ loginlog->enabled = true;
return true;
}
bool loginlog_final(void)
{
- SQL->Free(sql_handle);
- sql_handle = NULL;
+ SQL->Free(loginlog->sql_handle);
+ loginlog->sql_handle = NULL;
return true;
}
@@ -145,7 +138,7 @@ bool loginlog_config_read_names(const char *filename, struct config_t *config, b
return false;
}
- libconfig->setting_lookup_mutable_string(setting, "login_db", log_login_db, sizeof(log_login_db));
+ libconfig->setting_lookup_mutable_string(setting, "login_db", loginlog->dbs->log_login_db, sizeof(loginlog->dbs->log_login_db));
return true;
}
@@ -174,13 +167,13 @@ bool loginlog_config_read_log(const char *filename, struct config_t *config, boo
return false;
}
- libconfig->setting_lookup_mutable_string(setting, "db_hostname", log_db_hostname, sizeof(log_db_hostname));
- libconfig->setting_lookup_mutable_string(setting, "db_database", log_db_database, sizeof(log_db_database));
- libconfig->setting_lookup_mutable_string(setting, "db_username", log_db_username, sizeof(log_db_username));
- libconfig->setting_lookup_mutable_string(setting, "db_password", log_db_password, sizeof(log_db_password));
+ libconfig->setting_lookup_mutable_string(setting, "db_hostname", loginlog->dbs->log_db_hostname, sizeof(loginlog->dbs->log_db_hostname));
+ libconfig->setting_lookup_mutable_string(setting, "db_database", loginlog->dbs->log_db_database, sizeof(loginlog->dbs->log_db_database));
+ libconfig->setting_lookup_mutable_string(setting, "db_username", loginlog->dbs->log_db_username, sizeof(loginlog->dbs->log_db_username));
+ libconfig->setting_lookup_mutable_string(setting, "db_password", loginlog->dbs->log_db_password, sizeof(loginlog->dbs->log_db_password));
- libconfig->setting_lookup_uint16(setting, "db_port", &log_db_port);
- libconfig->setting_lookup_mutable_string(setting, "codepage", log_codepage, sizeof(log_codepage));
+ libconfig->setting_lookup_uint16(setting, "db_port", &loginlog->dbs->log_db_port);
+ libconfig->setting_lookup_mutable_string(setting, "codepage", loginlog->dbs->log_codepage, sizeof(loginlog->dbs->log_codepage));
return true;
}
@@ -206,16 +199,16 @@ bool loginlog_config_read(const char *filename, bool imported)
if (!libconfig->load_file(&config, filename))
return false; // Error message is already shown by libconfig->load_file
- if (!loginlog_config_read_names(filename, &config, imported))
+ if (!loginlog->config_read_names(filename, &config, imported))
retval = false;
- if (!loginlog_config_read_log(filename, &config, imported))
+ if (!loginlog->config_read_log(filename, &config, imported))
retval = false;
if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
if (strcmp(import, filename) == 0 || strcmp(import, "conf/common/inter-server.conf") == 0) {
ShowWarning("inter_config_read: Loop detected! Skipping 'import'...\n");
} else {
- if (!loginlog_config_read(import, true))
+ if (!loginlog->config_read(import, true))
retval = false;
}
}
@@ -223,3 +216,29 @@ bool loginlog_config_read(const char *filename, bool imported)
libconfig->destroy(&config);
return retval;
}
+
+void loginlog_defaults(void)
+{
+ loginlog = &loginlog_s;
+ loginlog->dbs = &loginlogdbs;
+
+ loginlog->sql_handle = NULL;
+ loginlog->enabled = false;
+
+ // Sql settings
+ strcpy(loginlog->dbs->log_db_hostname, "127.0.0.1");
+ loginlog->dbs->log_db_port = 3306;
+ strcpy(loginlog->dbs->log_db_username, "ragnarok");
+ strcpy(loginlog->dbs->log_db_password, "ragnarok");
+ strcpy(loginlog->dbs->log_db_database, "ragnarok");
+ *loginlog->dbs->log_codepage = 0;
+ strcpy(loginlog->dbs->log_login_db, "loginlog");
+
+ loginlog->failedattempts = loginlog_failedattempts;
+ loginlog->log = loginlog_log;
+ loginlog->init = loginlog_init;
+ loginlog->final = loginlog_final;
+ loginlog->config_read_names = loginlog_config_read_names;
+ loginlog->config_read_log = loginlog_config_read_log;
+ loginlog->config_read = loginlog_config_read;
+}
diff --git a/src/login/loginlog.h b/src/login/loginlog.h
index 589bc4fa1..fecb9b364 100644
--- a/src/login/loginlog.h
+++ b/src/login/loginlog.h
@@ -21,15 +21,41 @@
#ifndef LOGIN_LOGINLOG_H
#define LOGIN_LOGINLOG_H
+#include "common/hercules.h"
#include "common/cbasetypes.h"
+struct config_t;
+
+struct s_loginlog_dbs {
+ char log_db_hostname[32];
+ uint16 log_db_port;
+ char log_db_username[32];
+ char log_db_password[100];
+ char log_db_database[32];
+ char log_codepage[32];
+ char log_login_db[256];
+};
+
+/**
+ * Loginlog.c Interface
+ **/
+struct loginlog_interface {
+ struct Sql *sql_handle;
+ bool enabled;
+ struct s_loginlog_dbs *dbs;
+ unsigned long (*failedattempts) (uint32 ip, unsigned int minutes);
+ void (*log) (uint32 ip, const char* username, int rcode, const char* message);
+ bool (*init) (void);
+ bool (*final) (void);
+ bool (*config_read_names) (const char *filename, struct config_t *config, bool imported);
+ bool (*config_read_log) (const char *filename, struct config_t *config, bool imported);
+ bool (*config_read) (const char *filename, bool imported);
+};
+
#ifdef HERCULES_CORE
-// TODO: Interface
-unsigned long loginlog_failedattempts(uint32 ip, unsigned int minutes);
-void login_log(uint32 ip, const char* username, int rcode, const char* message);
-bool loginlog_init(void);
-bool loginlog_final(void);
-bool loginlog_config_read(const char *filename, bool imported);
+void loginlog_defaults(void);
#endif // HERCULES_CORE
+HPShared struct loginlog_interface *loginlog;
+
#endif /* LOGIN_LOGINLOG_H */
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 29e8bf4f8..9deed0098 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1691,7 +1691,7 @@ ACMD(cvcoff)
clif->map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING);
clif->maptypeproperty2(&sd->bl, ALL_SAMEMAP);
map->foreachinmap(atcommand->stopattack, sd->bl.m, BL_CHAR, 0);
- clif->message(fd, msg_fd(fd, 26)); // CvC: Off.
+ clif->message(fd, msg_fd(fd, 137)); // CvC: Off.
return true;
}
@@ -1710,7 +1710,7 @@ ACMD(cvcon)
map->list[sd->bl.m].flag.cvc = 1;
clif->map_property_mapall(sd->bl.m, MAPPROPERTY_AGITZONE);
clif->maptypeproperty2(&sd->bl, ALL_SAMEMAP);
- clif->message(fd, msg_fd(fd, 27)); // CvC: On.
+ clif->message(fd, msg_fd(fd, 138)); // CvC: On.
return true;
}
@@ -7596,7 +7596,7 @@ ACMD(mapflag) {
CHECKFLAG(noexppenalty); CHECKFLAG(pvp); CHECKFLAG(pvp_noparty); CHECKFLAG(pvp_noguild);
CHECKFLAG(pvp_nightmaredrop); CHECKFLAG(pvp_nocalcrank); CHECKFLAG(gvg_castle); CHECKFLAG(gvg);
CHECKFLAG(gvg_dungeon); CHECKFLAG(gvg_noparty); CHECKFLAG(battleground); CHECKFLAG(cvc);
- CHECKFLAG(nozenypenalty); CHECKFLAG(notrade); CHECKFLAG(noskill); CHECKFLAG(nowarp);
+ CHECKFLAG(nozenypenalty); CHECKFLAG(notrade); CHECKFLAG(noskill); CHECKFLAG(nowarp);
CHECKFLAG(nowarpto); CHECKFLAG(noicewall); CHECKFLAG(snow); CHECKFLAG(clouds);
CHECKFLAG(clouds2); CHECKFLAG(fog); CHECKFLAG(fireworks); CHECKFLAG(sakura);
CHECKFLAG(leaves); CHECKFLAG(nobaseexp);
@@ -7872,7 +7872,6 @@ ACMD(cash)
{
char output[128];
int value;
- int ret=0;
if (!*message || (value = atoi(message)) == 0) {
clif->message(fd, msg_fd(fd,1322)); // Please enter an amount.
@@ -7880,38 +7879,38 @@ ACMD(cash)
}
if (!strcmpi(info->command,"cash")) {
- if( value > 0 ) {
- if( (ret=pc->getcash(sd, value, 0)) >= 0){
+ if (value > 0) {
+ if ((pc->getcash(sd, value, 0)) >= 0) {
// If this option is set, the message is already sent by pc function
- if( !battle_config.cashshop_show_points ){
- sprintf(output, msg_fd(fd,505), ret, sd->cashPoints);
+ if (!battle_config.cashshop_show_points) {
+ sprintf(output, msg_fd(fd,505), value, sd->cashPoints);
clif_disp_onlyself(sd, output);
clif->message(fd, output);
}
} else
clif->message(fd, msg_fd(fd,149)); // Unable to decrease the number/value.
} else {
- if( (ret=pc->paycash(sd, -value, 0)) >= 0){
- sprintf(output, msg_fd(fd,410), ret, sd->cashPoints);
+ if ((pc->paycash(sd, -value, 0)) >= 0) {
+ sprintf(output, msg_fd(fd,410), -value, sd->cashPoints);
clif_disp_onlyself(sd, output);
clif->message(fd, output);
} else
clif->message(fd, msg_fd(fd,41)); // Unable to decrease the number/value.
}
} else { // @points
- if( value > 0 ) {
- if( (ret=pc->getcash(sd, 0, value)) >= 0) {
+ if (value > 0) {
+ if ((pc->getcash(sd, 0, value)) >= 0) {
// If this option is set, the message is already sent by pc function
- if( !battle_config.cashshop_show_points ){
- sprintf(output, msg_fd(fd,506), ret, sd->kafraPoints);
+ if (!battle_config.cashshop_show_points) {
+ sprintf(output, msg_fd(fd,506), value, sd->kafraPoints);
clif_disp_onlyself(sd, output);
clif->message(fd, output);
}
} else
clif->message(fd, msg_fd(fd,149)); // Unable to decrease the number/value.
} else {
- if( (ret=pc->paycash(sd, -value, -value)) >= 0){
- sprintf(output, msg_fd(fd,411), ret, sd->kafraPoints);
+ if ((pc->paycash(sd, -value, -value)) >= 0) {
+ sprintf(output, msg_fd(fd,411), -value, sd->kafraPoints);
clif_disp_onlyself(sd, output);
clif->message(fd, output);
} else
@@ -8473,7 +8472,7 @@ void atcommand_commands_sub(struct map_session_data* sd, const int fd, AtCommand
}
}
if (count_bind > 0)
- clif->message(fd, line_buff); // Last Line
+ clif->message(fd, line_buff); // Last Line
count += count_bind;
}
@@ -9506,7 +9505,7 @@ ACMD(claninfo)
struct DBIterator *iter = db_iterator(clan->db);
struct clan *c;
int i, count;
-
+
for (c = dbi_first(iter); dbi_exists(iter); c = dbi_next(iter)) {
safesnprintf(atcmd_output, sizeof(atcmd_output), "Clan #%d:", c->clan_id);
clif->messagecolor_self(fd, COLOR_DEFAULT, atcmd_output);
@@ -9545,9 +9544,6 @@ ACMD(claninfo)
for (i = 0; i < VECTOR_LENGTH(c->allies); i++) {
struct clan_relationship *ally = &VECTOR_INDEX(c->allies, i);
- if (ally == NULL)
- continue;
-
safesnprintf(atcmd_output, sizeof(atcmd_output), "- - Ally #%d (Id: %d): %s", i + 1, ally->clan_id, ally->constant);
clif->messagecolor_self(fd, COLOR_DEFAULT, atcmd_output);
count++;
@@ -9559,14 +9555,11 @@ ACMD(claninfo)
safesnprintf(atcmd_output, sizeof(atcmd_output), "- Antagonists: %d", VECTOR_LENGTH(c->antagonists));
clif->messagecolor_self(fd, COLOR_DEFAULT, atcmd_output);
-
+
count = 0;
for (i = 0; i < VECTOR_LENGTH(c->antagonists); i++) {
struct clan_relationship *antagonist = &VECTOR_INDEX(c->antagonists, i);
- if (antagonist == NULL)
- continue;
-
safesnprintf(atcmd_output, sizeof(atcmd_output), "- - Antagonist #%d (Id: %d): %s", i + 1, antagonist->clan_id, antagonist->constant);
clif->messagecolor_self(fd, COLOR_DEFAULT, atcmd_output);
count++;
@@ -9575,7 +9568,7 @@ ACMD(claninfo)
if (count == 0) {
clif->messagecolor_self(fd, COLOR_DEFAULT, "- - No Antagonists Found!");
}
-
+
clif->messagecolor_self(fd, COLOR_DEFAULT, "============================");
}
dbi_destroy(iter);
@@ -10062,6 +10055,7 @@ bool atcommand_exec(const int fd, struct map_session_data *sd, const char *messa
{
char params[100], command[100];
char output[CHAT_SIZE_MAX];
+ bool logCommand;
// Reconstructed message
char atcmd_msg[CHAT_SIZE_MAX];
@@ -10205,6 +10199,7 @@ bool atcommand_exec(const int fd, struct map_session_data *sd, const char *messa
}
}
+ logCommand = info->log;
//Attempt to use the command
if ((info->func(fd, ssd, command, params,info) != true)) {
#ifdef AUTOTRADE_PERSISTENCY
@@ -10216,7 +10211,8 @@ bool atcommand_exec(const int fd, struct map_session_data *sd, const char *messa
return true;
}
- if (info->log) /* log only if this command should be logged [Ind/Hercules] */
+ // info->log cant be used here, because info can be freed [4144]
+ if (logCommand) /* log only if this command should be logged [Ind/Hercules] */
logs->atcommand(sd, is_atcommand ? atcmd_msg : message);
return true;
diff --git a/src/map/battle.c b/src/map/battle.c
index d52d20f24..bd7e31d05 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -6799,7 +6799,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
} else if (!(map->list[m].flag.pvp && map->list[m].flag.pvp_noparty)
&& (!map->list[m].flag.battleground || sbg_id == tbg_id)) {
state |= BCT_PARTY;
- } else if (!map->list[m].flag.cvc || s_clan == t_clan) {
+ } else if (!map->list[m].flag.cvc || s_clan == t_clan) {
state |= BCT_PARTY;
} else {
state |= BCT_ENEMY;
@@ -7309,7 +7309,7 @@ static const struct battle_data {
{ "max_body_style", &battle_config.max_body_style, 4, 0, SHRT_MAX, },
{ "save_body_style", &battle_config.save_body_style, 0, 0, 1, },
{ "player_warp_keep_direction", &battle_config.player_warp_keep_direction, 0, 0, 1, },
- { "atcommand_levelup_events", &battle_config.atcommand_levelup_events, 0, 0, 1, },
+ { "atcommand_levelup_events", &battle_config.atcommand_levelup_events, 0, 0, 1, },
{ "bow_unequip_arrow", &battle_config.bow_unequip_arrow, 1, 0, 1, },
{ "max_summoner_parameter", &battle_config.max_summoner_parameter, 120, 10, 10000, },
{ "mvp_exp_reward_message", &battle_config.mvp_exp_reward_message, 0, 0, 1, },
diff --git a/src/map/battle.h b/src/map/battle.h
index 429249dca..8b7fea29f 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -546,7 +546,7 @@ struct Battle_Config {
// Warp Face Direction
int player_warp_keep_direction;
- int atcommand_levelup_events; // Enable atcommands trigger level up events for NPCs
+ int atcommand_levelup_events; // Enable atcommands trigger level up events for NPCs
int bow_unequip_arrow;
diff --git a/src/map/clan.c b/src/map/clan.c
index b67726b37..7aa9be5d4 100644
--- a/src/map/clan.c
+++ b/src/map/clan.c
@@ -94,7 +94,7 @@ struct clan *clan_searchname(const char *name)
/**
* Returns the first online character of clan
- *
+ *
* @param (struct clan *) c clan structure
* @return (struct map_session_data *)
*/
@@ -103,7 +103,7 @@ struct map_session_data *clan_getonlinesd(struct clan *c)
int i;
nullpo_retr(NULL, c);
- ARR_FIND(0, VECTOR_LENGTH(c->members), i, VECTOR_INDEX(c->members, i).sd != NULL);
+ ARR_FIND(0, VECTOR_LENGTH(c->members), i, (VECTOR_INDEX(c->members, i).sd != NULL && VECTOR_INDEX(c->members, i).online == 1));
return (i < VECTOR_LENGTH(c->members)) ? VECTOR_INDEX(c->members, i).sd : NULL;
}
@@ -150,7 +150,7 @@ void clan_buff_end(struct map_session_data *sd, struct clan *c)
{
nullpo_retv(sd);
nullpo_retv(c);
-
+
if (c->buff.icon <= 0) {
return;
}
@@ -171,7 +171,7 @@ bool clan_join(struct map_session_data *sd, int clan_id)
struct clan_member m;
nullpo_ret(sd);
-
+
// Already joined a guild or clan
if (sd->status.guild_id > 0 || sd->guild != NULL) {
ShowError("clan_join: Player already joined in a guild. char_id: %d\n", sd->status.char_id);
@@ -200,24 +200,24 @@ bool clan_join(struct map_session_data *sd, int clan_id)
ShowError("clan_join: Clan '%s' already reached its max capacity!\n", c->name);
return false;
}
-
+
VECTOR_ENSURE(c->members, 1, 1);
-
+
m.sd = sd;
m.char_id = sd->status.char_id;
m.online = 1;
m.last_login = sd->status.last_login;
VECTOR_PUSH(c->members, m);
-
+
c->connect_member++;
c->member_count++;
-
+
sd->status.clan_id = c->clan_id;
sd->clan = c;
-
+
sc_start2(NULL, &sd->bl, SC_CLAN_INFO, 10000, 0, c->clan_id, INFINITE_DURATION);
status_calc_pc(sd, SCO_FORCE);
-
+
chrif->save(sd, 0);
clif->clan_basicinfo(sd);
clif->clan_onlinecount(c);
@@ -256,11 +256,11 @@ void clan_member_online(struct map_session_data *sd, bool first)
clif->clan_leave(sd);
return;
}
-
+
if (!c->received) {
return;
}
-
+
if (c->max_member <= c->member_count || VECTOR_LENGTH(c->members) >= c->max_member) {
ShowError("Clan System: More members than the maximum allowed in clan #%d\n", c->clan_id);
return;
@@ -270,7 +270,7 @@ void clan_member_online(struct map_session_data *sd, bool first)
inactivity = (int)(time(NULL) - sd->status.last_login);
if (i == INDEX_NOT_FOUND) {
struct clan_member m;
-
+
if (c->kick_time > 0 && inactivity > c->kick_time) {
sd->status.clan_id = 0;
sd->clan = NULL;
@@ -290,10 +290,11 @@ void clan_member_online(struct map_session_data *sd, bool first)
} else {
struct clan_member *m = &VECTOR_INDEX(c->members, i);
-
+
if (c->kick_time > 0 && inactivity > c->kick_time) {
if (m->online == 1) {
m->online = 0;
+ m->sd = NULL;
c->connect_member--;
c->member_count--;
}
@@ -306,10 +307,11 @@ void clan_member_online(struct map_session_data *sd, bool first)
return;
}
+ m->sd = sd;
m->online = 1;
m->last_login = sd->status.last_login;
}
-
+
sd->clan = c;
c->connect_member++;
@@ -383,7 +385,7 @@ bool clan_leave(struct map_session_data *sd, bool first)
/**
* Sets a player offline
- *
+ *
* @param (struct map_session_data *) sd Player Data
*/
void clan_member_offline(struct map_session_data *sd)
@@ -392,9 +394,9 @@ void clan_member_offline(struct map_session_data *sd)
int i;
nullpo_retv(sd);
-
+
c = sd->clan;
-
+
if (c == NULL) {
return;
}
@@ -403,6 +405,7 @@ void clan_member_offline(struct map_session_data *sd)
if (i != INDEX_NOT_FOUND && VECTOR_INDEX(c->members, i).online == 1) {
// Only if it is online, because unit->free is called twice
VECTOR_INDEX(c->members, i).online = 0;
+ VECTOR_INDEX(c->members, i).sd = NULL;
c->connect_member--;
}
clif->clan_onlinecount(c);
@@ -520,7 +523,7 @@ int clan_inactivity_kick(int tid, int64 tick, int id, intptr_t data)
if ((c = clan->search(id)) != NULL) {
if (!c->kick_time || c->tid != tid || tid == INVALID_TIMER || c->tid == INVALID_TIMER) {
ShowError("Timer Mismatch (Time: %d seconds) %d != %d", c->kick_time, c->tid, tid);
- Assert_retr(0, 0);
+ Assert_report(0);
return 0;
}
for (i = 0; i < VECTOR_LENGTH(c->members); i++) {
@@ -647,11 +650,11 @@ void clan_read_buffs(struct clan *c, struct config_setting_t *buff, const char *
int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool reload)
{
int total, s, valid = 0;
-
+
nullpo_retr(false, settings);
-
+
total = libconfig->setting_length(settings);
-
+
for (s = 0; s < total; s++) {
struct clan *c;
struct config_setting_t *cl, *buff, *allies, *antagonists;
@@ -665,7 +668,7 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
ShowError("clan_read_db: Invalid Clan Id %d, skipping...\n", id);
return false;
}
-
+
if (clan->search(id) != NULL) {
ShowError("clan_read_db: Duplicate entry for Clan Id %d, skipping...\n", id);
return false;
@@ -674,18 +677,18 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
ShowError("clan_read_db: failed to find 'Id' for clan #%d\n", s);
return false;
}
-
+
if (libconfig->setting_lookup_string(cl, "Const", &aConst)) {
if (!*aConst) {
ShowError("clan_read_db: Invalid Clan Const '%s', skipping...\n", aConst);
return false;
}
-
+
if (strlen(aConst) > NAME_LENGTH) {
ShowError("clan_read_db: Clan Name '%s' is longer than %d characters, skipping...\n", aConst, NAME_LENGTH);
return false;
}
-
+
if (clan->searchname(aConst) != NULL) {
ShowError("clan_read_db: Duplicate entry for Clan Const '%s', skipping...\n", aConst);
return false;
@@ -694,18 +697,18 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
ShowError("clan_read_db: failed to find 'Const' for clan #%d\n", s);
return false;
}
-
+
if (libconfig->setting_lookup_string(cl, "Name", &aName)) {
if (!*aName) {
ShowError("clan_read_db: Invalid Clan Name '%s', skipping...\n", aName);
return false;
}
-
+
if (strlen(aName) > NAME_LENGTH) {
ShowError("clan_read_db: Clan Name '%s' is longer than %d characters, skipping...\n", aName, NAME_LENGTH);
return false;
}
-
+
if (clan->searchname(aName) != NULL) {
ShowError("clan_read_db: Duplicate entry for Clan Name '%s', skipping...\n", aName);
return false;
@@ -714,19 +717,19 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
ShowError("clan_read_db: failed to find 'Name' for clan #%d\n", s);
return false;
}
-
+
if (!libconfig->setting_lookup_string(cl, "Leader", &aLeader)) {
ShowError("clan_read_db: failed to find 'Leader' for clan #%d\n", s);
return false;
}
-
+
if (!libconfig->setting_lookup_string(cl, "Map", &aMap)) {
ShowError("clan_read_db: failed to find 'Map' for clan #%d\n", s);
return false;
}
CREATE(c, struct clan, 1);
-
+
c->clan_id = id;
safestrncpy(c->constant, aConst, NAME_LENGTH);
safestrncpy(c->name, aName, NAME_LENGTH);
@@ -767,19 +770,19 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
}
allies = libconfig->setting_get_member(cl, "Allies");
-
+
if (allies != NULL) {
int a = libconfig->setting_length(allies);
-
+
VECTOR_INIT(c->allies);
if (a > 0 && clan->max_relations > 0) {
const char *allyConst;
-
+
if (a > clan->max_relations) {
ShowWarning("clan_read_db: Clan %d has more allies(%d) than allowed(%d), reading only the first %d...\n", c->clan_id, a, clan->max_relations, clan->max_relations);
a = clan->max_relations;
}
-
+
VECTOR_ENSURE(c->allies, a, 1);
for (i = 0; i < a; i++) {
struct clan_relationship r;
@@ -807,12 +810,12 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
VECTOR_INIT(c->antagonists);
if (a > 0 && clan->max_relations > 0) {
const char *antagonistConst;
-
+
if (a > clan->max_relations) {
ShowWarning("clan_read_db: Clan %d has more antagonists(%d) than allowed(%d), reading only the first %d...\n", c->clan_id, a, clan->max_relations, clan->max_relations);
a = clan->max_relations;
}
-
+
VECTOR_ENSURE(c->antagonists, a, 1);
for (i = 0; i < a; i++) {
struct clan_relationship r;
@@ -831,7 +834,7 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
}
}
}
-
+
clan->read_db_additional_fields(c, cl, s, source);
if (c->kick_time > 0) {
c->tid = timer->add(timer->gettick() + c->check_time, clan->inactivity_kick, c->clan_id, 0);
@@ -843,13 +846,13 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
VECTOR_INIT(c->members);
valid++;
}
-
+
// Validating Relations
if (valid > 0) {
struct DBIterator *iter = db_iterator(clan->db);
struct clan *c_ok, *c;
int i;
-
+
for (c_ok = dbi_first(iter); dbi_exists(iter); c_ok = dbi_next(iter)) {
i = VECTOR_LENGTH(c_ok->allies);
while ( i > 0) {
@@ -868,7 +871,7 @@ int clan_read_db_sub(struct config_setting_t *settings, const char *source, bool
i = VECTOR_LENGTH(c_ok->antagonists);
while ( i > 0) {
struct clan_relationship *r;
-
+
i--;
r = &VECTOR_INDEX(c_ok->antagonists, i);
if ((c = clan->searchname(r->constant)) == NULL) {
@@ -900,7 +903,7 @@ void clan_read_db(struct config_setting_t *settings, const char *source, bool re
if ((clans = libconfig->setting_get_member(settings, "clans")) != NULL) {
int read;
-
+
read = clan->read_db_sub(clans, source, reload);
if (read > 0) {
clan->set_constants();
@@ -985,7 +988,7 @@ void clan_config_read_additional_settings(struct config_setting_t *settings, con
* Reloads Clan DB
*/
void clan_reload(void)
-{
+{
clan->config_read(true);
}
@@ -994,10 +997,11 @@ void clan_reload(void)
*/
void do_init_clan(bool minimal)
{
+ clan->db = idb_alloc(DB_OPT_RELEASE_DATA);
+
if (minimal) {
return;
}
- clan->db = idb_alloc(DB_OPT_RELEASE_DATA);
clan->config_read(false);
timer->add_func_list(clan->inactivity_kick, "clan_inactivity_kick");
}
diff --git a/src/map/clif.c b/src/map/clif.c
index 4efd00713..51de62a23 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -673,7 +673,7 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target
nullpo_retr(false, c);
for (i = 0; i < VECTOR_LENGTH(c->members); i++) {
- if ((sd = VECTOR_INDEX(c->members, i).sd) == NULL || (fd = sd->fd) <= 0)
+ if (VECTOR_INDEX(c->members, i).online == 0 || (sd = VECTOR_INDEX(c->members, i).sd) == NULL || (fd = sd->fd) <= 0)
continue;
WFIFOHEAD(fd, len);
memcpy(WFIFOP(fd, 0), buf, len);
@@ -6090,14 +6090,29 @@ void clif_wis_end(int fd, int flag) {
/// Returns character name requested by char_id (ZC_ACK_REQNAME_BYGID).
/// 0194 <char id>.L <name>.24B
+/// 0af7 <flag>.W <char id>.L <name>.24B
void clif_solved_charname(int fd, int charid, const char* name)
{
nullpo_retv(name);
- WFIFOHEAD(fd,packet_len(0x194));
- WFIFOW(fd,0)=0x194;
- WFIFOL(fd,2)=charid;
- safestrncpy(WFIFOP(fd,6), name, NAME_LENGTH);
- WFIFOSET(fd,packet_len(0x194));
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
+ WFIFOHEAD(fd, packet_len(0x0af7));
+ WFIFOW(fd, 0) = 0xaf7;
+ if (*name == 0) {
+ WFIFOW(fd, 2) = 2;
+ memset(WFIFOP(fd, 8), 0, NAME_LENGTH);
+ } else {
+ WFIFOW(fd, 2) = 3;
+ safestrncpy(WFIFOP(fd, 8), name, NAME_LENGTH);
+ }
+ WFIFOL(fd, 4) = charid;
+ WFIFOSET(fd, packet_len(0x0af7));
+#else
+ WFIFOHEAD(fd, packet_len(0x194));
+ WFIFOW(fd, 0) = 0x194;
+ WFIFOL(fd, 2) = charid;
+ safestrncpy(WFIFOP(fd, 6), name, NAME_LENGTH);
+ WFIFOSET(fd, packet_len(0x194));
+#endif
}
/// Presents a list of items that can be carded/composed (ZC_ITEMCOMPOSITION_LIST).
@@ -7411,7 +7426,7 @@ void clif_mvp_item(struct map_session_data *sd,int nameid)
/// 010b <exp>.L
void clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
{
-#if PACKETVER >= 20131223 // Kro removed this packet [Napster]
+#if PACKETVER >= 20131223 // Kro removed this packet [Napster]
if (battle_config.mvp_exp_reward_message) {
char e_msg[CHAT_SIZE_MAX];
sprintf(e_msg, msg_txt(855), exp);
@@ -11001,13 +11016,21 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd) __attribute_
void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd)
{
int len = RFIFOW(fd,2)-15;
- int limit = RFIFOW(fd,4);
- bool pub = (RFIFOB(fd,6) != 0);
- const char *password = RFIFOP(fd,7); //not zero-terminated
- const char *title = RFIFOP(fd,15); // not zero-terminated
+ int limit;
+ bool pub;
+ const char *password; //not zero-terminated
+ const char *title; // not zero-terminated
char s_password[CHATROOM_PASS_SIZE];
char s_title[CHATROOM_TITLE_SIZE];
+ if (len < 1)
+ return;
+
+ limit = RFIFOW(fd, 4);
+ pub = (RFIFOB(fd, 6) != 0);
+ password = RFIFOP(fd, 7); //not zero-terminated
+ title = RFIFOP(fd, 15); // not zero-terminated
+
if (pc_ismuted(&sd->sc, MANNER_NOROOM))
return;
if(battle_config.basic_skill_check && !pc->check_basicskill(sd, 4)) {
@@ -11023,9 +11046,6 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd)
return;
}
- if( len <= 0 )
- return; // invalid input
-
safestrncpy(s_password, password, CHATROOM_PASS_SIZE);
safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE)); //NOTE: assumes that safestrncpy will not access the len+1'th byte
@@ -11052,15 +11072,20 @@ void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data* sd) __attr
void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data* sd)
{
int len = RFIFOW(fd,2)-15;
- int limit = RFIFOW(fd,4);
- bool pub = (RFIFOB(fd,6) != 0);
- const char *password = RFIFOP(fd,7); // not zero-terminated
- const char *title = RFIFOP(fd,15); // not zero-terminated
+ int limit;
+ bool pub;
+ const char *password; // not zero-terminated
+ const char *title; // not zero-terminated
char s_password[CHATROOM_PASS_SIZE];
char s_title[CHATROOM_TITLE_SIZE];
- if( len <= 0 )
- return; // invalid input
+ if (len < 1)
+ return;
+
+ limit = RFIFOW(fd, 4);
+ pub = (RFIFOB(fd, 6) != 0);
+ password = RFIFOP(fd, 7); // not zero-terminated
+ title = RFIFOP(fd, 15); // not zero-terminated
safestrncpy(s_password, password, CHATROOM_PASS_SIZE);
safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE)); //NOTE: assumes that safestrncpy will not access the len+1'th byte
@@ -11076,7 +11101,7 @@ void clif_parse_ChangeChatOwner(int fd, struct map_session_data* sd) __attribute
/// 1 = normal
void clif_parse_ChangeChatOwner(int fd, struct map_session_data* sd)
{
- chat->change_owner(sd, RFIFOP(fd,6));
+ chat->change_owner(sd, RFIFOP(fd,6)); // non null terminated
}
void clif_parse_KickFromChat(int fd,struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -11084,7 +11109,7 @@ void clif_parse_KickFromChat(int fd,struct map_session_data *sd) __attribute__((
/// 00e2 <name>.24B
void clif_parse_KickFromChat(int fd,struct map_session_data *sd)
{
- chat->kick(sd, RFIFOP(fd,2));
+ chat->kick(sd, RFIFOP(fd,2)); // non null terminated
}
void clif_parse_ChatLeave(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
@@ -11843,17 +11868,21 @@ void clif_parse_NpcStringInput(int fd, struct map_session_data* sd) __attribute_
/// 01d5 <packet len>.W <npc id>.L <string>.?B
void clif_parse_NpcStringInput(int fd, struct map_session_data* sd)
{
+ int len = RFIFOW(fd, 2);
// [4144] can't confirm exact client version. At least >= correct for 20150513
#if PACKETVER >= 20151029
- int message_len = RFIFOW(fd, 2) - 7;
+ int message_len = len - 7;
#else
- int message_len = RFIFOW(fd, 2) - 8;
+ int message_len = len - 8;
#endif
- int npcid = RFIFOL(fd,4);
- const char *message = RFIFOP(fd,8);
+ int npcid;
+ const char *message;
+
+ if (len < 9)
+ return;
- if( message_len <= 0 )
- return; // invalid input
+ npcid = RFIFOL(fd, 4);
+ message = RFIFOP(fd, 8);
safestrncpy(sd->npc_str, message, min(message_len,CHATBOX_SIZE));
npc->scriptcont(sd, npcid, false);
@@ -11891,8 +11920,8 @@ void clif_parse_ItemIdentify(int fd,struct map_session_data *sd)
clif_menuskill_clear(sd);
}
-/// Identifying item with right-click (CZ_REQ_ONECLICK_ITEMIDENTIFY).
-/// 0A35 <index>.W
+/// Identifying item with right-click (CZ_REQ_ONECLICK_ITEMIDENTIFY).
+/// 0A35 <index>.W
void clif_parse_OneClick_ItemIdentify(int fd, struct map_session_data *sd)
{
int cmd = RFIFOW(fd,0);
@@ -13007,9 +13036,15 @@ void clif_parse_PurchaseReq(int fd, struct map_session_data* sd) __attribute__((
/// 0134 <packet len>.W <account id>.L { <amount>.W <index>.W }*
void clif_parse_PurchaseReq(int fd, struct map_session_data* sd)
{
- int len = (int)RFIFOW(fd,2) - 8;
- int id = RFIFOL(fd,4);
- const uint8 *data = RFIFOP(fd,8);
+ int len = (int)RFIFOW(fd, 2) - 8;
+ int id;
+ const uint8 *data;
+
+ if (len < 1)
+ return;
+
+ id = RFIFOL(fd, 4);
+ data = RFIFOP(fd, 8);
vending->purchase(sd, id, sd->vended_id, data, len/4);
@@ -13022,10 +13057,16 @@ void clif_parse_PurchaseReq2(int fd, struct map_session_data* sd) __attribute__(
/// 0801 <packet len>.W <account id>.L <unique id>.L { <amount>.W <index>.W }*
void clif_parse_PurchaseReq2(int fd, struct map_session_data* sd)
{
- int len = (int)RFIFOW(fd,2) - 12;
- int aid = RFIFOL(fd,4);
- int uid = RFIFOL(fd,8);
- const uint8 *data = RFIFOP(fd,12);
+ int len = (int)RFIFOW(fd, 2) - 12;
+ int aid;
+ int uid;
+ const uint8 *data;
+
+ if (len < 1)
+ return;
+ aid = RFIFOL(fd, 4);
+ uid = RFIFOL(fd, 8);
+ data = RFIFOP(fd, 12);
vending->purchase(sd, aid, uid, data, len/4);
@@ -13042,9 +13083,16 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd) __attribute__((
/// 1 = open
void clif_parse_OpenVending(int fd, struct map_session_data* sd) {
short len = (short)RFIFOW(fd,2) - 85;
- const char *message = RFIFOP(fd,4);
- bool flag = (RFIFOB(fd,84) != 0) ? true : false;
- const uint8 *data = RFIFOP(fd,85);
+ const char *message;
+ bool flag;
+ const uint8 *data;
+
+ if (len < 1)
+ return;
+
+ message = RFIFOP(fd,4);
+ flag = (RFIFOB(fd,84) != 0) ? true : false;
+ data = RFIFOP(fd,85);
if( !flag )
sd->state.prevend = sd->state.workinprogress = 0;
@@ -13137,12 +13185,14 @@ void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd) __a
void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd)
{
int i;
+ int count = (RFIFOW(fd, 2) - 4) / 40;
- if(!sd->state.gmaster_flag)
+ if (!sd->state.gmaster_flag)
return;
- for(i = 4; i < RFIFOW(fd,2); i += 40 ){
- guild->change_position(sd->status.guild_id, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), RFIFOP(fd,i+16));
+ for (i = 0; i < count; i ++ ) {
+ int idx = i * 40 + 4;
+ guild->change_position(sd->status.guild_id, RFIFOL(fd, idx), RFIFOL(fd, idx + 4), RFIFOL(fd, idx + 12), RFIFOP(fd, idx + 16));
}
}
@@ -13153,6 +13203,7 @@ void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd)
{
int i;
int len = RFIFOW(fd, 2);
+ int count = (len - 4) / 12;
if(!sd->state.gmaster_flag)
return;
@@ -13163,10 +13214,11 @@ void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd)
return;
}
- for(i=4;i<RFIFOW(fd,2);i+=12){
- int position = RFIFOL(fd, i + 8);
- if (position > 0) {
- guild->change_memberposition(sd->status.guild_id, RFIFOL(fd, i), RFIFOL(fd, i + 4), position);
+ for (i = 0; i < count; i++) {
+ int idx = i * 12 + 4;
+ int position = RFIFOL(fd, idx + 8);
+ if (position > 0 && position < MAX_GUILDPOSITION) {
+ guild->change_memberposition(sd->status.guild_id, RFIFOL(fd, idx), RFIFOL(fd, idx + 4), position);
}
}
}
@@ -13550,12 +13602,15 @@ void clif_parse_GuildBreak(int fd, struct map_session_data *sd) __attribute__((n
/// key:
/// now guild name; might have been (intended) email, since the
/// field name and size is same as the one in CH_DELETE_CHAR.
-void clif_parse_GuildBreak(int fd, struct map_session_data *sd) {
+void clif_parse_GuildBreak(int fd, struct map_session_data *sd)
+{
+ char key[40];
if( map->list[sd->bl.m].flag.guildlock ) {
clif->message(fd, msg_fd(fd,228)); // Guild modification is disabled in this map.
return;
}
- guild->dobreak(sd, RFIFOP(fd,2));
+ safestrncpy(key, RFIFOP(fd, 2), 40);
+ guild->dobreak(sd, key);
}
/// Pet
@@ -14144,6 +14199,7 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd)
/// Toggles a single friend online/offline [Skotlex] (ZC_FRIENDS_STATE).
/// 0206 <account id>.L <char id>.L <state>.B
+/// 0206 <account id>.L <char id>.L <state>.B <name>.24B
/// state:
/// 0 = online
/// 1 = offline
@@ -14163,7 +14219,11 @@ void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int cha
WFIFOW(fd, 0) = 0x206;
WFIFOL(fd, 2) = sd->status.friends[i].account_id;
WFIFOL(fd, 6) = sd->status.friends[i].char_id;
- WFIFOB(fd,10) = !online; //Yeah, a 1 here means "logged off", go figure...
+ WFIFOB(fd, 10) = !online; //Yeah, a 1 here means "logged off", go figure...
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
+ memcpy(WFIFOP(fd, 11), sd->status.friends[i].name, NAME_LENGTH);
+#endif // PACKETVER_ZERO
+
WFIFOSET(fd, packet_len(0x206));
}
@@ -14180,22 +14240,30 @@ int clif_friendslist_toggle_sub(struct map_session_data *sd,va_list ap)
/// Sends the whole friends list (ZC_FRIENDS_LIST).
/// 0201 <packet len>.W { <account id>.L <char id>.L <name>.24B }*
+/// 0201 <packet len>.W { <account id>.L <char id>.L }*
void clif_friendslist_send(struct map_session_data *sd)
{
int i = 0, n, fd = sd->fd;
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
+ const int offset = 8;
+#else
+ const int offset = 32;
+#endif
nullpo_retv(sd);
// Send friends list
- WFIFOHEAD(fd, MAX_FRIENDS * 32 + 4);
+ WFIFOHEAD(fd, MAX_FRIENDS * offset + 4);
WFIFOW(fd, 0) = 0x201;
for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++) {
- WFIFOL(fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id;
- WFIFOL(fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id;
- memcpy(WFIFOP(fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
+ WFIFOL(fd, 4 + offset * i + 0) = sd->status.friends[i].account_id;
+ WFIFOL(fd, 4 + offset * i + 4) = sd->status.friends[i].char_id;
+#if !(PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221)
+ memcpy(WFIFOP(fd, 4 + offset * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
+#endif
}
if (i) {
- WFIFOW(fd,2) = 4 + 32 * i;
+ WFIFOW(fd,2) = 4 + offset * i;
WFIFOSET(fd, WFIFOW(fd,2));
}
@@ -15304,17 +15372,19 @@ void clif_parse_Mail_winopen(int fd, struct map_session_data *sd)
void clif_parse_Mail_send(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
/// Request to send mail (CZ_MAIL_SEND).
/// 0248 <packet len>.W <recipient>.24B <title>.40B <body len>.B <body>.?B
+
void clif_parse_Mail_send(int fd, struct map_session_data *sd)
{
struct mail_message msg;
int body_len;
+ int len = RFIFOW(fd, 2);
if( !chrif->isconnected() )
return;
if( sd->state.trading )
return;
- if( RFIFOW(fd,2) < 69 ) {
+ if (len < 69) {
ShowWarning("Invalid Msg Len from account %d.\n", sd->status.account_id);
return;
}
@@ -15330,6 +15400,11 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd)
if (body_len > MAIL_BODY_LENGTH)
body_len = MAIL_BODY_LENGTH;
+ if (body_len + 69 > len) {
+ ShowWarning("Invalid Msg Len from account %d.\n", sd->status.account_id);
+ return;
+ }
+
memset(&msg, 0, sizeof(msg));
if (!mail->setattachment(sd, &msg)) { // Invalid Append condition
clif->mail_send(sd->fd, true); // fail
@@ -15835,15 +15910,24 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
fail = npc->cashshop_buy(sd, nameid, amount, points);
#else
int len = RFIFOW(fd,2);
- int points = RFIFOL(fd,4);
- int count = RFIFOW(fd,8);
+ int points;
+ int count;
struct itemlist item_list = { 0 };
int i;
- if( len < 10 || len != 10 + count * 4) {
+ if (len < 10) {
+ ShowWarning("Player %d sent incorrect cash shop buy packet (len %d)!\n", sd->status.char_id, len);
+ return;
+ }
+
+ points = RFIFOL(fd, 4);
+ count = RFIFOW(fd, 8);
+
+ if (len != 10 + count * 4) {
ShowWarning("Player %d sent incorrect cash shop buy packet (len %d:%d)!\n", sd->status.char_id, len, 10 + count * 4);
return;
}
+
VECTOR_INIT(item_list);
VECTOR_ENSURE(item_list, count, 1);
for (i = 0; i < count; i++) {
@@ -16568,15 +16652,15 @@ void clif_bg_message(struct battleground_data *bgd, int src_id, const char *name
return;
len = (int)strlen(mes);
- Assert_retv(len <= INT16_MAX - NAME_LENGTH - 8);
- buf = (unsigned char*)aMalloc((len + NAME_LENGTH + 8)*sizeof(unsigned char));
+ Assert_retv(len <= INT16_MAX - NAME_LENGTH - 9);
+ buf = (unsigned char *)aCalloc(len + NAME_LENGTH + 9, sizeof(unsigned char));
- WBUFW(buf,0) = 0x2dc;
- WBUFW(buf,2) = len + NAME_LENGTH + 8;
- WBUFL(buf,4) = src_id;
- memcpy(WBUFP(buf,8), name, NAME_LENGTH);
- memcpy(WBUFP(buf,32), mes, len); // [!] no NUL terminator
- clif->send(buf,WBUFW(buf,2), &sd->bl, BG);
+ WBUFW(buf, 0) = 0x2dc;
+ WBUFW(buf, 2) = len + NAME_LENGTH + 9;
+ WBUFL(buf, 4) = src_id;
+ safestrncpy(WBUFP(buf, 8), name, NAME_LENGTH);
+ safestrncpy(WBUFP(buf, 32), mes, len + 1);
+ clif->send(buf, WBUFW(buf, 2), &sd->bl, BG);
aFree(buf);
}
@@ -16881,7 +16965,7 @@ void clif_parse_ItemListWindowSelected(int fd, struct map_session_data *sd) __at
/// S 07e4 <length>.w <option>.l <val>.l {<index>.w <amount>.w).4b*
void clif_parse_ItemListWindowSelected(int fd, struct map_session_data *sd)
{
- int n = ((int)RFIFOW(fd,2) - 12) / 4;
+ int n = ((int)RFIFOW(fd, 2) - 12) / 4;
int type = RFIFOL(fd,4);
int flag = RFIFOL(fd,8); // Button clicked: 0 = Cancel, 1 = OK
struct itemlist item_list = { 0 };
@@ -17012,7 +17096,7 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) {
char storename[MESSAGE_SIZE];
unsigned char result;
int zenylimit;
- unsigned int count, packet_len;
+ int count, packet_len;
struct s_packet_db* info = &packet_db[RFIFOW(fd,0)];
packet_len = RFIFOW(fd,info->pos[0]);
@@ -17020,7 +17104,7 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) {
// TODO: Make this check global for all variable length packets.
if( packet_len < 89 )
{// minimum packet length
- ShowError("clif_parse_ReqOpenBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 89U, packet_len, sd->bl.id);
+ ShowError("clif_parse_ReqOpenBuyingStore: Malformed packet (expected length=%u, length=%d, account_id=%d).\n", 89U, packet_len, sd->bl.id);
return;
}
@@ -17032,9 +17116,12 @@ void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data* sd) {
// so that buyingstore_create knows, how many elements it has access to
packet_len-= info->pos[4];
+ if (packet_len < 0)
+ return;
+
if( packet_len%blocksize )
{
- ShowError("clif_parse_ReqOpenBuyingStore: Unexpected item list size %u (account_id=%d, block size=%u)\n", packet_len, sd->bl.id, blocksize);
+ ShowError("clif_parse_ReqOpenBuyingStore: Unexpected item list size %d (account_id=%d, block size=%u)\n", packet_len, sd->bl.id, blocksize);
return;
}
count = packet_len/blocksize;
@@ -17203,14 +17290,15 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) {
const unsigned int blocksize = 6;
const uint8 *itemlist;
int account_id;
- unsigned int count, packet_len, buyer_id;
+ unsigned int buyer_id;
+ int count, packet_len;
struct s_packet_db* info = &packet_db[RFIFOW(fd,0)];
packet_len = RFIFOW(fd,info->pos[0]);
if( packet_len < 12 )
{// minimum packet length
- ShowError("clif_parse_ReqTradeBuyingStore: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 12U, packet_len, sd->bl.id);
+ ShowError("clif_parse_ReqTradeBuyingStore: Malformed packet (expected length=%u, length=%d, account_id=%d).\n", 12U, packet_len, sd->bl.id);
return;
}
@@ -17220,10 +17308,12 @@ void clif_parse_ReqTradeBuyingStore(int fd, struct map_session_data* sd) {
// so that buyingstore_trade knows, how many elements it has access to
packet_len-= info->pos[3];
+ if (packet_len < 0)
+ return;
if( packet_len%blocksize )
{
- ShowError("clif_parse_ReqTradeBuyingStore: Unexpected item list size %u (account_id=%d, buyer_id=%d, block size=%u)\n", packet_len, sd->bl.id, account_id, blocksize);
+ ShowError("clif_parse_ReqTradeBuyingStore: Unexpected item list size %d (account_id=%d, buyer_id=%d, block size=%u)\n", packet_len, sd->bl.id, account_id, blocksize);
return;
}
count = packet_len/blocksize;
@@ -17342,14 +17432,15 @@ void clif_parse_SearchStoreInfo(int fd, struct map_session_data* sd) {
const uint8* itemlist;
const uint8* cardlist;
unsigned char type;
- unsigned int min_price, max_price, packet_len, count, item_count, card_count;
+ unsigned int min_price, max_price;
+ int packet_len, count, item_count, card_count;
struct s_packet_db* info = &packet_db[RFIFOW(fd,0)];
packet_len = RFIFOW(fd,info->pos[0]);
if( packet_len < 15 )
{// minimum packet length
- ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected length=%u, length=%u, account_id=%d).\n", 15U, packet_len, sd->bl.id);
+ ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected length=%u, length=%d, account_id=%d).\n", 15U, packet_len, sd->bl.id);
return;
}
@@ -17359,24 +17450,28 @@ void clif_parse_SearchStoreInfo(int fd, struct map_session_data* sd) {
item_count = RFIFOB(fd,info->pos[4]);
card_count = RFIFOB(fd,info->pos[5]);
itemlist = RFIFOP(fd,info->pos[6]);
- cardlist = RFIFOP(fd,info->pos[6]+blocksize*item_count);
// check, if there is enough data for the claimed count of items
packet_len-= info->pos[6];
+ if (packet_len < 0)
+ return;
+
if( packet_len%blocksize )
{
- ShowError("clif_parse_SearchStoreInfo: Unexpected item list size %u (account_id=%d, block size=%u)\n", packet_len, sd->bl.id, blocksize);
+ ShowError("clif_parse_SearchStoreInfo: Unexpected item list size %d (account_id=%d, block size=%u)\n", packet_len, sd->bl.id, blocksize);
return;
}
count = packet_len/blocksize;
if( count < item_count+card_count )
{
- ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected count=%u, count=%u, account_id=%d).\n", item_count+card_count, count, sd->bl.id);
+ ShowError("clif_parse_SearchStoreInfo: Malformed packet (expected count=%d, count=%d, account_id=%d).\n", item_count+card_count, count, sd->bl.id);
return;
}
+ cardlist = RFIFOP(fd, info->pos[6] + blocksize * item_count);
+
searchstore->query(sd, type, min_price, max_price, (const unsigned short*)itemlist, item_count, (const unsigned short*)cardlist, card_count);
}
@@ -17996,47 +18091,67 @@ void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd)
#endif
}
+/// R 0848 <len>.W <limit>.W <kafra pay>.L (<item id>.L <amount>.L <tab>.W)*
void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) {
- unsigned short limit = RFIFOW(fd, 4), i, j;
- unsigned int kafra_pay = RFIFOL(fd, 6);// [Ryuuzaki] - These are free cash points (strangely #CASH = main cash currently for us, confusing)
+ int len = RFIFOW(fd, 2);
+ unsigned short limit, i, j;
+ unsigned int kafra_pay;
+ int count;
if (map->list[sd->bl.m].flag.nocashshop) {
clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1489)); //Cash Shop is disabled in this map
return;
}
+ if (len < 10)
+ return;
+
+ limit = RFIFOW(fd, 4);
+ kafra_pay = RFIFOL(fd, 6); // [Ryuuzaki] - These are free cash points (strangely #CASH = main cash currently for us, confusing)
+ count = (len - 10) / 10;
+ if (count != limit) {
+ ShowError("Wrong cash shop limit: %d\n", limit);
+ return;
+ }
+
for(i = 0; i < limit; i++) {
int qty = RFIFOL(fd, 14 + ( i * 10 ));
int id = RFIFOL(fd, 10 + ( i * 10 ));
short tab = RFIFOW(fd, 18 + ( i * 10 ));
enum CASH_SHOP_BUY_RESULT result = CSBR_UNKNOWN;
- if( tab < 0 || tab >= CASHSHOP_TAB_MAX )
+ if(tab < 0 || tab >= CASHSHOP_TAB_MAX)
continue;
- for( j = 0; j < clif->cs.item_count[tab]; j++ ) {
+ for(j = 0; j < clif->cs.item_count[tab]; j++) {
if( clif->cs.data[tab][j]->id == id )
break;
}
- if( j < clif->cs.item_count[tab] ) {
+ if(j < clif->cs.item_count[tab]) {
struct item_data *data;
- if( sd->kafraPoints < kafra_pay ) {
+ if(sd->kafraPoints < kafra_pay) {
result = CSBR_SHORTTAGE_CASH;
- } else if( (sd->cashPoints+kafra_pay) < (clif->cs.data[tab][j]->price * qty) ) {
+ } else if((sd->cashPoints+kafra_pay) < (clif->cs.data[tab][j]->price * qty)) {
result = CSBR_SHORTTAGE_CASH;
- } else if ( !( data = itemdb->exists(clif->cs.data[tab][j]->id) ) ) {
+ } else if (!(data = itemdb->exists(clif->cs.data[tab][j]->id))) {
result = CSBR_UNKONWN_ITEM;
} else {
struct item item_tmp;
int k, get_count;
-
+ int ret = 0;
+
get_count = qty;
if (!itemdb->isstackable2(data))
get_count = 1;
-
- pc->paycash(sd, clif->cs.data[tab][j]->price * qty, kafra_pay);// [Ryuuzaki]
+
+ ret = pc->paycash(sd, clif->cs.data[tab][j]->price * qty, kafra_pay);// [Ryuuzaki] //changed Kafrapoints calculation. [Normynator]
+ if (ret < 0) {
+ ShowError("clif_parse_CashShopBuy: The return from pc->paycash was negative which is not allowed.\n");
+ break; //This should never happen.
+ }
+ kafra_pay = ret;
for (k = 0; k < qty; k += get_count) {
if (!pet->create_egg(sd, data->nameid)) {
memset(&item_tmp, 0, sizeof(item_tmp));
@@ -19360,10 +19475,10 @@ void clif_clan_basicinfo(struct map_session_data *sd)
len += NAME_LENGTH;
}
}
-
+
for (i = 0; i < VECTOR_LENGTH(c->antagonists); i++) {
struct clan_relationship *an = &VECTOR_INDEX(c->antagonists, i);
-
+
if ((antagonist = clan->search(an->clan_id)) != NULL) {
safestrncpy(WFIFOP(fd, len), antagonist->name, NAME_LENGTH);
len += NAME_LENGTH;
@@ -19386,7 +19501,7 @@ void clif_clan_onlinecount(struct clan *c)
struct PACKET_ZC_NOTIFY_CLAN_CONNECTINFO p;
nullpo_retv(c);
-
+
p.PacketType = clanOnlineCount;
p.NumConnect = c->connect_member;
p.NumTotal = c->max_member;
@@ -19512,7 +19627,7 @@ void clif_parse_rodex_open_write_mail(int fd, struct map_session_data *sd) __att
void clif_parse_rodex_open_write_mail(int fd, struct map_session_data *sd)
{
const struct PACKET_CZ_REQ_OPEN_WRITE_MAIL *rPacket = RFIFOP(fd, 0);
- int8 result = (rodex->isenabled() == true) ? 1 : 0;
+ int8 result = (rodex->isenabled() == true && sd->npc_id == 0) ? 1 : 0;
clif->rodex_open_write_mail(fd, rPacket->receiveName, result);
}
@@ -19722,7 +19837,7 @@ void clif_rodex_send_maillist(int fd, struct map_session_data *sd, int8 open_typ
continue;
inner->MailID = msg->id;
- inner->Isread = msg->is_read == true ? 1 : 0;
+ inner->Isread = (msg->is_read == true || msg->sender_read == true) ? 1 : 0;
inner->type = msg->type;
#if PACKETVER >= 20170419
inner->openType = msg->opentype;
@@ -19754,7 +19869,7 @@ void clif_rodex_send_maillist(int fd, struct map_session_data *sd, int8 open_typ
#endif
}
-void clif_rodex_send_mails_all(int fd, struct map_session_data *sd)
+void clif_rodex_send_mails_all(int fd, struct map_session_data *sd, int64 mail_id)
{
#if PACKETVER >= 20170419
struct PACKET_ZC_MAIL_LIST *packet;
@@ -19762,18 +19877,24 @@ void clif_rodex_send_mails_all(int fd, struct map_session_data *sd)
int16 size = sizeof(*packet);
int packetMailCount = 0;
int mailListCount = 0;
- int mailsSize = VECTOR_LENGTH(sd->rodex.messages);
- int i;
+ int mailsSize, i;
+ int j = -1;
nullpo_retv(sd);
+ mailsSize = VECTOR_LENGTH(sd->rodex.messages);
+
+ if (mail_id > 0)
+ ARR_FIND(0, VECTOR_LENGTH(sd->rodex.messages), j, (VECTOR_INDEX(sd->rodex.messages, j)).id == mail_id);
+
WFIFOHEAD(fd, sizeof(*packet) + (sizeof(*inner) + RODEX_TITLE_LENGTH) * RODEX_MAIL_PER_PAGE);
packet = WFIFOP(fd, 0);
packet->PacketType = rodexmailList;
inner = WFIFOP(fd, size);
i = mailsSize - 1;
- while (i >= 0) {
+ mailsSize -= (j + 1);
+ while (i > j) {
struct rodex_message *msg = &VECTOR_INDEX(sd->rodex.messages, i);
--i;
@@ -19781,7 +19902,7 @@ void clif_rodex_send_mails_all(int fd, struct map_session_data *sd)
continue;
inner->MailID = msg->id;
- inner->Isread = msg->is_read == true ? 1 : 0;
+ inner->Isread = (msg->is_read == true || msg->sender_read == true) ? 1 : 0;
inner->type = msg->type;
inner->openType = msg->opentype;
inner->expireDateTime = msg->expire_date - (int)time(NULL);
@@ -19848,7 +19969,7 @@ void clif_rodex_send_refresh(int fd, struct map_session_data *sd, int8 open_type
continue;
inner->MailID = msg->id;
- inner->Isread = msg->is_read == true ? 1 : 0;
+ inner->Isread = (msg->is_read == true || msg->sender_read == true) ? 1 : 0;
inner->type = msg->type;
#if PACKETVER >= 20170419
inner->openType = msg->opentype;
diff --git a/src/map/clif.h b/src/map/clif.h
index d6fbc3990..ba1a31187 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -110,7 +110,7 @@ typedef enum send_target {
BG_AREA_WOS,
BG_QUEUE,
-
+
CLAN, // Clan System
} send_target;
@@ -1389,7 +1389,7 @@ struct clif_interface {
void (*rodex_send_mail_result) (int fd, struct map_session_data *sd, int8 result);
void (*rodex_send_maillist) (int fd, struct map_session_data *sd, int8 open_type, int64 page_start);
void (*rodex_send_refresh) (int fd, struct map_session_data *sd, int8 open_type, int count);
- void (*rodex_send_mails_all) (int fd, struct map_session_data *sd);
+ void (*rodex_send_mails_all) (int fd, struct map_session_data *sd, int64 mail_id);
void (*pRodexReadMail) (int fd, struct map_session_data *sd);
void (*rodex_read_mail) (struct map_session_data *sd, int8 opentype, struct rodex_message *msg);
void (*pRodexNextMaillist) (int fd, struct map_session_data *sd);
diff --git a/src/map/intif.c b/src/map/intif.c
index c933ceb15..f656a0df9 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -751,7 +751,7 @@ int intif_party_leaderchange(int party_id,int account_id,int char_id)
/**
* Request clan member count
- *
+ *
* @param clan_id Id of the clan to have members counted
* @param kick_interval Interval of the inactivity kick
*/
@@ -759,7 +759,7 @@ int intif_clan_membercount(int clan_id, int kick_interval)
{
if (intif->CheckForCharServer() || clan_id == 0 || kick_interval <= 0)
return 0;
-
+
WFIFOHEAD(inter_fd, 10);
WFIFOW(inter_fd, 0) = 0x3044;
WFIFOL(inter_fd, 2) = clan_id;
@@ -791,7 +791,7 @@ void intif_parse_RecvClanMemberAction(int fd)
ShowError("intif_parse_RecvClanMemberAction: Received invalid clan_id '%d'\n", clan_id);
return;
}
-
+
if (count < 0) {
ShowError("intif_parse_RecvClanMemberAction: Received invalid member count value '%d'\n", count);
return;
@@ -2516,6 +2516,9 @@ void intif_parse_RequestRodexOpenInbox(int fd)
int8 is_end = RFIFOB(fd, 10);
int is_first = RFIFOB(fd, 11);
int count = RFIFOL(fd, 12);
+#if PACKETVER >= 20170419
+ int64 mail_id = RFIFOQ(fd, 16);
+#endif
int i, j;
sd = map->charid2sd(RFIFOL(fd, 4));
@@ -2533,15 +2536,15 @@ void intif_parse_RequestRodexOpenInbox(int fd)
else
sd->rodex.total += count;
- if (RFIFOW(fd, 2) - 16 != count * sizeof(struct rodex_message)) {
- ShowError("intif_parse_RodexInboxOpenReceived: data size mismatch %d != %"PRIuS"\n", RFIFOW(fd, 2) - 16, count * sizeof(struct rodex_message));
+ if (RFIFOW(fd, 2) - 24 != count * sizeof(struct rodex_message)) {
+ ShowError("intif_parse_RodexInboxOpenReceived: data size mismatch %d != %"PRIuS"\n", RFIFOW(fd, 2) - 24, count * sizeof(struct rodex_message));
return;
}
if (flag == 0 && is_first)
VECTOR_CLEAR(sd->rodex.messages);
- for (i = 0, j = 16; i < count; ++i, j += sizeof(struct rodex_message)) {
+ for (i = 0, j = 24; i < count; ++i, j += sizeof(struct rodex_message)) {
struct rodex_message msg = { 0 };
VECTOR_ENSURE(sd->rodex.messages, 1, 1);
memcpy(&msg, RFIFOP(fd, j), sizeof(struct rodex_message));
@@ -2550,7 +2553,7 @@ void intif_parse_RequestRodexOpenInbox(int fd)
if (is_end == true) {
#if PACKETVER >= 20170419
- clif->rodex_send_mails_all(sd->fd, sd);
+ clif->rodex_send_mails_all(sd->fd, sd, mail_id);
#else
if (flag == 0)
clif->rodex_send_maillist(sd->fd, sd, opentype, VECTOR_LENGTH(sd->rodex.messages) - 1);
@@ -2599,10 +2602,11 @@ void intif_parse_RodexNotifications(int fd)
/// Updates a mail
/// flag:
-/// 0 - user Read
-/// 1 - user got Zeny
-/// 2 - user got Items
-/// 3 - delete
+/// 0 - receiver Read
+/// 1 - user got Zeny
+/// 2 - user got Items
+/// 3 - delete
+/// 4 - sender Read (returned mail)
int intif_rodex_updatemail(int64 mail_id, int8 flag)
{
if (intif->CheckForCharServer())
diff --git a/src/map/map.c b/src/map/map.c
index 106224a47..780e6f535 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -66,6 +66,7 @@
#include "common/core.h"
#include "common/ers.h"
#include "common/grfio.h"
+#include "common/md5calc.h"
#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
@@ -2899,21 +2900,26 @@ int map_cell2gat(struct mapcell cell) {
ShowWarning("map_cell2gat: cell has no matching gat type\n");
return 1; // default to 'wall'
}
-void map_cellfromcache(struct map_data *m) {
- struct map_cache_map_info *info;
+/**
+ * Extracts a map's cell data from its compressed mapcache.
+ *
+ * @param[in, out] m The target map.
+ */
+void map_cellfromcache(struct map_data *m)
+{
nullpo_retv(m);
- info = (struct map_cache_map_info *)m->cellPos;
- if (info) {
+ if (m->cell_buf.data != NULL) {
char decode_buffer[MAX_MAP_SIZE];
unsigned long size, xy;
int i;
- size = (unsigned long)info->xs*(unsigned long)info->ys;
+ size = (unsigned long)m->xs * (unsigned long)m->ys;
// TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo]
- grfio->decode_zip(decode_buffer, &size, m->cellPos+sizeof(struct map_cache_map_info), info->len);
+ grfio->decode_zip(decode_buffer, &size, m->cell_buf.data, m->cell_buf.len);
+
CREATE(m->cell, struct mapcell, size);
// Set cell properties
@@ -3253,97 +3259,125 @@ int map_eraseipport(unsigned short map_index, uint32 ip, uint16 port) {
return 0;
}
-/*==========================================
- * [Shinryo]: Init the mapcache
- *------------------------------------------*/
-char *map_init_mapcache(FILE *fp) {
- struct map_cache_main_header header;
- size_t size = 0;
- char *buffer;
-
- // No file open? Return..
- nullpo_ret(fp);
+/**
+ * Reads a map's compressed cell data from its mapcache file.
+ *
+ * @param[in,out] m The target map.
+ * @return The loading success state.
+ * @retval false in case of errors.
+ */
+bool map_readfromcache(struct map_data *m)
+{
+ unsigned int file_size;
+ char file_path[256];
+ FILE *fp = NULL;
+ bool retval = false;
+ int16 version;
- // Get file size
- fseek(fp, 0, SEEK_END);
- size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
+ nullpo_retr(false, m);
- // Allocate enough space
- CREATE(buffer, char, size);
+ snprintf(file_path, sizeof(file_path), "%s%s%s.%s", "maps/", DBPATH, m->name, "mcache");
+ fp = fopen(file_path, "rb");
- // No memory? Return..
- nullpo_ret(buffer);
+ if (fp == NULL) {
+ ShowWarning("map_readfromcache: Could not open the mapcache file for map '%s' at path '%s'.\n", m->name, file_path);
+ return false;
+ }
- // Read file into buffer..
- if(fread(buffer, sizeof(char), size, fp) != size) {
- ShowError("map_init_mapcache: Could not read entire mapcache file\n");
- aFree(buffer);
- return NULL;
+ if (fread(&version, sizeof(version), 1, fp) < 1) {
+ ShowError("map_readfromcache: Could not read file version for map '%s'.\n", m->name);
+ fclose(fp);
+ return false;
}
- rewind(fp);
+ fseek(fp, 0, SEEK_END);
+ file_size = (unsigned int)ftell(fp);
+ fseek(fp, 0, SEEK_SET); // Rewind file pointer before passing it to the read function.
- // Get main header to verify if data is corrupted
- if( fread(&header, sizeof(header), 1, fp) != 1 ) {
- ShowError("map_init_mapcache: Error obtaining main header!\n");
- aFree(buffer);
- return NULL;
- }
- if( GetULong((unsigned char *)&(header.file_size)) != size ) {
- ShowError("map_init_mapcache: Map cache is corrupted!\n");
- aFree(buffer);
- return NULL;
+ switch(version) {
+ case 1:
+ retval = map->readfromcache_v1(fp, m, file_size);
+ break;
+ default:
+ ShowError("map_readfromcache: Mapcache file has unknown version '%d' for map '%s'.\n", version, m->name);
+ break;
}
- return buffer;
+ fclose(fp);
+ return retval;
}
-/*==========================================
- * Map cache reading
- * [Shinryo]: Optimized some behaviour to speed this up
- *==========================================*/
-int map_readfromcache(struct map_data *m, char *buffer) {
- int i;
- struct map_cache_main_header *header = (struct map_cache_main_header *)buffer;
- struct map_cache_map_info *info = NULL;
- char *p = buffer + sizeof(struct map_cache_main_header);
-
- nullpo_ret(m);
- nullpo_ret(buffer);
-
- for(i = 0; i < header->map_count; i++) {
- info = (struct map_cache_map_info *)p;
+/**
+ * Reads a map's compressed cell data from its mapcache file (file format
+ * version 1).
+ *
+ * @param[in] fp The file pointer to read from (opened and closed by
+ * the caller).
+ * @param[in,out] m The target map.
+ * @param[in] file_size The size of the file to load from.
+ * @return The loading success state.
+ * @retval false in case of errors.
+ */
+bool map_readfromcache_v1(FILE *fp, struct map_data *m, unsigned int file_size)
+{
+ struct map_cache_header mheader = { 0 };
+ uint8 md5buf[16] = { 0 };
+ int map_size;
+ nullpo_retr(false, fp);
+ nullpo_retr(false, m);
+
+ if (file_size <= sizeof(mheader) || fread(&mheader, sizeof(mheader), 1, fp) < 1) {
+ ShowError("map_readfromcache: Failed to read cache header for map '%s'.\n", m->name);
+ return false;
+ }
- if( strcmp(m->name, info->name) == 0 )
- break; // Map found
+ if (mheader.len <= 0) {
+ ShowError("map_readfromcache: A file with negative or zero compressed length passed '%d'.\n", mheader.len);
+ return false;
+ }
- // Jump to next entry..
- p += sizeof(struct map_cache_map_info) + info->len;
+ if (file_size < sizeof(mheader) + mheader.len) {
+ ShowError("map_readfromcache: An incomplete file passed for map '%s'.\n", m->name);
+ return false;
}
- if( info && i < header->map_count ) {
- unsigned long size;
+ if (mheader.ys <= 0 || mheader.xs <= 0) {
+ ShowError("map_readfromcache: A map with invalid size passed '%s' xs: '%d' ys: '%d'.\n", m->name, mheader.xs, mheader.ys);
+ return false;
+ }
- if( info->xs <= 0 || info->ys <= 0 )
- return 0;// Invalid
+ m->xs = mheader.xs;
+ m->ys = mheader.ys;
+ map_size = (int)mheader.xs * (int)mheader.ys;
- m->xs = info->xs;
- m->ys = info->ys;
- size = (unsigned long)info->xs*(unsigned long)info->ys;
+ if (map_size > MAX_MAP_SIZE) {
+ ShowWarning("map_readfromcache: %s exceeded MAX_MAP_SIZE of %d.\n", m->name, MAX_MAP_SIZE);
+ return false;
+ }
- if(size > MAX_MAP_SIZE) {
- ShowWarning("map_readfromcache: %s exceeded MAX_MAP_SIZE of %d\n", info->name, MAX_MAP_SIZE);
- return 0; // Say not found to remove it from list.. [Shinryo]
- }
+ CREATE(m->cell_buf.data, uint8, mheader.len);
+ m->cell_buf.len = mheader.len;
+ if (fread(m->cell_buf.data, mheader.len, 1, fp) < 1) {
+ ShowError("mapreadfromcache: Could not load the compressed cell data for map '%s'.\n", m->name);
+ aFree(m->cell_buf.data);
+ m->cell_buf.data = NULL;
+ m->cell_buf.len = 0;
+ return false;
+ }
- m->cellPos = p;
- m->cell = (struct mapcell *)0xdeadbeaf;
+ md5->binary(m->cell_buf.data, m->cell_buf.len, md5buf);
- return 1;
+ if (memcmp(md5buf, mheader.md5_checksum, sizeof(md5buf)) != 0) {
+ ShowError("mapreadfromcache: md5 checksum check failed for map '%s'\n", m->name);
+ aFree(m->cell_buf.data);
+ m->cell_buf.data = NULL;
+ m->cell_buf.len = 0;
+ return false;
}
- return 0; // Not found
+ m->cell = (struct mapcell *)0xdeadbeaf;
+
+ return true;
}
/**
@@ -3747,26 +3781,12 @@ void map_removemapdb(struct map_data *m) {
*--------------------------------------*/
int map_readallmaps (void) {
int i;
- FILE* fp=NULL;
int maps_removed = 0;
- if( map->enable_grf )
+ if (map->enable_grf) {
ShowStatus("Loading maps (using GRF files)...\n");
- else {
- char mapcachefilepath[256];
- safesnprintf(mapcachefilepath, 256, "%s/%s%s", map->db_path, DBPATH, "map_cache.dat");
- ShowStatus("Loading maps (using %s as map cache)...\n", mapcachefilepath);
- if( (fp = fopen(mapcachefilepath, "rb")) == NULL ) {
- ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", mapcachefilepath);
- exit(EXIT_FAILURE); //No use launching server if maps can't be read.
- }
-
- // Init mapcache data.. [Shinryo]
- map->cache_buffer = map->init_mapcache(fp);
- if(!map->cache_buffer) {
- ShowFatalError("Failed to initialize mapcache data (%s)..\n", mapcachefilepath);
- exit(EXIT_FAILURE);
- }
+ } else {
+ ShowStatus("Loading maps using map cache files...\n");
}
for(i = 0; i < map->count; i++) {
@@ -3780,7 +3800,7 @@ int map_readallmaps (void) {
if( !
(map->enable_grf?
map->readgat(&map->list[i])
- :map->readfromcache(&map->list[i], map->cache_buffer))
+ :map->readfromcache(&map->list[i]))
) {
map->delmapid(i);
maps_removed++;
@@ -3822,10 +3842,6 @@ int map_readallmaps (void) {
// intialization and configuration-dependent adjustments of mapflags
map->flags_init();
- if( !map->enable_grf ) {
- fclose(fp);
- }
-
// finished map loading
ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps."CL_CLL"\n",map->count);
instance->start_id = map->count; // Next Map Index will be instances
@@ -4502,6 +4518,8 @@ void map_zone_change2(int m, struct map_zone_data *zone)
{
const char *empty = "";
+ if (zone == NULL)
+ return;
Assert_retv(m >= 0 && m < map->count);
if( map->list[m].zone == zone )
return;
@@ -6060,6 +6078,11 @@ int do_final(void) {
ers_destroy(map->iterator_ers);
ers_destroy(map->flooritem_ers);
+ for (i = 0; i < map->count; ++i) {
+ if (map->list[i].cell_buf.data != NULL)
+ aFree(map->list[i].cell_buf.data);
+ map->list[i].cell_buf.len = 0;
+ }
aFree(map->list);
if( map->block_free )
@@ -6067,9 +6090,6 @@ int do_final(void) {
if( map->bl_list )
aFree(map->bl_list);
- if( !map->enable_grf )
- aFree(map->cache_buffer);
-
aFree(map->MAP_CONF_NAME);
aFree(map->BATTLE_CONF_FILENAME);
aFree(map->ATCOMMAND_CONF_FILENAME);
@@ -6685,7 +6705,6 @@ void map_defaults(void) {
map->list = NULL;
map->iterator_ers = NULL;
- map->cache_buffer = NULL;
map->flooritem_ers = NULL;
/* */
@@ -6832,8 +6851,8 @@ void map_defaults(void) {
map->iwall_nextxy = map_iwall_nextxy;
map->create_map_data_other_server = create_map_data_other_server;
map->eraseallipport_sub = map_eraseallipport_sub;
- map->init_mapcache = map_init_mapcache;
map->readfromcache = map_readfromcache;
+ map->readfromcache_v1 = map_readfromcache_v1;
map->addmap = map_addmap;
map->delmapid = map_delmapid;
map->zone_db_clear = map_zone_db_clear;
diff --git a/src/map/map.h b/src/map/map.h
index facf1d921..5c4c6d59d 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -909,7 +909,10 @@ struct map_data {
/* */
int (*getcellp)(struct map_data* m, const struct block_list *bl, int16 x, int16 y, cell_chk cellchk);
void (*setcell) (int16 m, int16 x, int16 y, cell_t cell, bool flag);
- char *cellPos;
+ struct {
+ uint8 *data;
+ int len;
+ } cell_buf;
/* ShowEvent Data Cache */
struct questinfo *qi_data;
@@ -1064,20 +1067,20 @@ struct charid2nick {
struct charid_request* requests;// requests of notification on this nick
};
-// This is the main header found at the very beginning of the map cache
-struct map_cache_main_header {
- uint32 file_size;
- uint16 map_count;
-};
-
-// This is the header appended before every compressed map cells info in the map cache
-struct map_cache_map_info {
- char name[MAP_NAME_LENGTH];
+// New mcache file format header
+#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
+#pragma pack(push, 1)
+#endif // not NetBSD < 6 / Solaris
+struct map_cache_header {
+ int16 version;
+ uint8 md5_checksum[16];
int16 xs;
int16 ys;
int32 len;
-};
-
+} __attribute__((packed));
+#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
+#pragma pack(pop)
+#endif // not NetBSD < 6 / Solaris
/*=====================================
* Interface : map.h
@@ -1167,7 +1170,6 @@ END_ZEROED_BLOCK;
struct map_data *list;
/* [Ind/Hercules] */
struct eri *iterator_ers;
- char *cache_buffer; // Has the uncompressed gat data of all maps, so just one allocation has to be made
/* */
struct eri *flooritem_ers;
/* */
@@ -1317,8 +1319,8 @@ END_ZEROED_BLOCK;
void (*iwall_nextxy) (int16 x, int16 y, int8 dir, int pos, int16 *x1, int16 *y1);
struct DBData (*create_map_data_other_server) (union DBKey key, va_list args);
int (*eraseallipport_sub) (union DBKey key, struct DBData *data, va_list va);
- char* (*init_mapcache) (FILE *fp);
- int (*readfromcache) (struct map_data *m, char *buffer);
+ bool (*readfromcache) (struct map_data *m);
+ bool (*readfromcache_v1) (FILE *fp, struct map_data *m, unsigned int file_size);
int (*addmap) (const char *mapname);
void (*delmapid) (int id);
void (*zone_db_clear) (void);
diff --git a/src/map/packets.h b/src/map/packets.h
index ad677728a..d18abf4da 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -3987,4 +3987,84 @@ packet(0x96e,-1,clif->ackmergeitems);
#endif
#endif
+#ifdef PACKETVER_ZERO
+// 2018-01-31dRagexe_zero
+#if PACKETVER >= 20180131
+// new packets
+ packet(0x0af2,40,clif->pDull/*,XXX*/);
+ packet(0x0af3,-1,clif->pDull/*,XXX*/);
+ packet(0x0af4,11,clif->pDull/*,XXX*/);
+// changed packet sizes
+ packet(0x0ae6,10,clif->pDull/*,XXX*/);
+#endif
+#endif // PACKETVER_ZERO
+
+#if PACKETVER >= 20180131
+// changed packet sizes
+ packet(0x0821,102); // AC_OTP_USER
+#endif
+
+#ifdef PACKETVER_ZERO
+// 2018-02-07bRagexe_zero
+#if PACKETVER >= 20180207
+// new packets
+ packet(0x0af5,3);
+ packet(0x0af6,88);
+ packet(0x0af7,32);
+// changed packet sizes
+#endif
+#else // PACKETVER_ZERO
+// 2018-02-07bRagexeRE, 2018-02-07bRagexe
+#if PACKETVER >= 20180207
+// new packets
+ packet(0x0af4,11);
+ packet(0x0af5,3);
+ packet(0x0af6,88);
+ packet(0x0af7,32);
+// changed packet sizes
+ packet(0x0ae6,10);
+#endif
+#endif // PACKETVER_ZERO
+
+#ifdef PACKETVER_RE
+// 2018-02-21aRagexeRE
+#if PACKETVER >= 20180221
+// new packets
+// changed packet sizes
+ packet(0x0206,35); // ZC_FRIENDS_STATE
+#endif
+#endif // PACKETVER_RE
+
+#ifndef PACKETVER_ZERO
+// 2018-03-07bRagexe
+#if PACKETVER >= 20180307
+// new packets
+// changed packet sizes
+ packet(0x0206,35); // ZC_FRIENDS_STATE
+#endif
+#endif // PACKETVER_ZERO
+
+#ifndef PACKETVER_ZERO
+// 2018-03-21aRagexe, 2018-03-21aRagexeRE
+#if PACKETVER >= 20180321
+// new packets
+ packet(0x0af8,11,clif->pDull/*,XXX*/);
+// changed packet sizes
+ packet(0x0ae7,34,clif->pDull/*,XXX*/);
+#endif
+#endif // PACKETVER_ZERO
+
+#ifdef PACKETVER_ZERO
+// 2018-03-28_1aRagexe_zero
+#if PACKETVER >= 20180328
+// new packets
+ packet(0x0af8,11,clif->pDull/*,XXX*/);
+ packet(0x0af9,6,clif->pDull/*,XXX*/);
+ packet(0x0afa,54,clif->pDull/*,XXX*/);
+// changed packet sizes
+ packet(0x0206,35); // ZC_FRIENDS_STATE
+ packet(0x0ae7,38,clif->pDull/*,XXX*/);
+#endif
+#endif // PACKETVER_ZERO
+
#endif /* MAP_PACKETS_H */
diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h
index afaf62e2d..8d20780d4 100644
--- a/src/map/packets_keys_main.h
+++ b/src/map/packets_keys_main.h
@@ -874,11 +874,14 @@
packetKeys(0x6A596301,0x76866D0E,0x32294A45);
#endif
-// 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe
+// 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE
#if PACKETVER == 20131223 || \
PACKETVER == 20140508 || \
PACKETVER == 20140611 || \
- PACKETVER == 20150225
+ PACKETVER == 20150225 || \
+ PACKETVER == 20180315 || \
+ PACKETVER == 20180321 || \
+ PACKETVER == 20180328
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
@@ -1949,10 +1952,37 @@
packetKeys(0x21F477F4,0x37F437F4,0x37F437F4);
#endif
-// 2018-01-24bRagexe, 2018-01-24bRagexeRE
-#if PACKETVER == 20180124
+// 2018-01-24bRagexe, 2018-01-24bRagexeRE, 2018-01-31Ragexe
+#if PACKETVER == 20180124 || \
+ PACKETVER == 20180131
packetKeys(0x7EAA1CE0,0x415D1CFD,0x4C8F19FA);
#endif
+// 2018-02-07bRagexe, 2018-02-07bRagexeRE, 2018-02-07cRagexe
+#if PACKETVER == 20180207
+ packetKeys(0x45AA1B44,0x20E716B7,0x5388105C);
+#endif
+
+// 2018-02-13aRagexe, 2018-02-13aRagexeRE, 2018-02-13bRagexe
+#if PACKETVER == 20180213
+ packetKeys(0x189D69B2,0x43B85EAD,0x2B7A687E);
+#endif
+
+// 2018-02-21aRagexeRE, 2018-02-21bRagexe, 2018-02-21bRagexeRE
+#if PACKETVER == 20180221
+ packetKeys(0x6E2F6233,0x193B0A66,0x0D1D2CA5);
+#endif
+
+// 2018-03-07bRagexe, 2018-03-07bRagexeRE, 2018-03-09aRagexe
+#if PACKETVER == 20180307 || \
+ PACKETVER == 20180309
+ packetKeys(0x47DA10EB,0x4B922CCF,0x765C5055);
+#endif
+
+// 2018-03-14nRagexe
+#if PACKETVER == 20180314
+ packetKeys(0x2FF07149,0x00596EA3,0x2B853026);
+#endif
+
#endif /* MAP_PACKETS_MAIN_KEYS_H */
diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h
index 93c917559..2bd6f1604 100644
--- a/src/map/packets_keys_zero.h
+++ b/src/map/packets_keys_zero.h
@@ -29,7 +29,7 @@
/* This file is autogenerated, please do not commit manual changes */
-// 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero
+// 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero
#if PACKETVER == 20171019 || \
PACKETVER == 20171023 || \
PACKETVER == 20171024 || \
@@ -38,7 +38,10 @@
PACKETVER == 20171030 || \
PACKETVER == 20171031 || \
PACKETVER == 20171109 || \
- PACKETVER == 20171113
+ PACKETVER == 20171113 || \
+ PACKETVER == 20180315 || \
+ PACKETVER == 20180321 || \
+ PACKETVER == 20180328
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
@@ -114,5 +117,37 @@
packetKeys(0x230959EB,0x1CCB0182,0x1FFA2B30);
#endif
+// 2018-01-31dRagexe_zero
+#if PACKETVER == 20180131
+ packetKeys(0x1F422E02,0x12025202,0x52025202);
+#endif
+
+// 2018-02-07bRagexe_zero
+#if PACKETVER == 20180207
+ packetKeys(0x07CB29CB,0x69CB69CB,0x69CB69CB);
+#endif
+
+// 2018-02-13aRagexe_zero
+#if PACKETVER == 20180213
+ packetKeys(0x0513075E,0x347075AF,0x67C56C6F);
+#endif
+
+// 2018-02-21aRagexe_zero
+#if PACKETVER == 20180221
+ packetKeys(0x28ED7635,0x76591F21,0x59383498);
+#endif
+
+// 2018-02-28bRagexe_zero, 2018-03-07aRagexe_zero, 2018-03-09aRagexe_zero
+#if PACKETVER == 20180228 || \
+ PACKETVER == 20180307 || \
+ PACKETVER == 20180309
+ packetKeys(0x56C82ABE,0x61AE2B2E,0x472E272E);
+#endif
+
+// 2018-03-14nRagexe_zero
+#if PACKETVER == 20180314
+ packetKeys(0x2FC330DD,0x01C04E1F,0x4D914DE2);
+#endif
+
#endif /* MAP_PACKETS_ZERO_KEYS_H */
diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h
index c30f4296b..d1f9a2062 100644
--- a/src/map/packets_shuffle_main.h
+++ b/src/map/packets_shuffle_main.h
@@ -3178,10 +3178,13 @@
packet(0x096a,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
#endif
-// 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe
+// 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE
#if PACKETVER == 20140508 || \
PACKETVER == 20140611 || \
- PACKETVER == 20150225
+ PACKETVER == 20150225 || \
+ PACKETVER == 20180315 || \
+ PACKETVER == 20180321 || \
+ PACKETVER == 20180328
packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
@@ -9500,8 +9503,9 @@
packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
#endif
-// 2018-01-24bRagexe, 2018-01-24bRagexeRE
-#if PACKETVER == 20180124
+// 2018-01-24bRagexe, 2018-01-24bRagexeRE, 2018-01-31Ragexe
+#if PACKETVER == 20180124 || \
+ PACKETVER == 20180131
packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
@@ -9533,5 +9537,171 @@
packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
#endif
+// 2018-02-07bRagexe, 2018-02-07bRagexeRE, 2018-02-07cRagexe
+#if PACKETVER == 20180207
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0360,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0870,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0881,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x092c,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x092e,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0940,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0950,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2018-02-13aRagexe, 2018-02-13aRagexeRE, 2018-02-13bRagexe
+#if PACKETVER == 20180213
+ packet(0x0369,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0802,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0817,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x085a,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x086f,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0874,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0875,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0878,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x087b,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0882,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x088c,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0892,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0898,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x089c,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x08a3,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x08a5,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x08a9,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x08ad,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0917,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0922,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0924,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0926,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0933,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0936,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x093c,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0943,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0955,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x095a,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0962,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+#endif
+
+// 2018-02-21aRagexeRE, 2018-02-21bRagexe, 2018-02-21bRagexeRE
+#if PACKETVER == 20180221
+ packet(0x0202,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0366,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0436,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0838,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0867,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x086c,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x086f,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0871,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0876,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0879,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x087d,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0880,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0881,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0883,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x088f,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0891,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0897,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0899,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x089d,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0917,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x091e,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0929,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x093d,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x094b,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x094d,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x094e,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0957,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0964,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x096a,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+#endif
+
+// 2018-03-07bRagexe, 2018-03-07bRagexeRE, 2018-03-09aRagexe
+#if PACKETVER == 20180307 || \
+ PACKETVER == 20180309
+ packet(0x0281,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x035f,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0437,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x07e4,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0861,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0862,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0864,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x086c,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0870,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0872,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0877,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x088d,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0893,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x089b,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x08a6,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x08aa,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x08ab,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0917,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0920,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0937,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0939,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x093d,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0941,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0944,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0948,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0951,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0954,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0957,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0969,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+#endif
+
+// 2018-03-14nRagexe
+#if PACKETVER == 20180314
+ packet(0x0361,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0366,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0369,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0436,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x085a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0862,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0863,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0868,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x086e,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0874,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x087a,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0888,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x088a,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x088d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0894,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x089b,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0921,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0927,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x092f,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0933,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0935,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0945,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x094d,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x094e,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0956,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0959,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x095f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0962,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0967,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+#endif
+
#endif /* MAP_PACKETS_SHUFFLE_MAIN_H */
diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h
index 01facb96b..7cd52d971 100644
--- a/src/map/packets_shuffle_zero.h
+++ b/src/map/packets_shuffle_zero.h
@@ -36,7 +36,7 @@
/* This file is autogenerated, please do not commit manual changes */
-// 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero
+// 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero
#if PACKETVER == 20171019 || \
PACKETVER == 20171023 || \
PACKETVER == 20171024 || \
@@ -45,7 +45,10 @@
PACKETVER == 20171030 || \
PACKETVER == 20171031 || \
PACKETVER == 20171109 || \
- PACKETVER == 20171113
+ PACKETVER == 20171113 || \
+ PACKETVER == 20180315 || \
+ PACKETVER == 20180321 || \
+ PACKETVER == 20180328
packet(0x0202,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
packet(0x022d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
packet(0x023b,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
@@ -485,5 +488,205 @@
packet(0x0963,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
#endif
+// 2018-01-31dRagexe_zero
+#if PACKETVER == 20180131
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0367,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0940,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2018-02-07bRagexe_zero
+#if PACKETVER == 20180207
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0967,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2018-02-13aRagexe_zero
+#if PACKETVER == 20180213
+ packet(0x022d,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x02c4,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x035f,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0361,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0802,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0815,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0838,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x085a,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x085d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0868,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x087b,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0882,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0887,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0888,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x088a,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x088e,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0899,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0917,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x091d,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0922,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0930,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0941,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0942,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0947,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x094d,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0958,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x095b,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x095c,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0967,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+#endif
+
+// 2018-02-21aRagexe_zero
+#if PACKETVER == 20180221
+ packet(0x02c4,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0362,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0364,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0438,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0817,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x085b,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x086a,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0878,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0880,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0884,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x088d,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0892,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0895,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x08a1,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x08a3,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x091b,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0921,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0923,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x092d,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0932,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x093b,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x093d,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x093e,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0942,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0951,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0952,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0958,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0959,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x095d,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+#endif
+
+// 2018-02-28bRagexe_zero, 2018-03-07aRagexe_zero, 2018-03-09aRagexe_zero
+#if PACKETVER == 20180228 || \
+ PACKETVER == 20180307 || \
+ PACKETVER == 20180309
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0930,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2018-03-14nRagexe_zero
+#if PACKETVER == 20180314
+ packet(0x023b,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0438,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x07ec,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x083c,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x085d,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x085f,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0866,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0878,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x088d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0891,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0897,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0899,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x089e,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x08a1,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0917,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0918,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x091f,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0920,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0923,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0930,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0931,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x093f,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0946,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x094a,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x094e,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0954,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0956,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0958,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+#endif
+
#endif /* MAP_PACKETS_SHUFFLE_ZERO_H */
diff --git a/src/map/pc.c b/src/map/pc.c
index cf3444538..4404101b9 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1525,7 +1525,7 @@ int pc_reg_received(struct map_session_data *sd)
status_calc_pc(sd,SCO_FIRST|SCO_FORCE);
chrif->scdata_request(sd->status.account_id, sd->status.char_id);
-
+
if (sd->status.clan_id)
clan->member_online(sd, true);
@@ -4449,46 +4449,54 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
return 0;
}
-/*==========================================
- * Cash Shop
- *------------------------------------------*/
+/**
+ * Calculates leftover cashpoints and kafrapoints when buying an item from cashshop
+ *
+ * @param price Price of the item.
+ * @param points Provided kafra points.
+ *
+ * @return points Leftover kafra points.
+ */
+//Changed Kafrapoints calculation. [Normynator]
int pc_paycash(struct map_session_data *sd, int price, int points)
{
int cash;
- nullpo_retr(-1,sd);
+ int mempoints;
+ nullpo_retr(-1, sd);
- points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB
- if( price < 0 || points < 0 )
- {
+ points = cap_value(points, -MAX_ZENY, MAX_ZENY); //prevent command UB
+ if (price < 0 || points < 0) {
ShowError("pc_paycash: Paying negative points (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
return -2;
}
- if( points > price )
- {
+ if (points > price) {
ShowWarning("pc_paycash: More kafra points provided than needed (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
- points = price;
+ points = points - price;
+ mempoints = price;
+ cash = 0;
+ } else {
+ cash = price - points;
+ mempoints = points;
+ points = 0;
}
- cash = price-points;
-
- if( sd->cashPoints < cash || sd->kafraPoints < points )
- {
+ if (sd->cashPoints < cash || sd->kafraPoints < mempoints) {
ShowError("pc_paycash: Not enough points (cash=%d, kafra=%d) to cover the price (cash=%d, kafra=%d) (account_id=%d, char_id=%d).\n", sd->cashPoints, sd->kafraPoints, cash, points, sd->status.account_id, sd->status.char_id);
return -1;
}
- pc_setaccountreg(sd, script->add_str("#CASHPOINTS"), sd->cashPoints-cash);
- pc_setaccountreg(sd, script->add_str("#KAFRAPOINTS"), sd->kafraPoints-points);
+ pc_setaccountreg(sd, script->add_str("#CASHPOINTS"), sd->cashPoints - cash);
+ pc_setaccountreg(sd, script->add_str("#KAFRAPOINTS"), sd->kafraPoints - mempoints);
- if( battle_config.cashshop_show_points )
- {
+ if (battle_config.cashshop_show_points) {
char output[128];
sprintf(output, msg_sd(sd,504), points, cash, sd->kafraPoints, sd->cashPoints);
clif_disp_onlyself(sd, output);
}
- return cash+points;
+
+ return points;
}
int pc_getcash(struct map_session_data *sd, int cash, int points)
diff --git a/src/map/rodex.c b/src/map/rodex.c
index dcecb6b8f..0e9e4ee2a 100644
--- a/src/map/rodex.c
+++ b/src/map/rodex.c
@@ -216,11 +216,11 @@ void rodex_check_player(struct map_session_data *sd, const char *name, int *base
/// @param title : Mail Title
/// @param zeny : Amount of zeny attached
/// Returns result code:
-/// RODEX_SEND_MAIL_SUCCESS = 0,
-/// RODEX_SEND_MAIL_FATAL_ERROR = 1,
-/// RODEX_SEND_MAIL_COUNT_ERROR = 2,
-/// RODEX_SEND_MAIL_ITEM_ERROR = 3,
-/// RODEX_SEND_MAIL_RECEIVER_ERROR = 4
+/// RODEX_SEND_MAIL_SUCCESS = 0,
+/// RODEX_SEND_MAIL_FATAL_ERROR = 1,
+/// RODEX_SEND_MAIL_COUNT_ERROR = 2,
+/// RODEX_SEND_MAIL_ITEM_ERROR = 3,
+/// RODEX_SEND_MAIL_RECEIVER_ERROR = 4
int rodex_send_mail(struct map_session_data *sd, const char *receiver_name, const char *body, const char *title, int64 zeny)
{
int i;
@@ -231,6 +231,11 @@ int rodex_send_mail(struct map_session_data *sd, const char *receiver_name, cons
nullpo_retr(RODEX_SEND_MAIL_FATAL_ERROR, body);
nullpo_retr(RODEX_SEND_MAIL_FATAL_ERROR, title);
+ if (!rodex->isenabled() || sd->npc_id > 0) {
+ rodex->clean(sd, 1);
+ return RODEX_SEND_MAIL_FATAL_ERROR;
+ }
+
if (zeny < 0) {
rodex->clean(sd, 1);
return RODEX_SEND_MAIL_FATAL_ERROR;
@@ -364,15 +369,24 @@ struct rodex_message *rodex_get_mail(struct map_session_data *sd, int64 mail_id)
{
int i;
struct rodex_message *msg;
+ int char_id;
nullpo_retr(NULL, sd);
- ARR_FIND(0, VECTOR_LENGTH(sd->rodex.messages), i, VECTOR_INDEX(sd->rodex.messages, i).id == mail_id && VECTOR_INDEX(sd->rodex.messages, i).is_deleted != true);
+ ARR_FIND(0, VECTOR_LENGTH(sd->rodex.messages), i, VECTOR_INDEX(sd->rodex.messages, i).id == mail_id);
if (i == VECTOR_LENGTH(sd->rodex.messages))
return NULL;
msg = &VECTOR_INDEX(sd->rodex.messages, i);
+ char_id = sd->status.char_id;
+
+ if ((msg->is_deleted == true)
+ || (msg->expire_date < time(NULL) && ((msg->receiver_accountid > 0) || (msg->receiver_id == char_id && msg->sender_id != char_id)))
+ || ((msg->send_date + 2 * RODEX_EXPIRE) < time(NULL))
+ )
+ return NULL;
+
return msg;
}
@@ -388,9 +402,16 @@ void rodex_read_mail(struct map_session_data *sd, int64 mail_id)
msg = rodex->get_mail(sd, mail_id);
nullpo_retv(msg);
- if (msg->is_read == false) {
- intif->rodex_updatemail(msg->id, 0);
- msg->is_read = true;
+ if (msg->opentype == RODEX_OPENTYPE_RETURN) {
+ if (msg->sender_read == false) {
+ intif->rodex_updatemail(msg->id, 4);
+ msg->sender_read = true;
+ }
+ } else {
+ if (msg->is_read == false) {
+ intif->rodex_updatemail(msg->id, 0);
+ msg->is_read = true;
+ }
}
clif->rodex_read_mail(sd, msg->opentype, msg);
@@ -440,6 +461,7 @@ void rodex_get_zeny(struct map_session_data *sd, int8 opentype, int64 mail_id)
return;
}
+ msg->type &= ~MAIL_TYPE_ZENY;
msg->zeny = 0;
intif->rodex_updatemail(mail_id, 1);
@@ -523,6 +545,8 @@ void rodex_get_items(struct map_session_data *sd, int8 opentype, int64 mail_id)
}
}
+ msg->type &= ~MAIL_TYPE_ITEM;
+ msg->items_count = 0;
intif->rodex_updatemail(mail_id, 2);
clif->rodex_request_items(sd, opentype, mail_id, RODEX_GET_ITEMS_SUCCESS);
@@ -532,8 +556,8 @@ void rodex_get_items(struct map_session_data *sd, int8 opentype, int64 mail_id)
/// - should be called everytime we're going to stop using rodex in this character
/// @param sd : Target to clean
/// @param flag :
-/// 0 - clear everything
-/// 1 - clear tmp only
+/// 0 - clear everything
+/// 1 - clear tmp only
void rodex_clean(struct map_session_data *sd, int8 flag)
{
nullpo_retv(sd);
diff --git a/src/map/script.c b/src/map/script.c
index 58083a3a2..275601dcc 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -8284,7 +8284,7 @@ BUILDIN(makeitem2)
map->search_freecell(NULL, m, &x, &y, -1, -1, 1);
} else {
range = (script_hasdata(st, 14) ? cap_value(script_getnum(st, 14), 1, battle_config.area_size) : 3);
- map->search_freecell(&sd->bl, sd->bl.m, &x, &y, range, range, 0); // Locate spot next to player.
+ map->search_freecell(&sd->bl, sd->bl.m, &x, &y, range, range, 0); // Locate spot next to player.
}
}
@@ -8635,7 +8635,7 @@ BUILDIN(readparam) {
BUILDIN(getcharid) {
int num = script_getnum(st, 2);
struct map_session_data *sd;
-
+
if (script_hasdata(st, 3))
sd = map->nick2sd(script_getstr(st, 3));
else
@@ -8647,22 +8647,22 @@ BUILDIN(getcharid) {
}
switch (num) {
- case 0:
+ case 0:
script_pushint(st, sd->status.char_id);
break;
- case 1:
+ case 1:
script_pushint(st, sd->status.party_id);
break;
- case 2:
+ case 2:
script_pushint(st, sd->status.guild_id);
break;
- case 3:
+ case 3:
script_pushint(st, sd->status.account_id);
break;
- case 4:
+ case 4:
script_pushint(st, sd->bg_id);
break;
- case 5:
+ case 5:
script_pushint(st, sd->status.clan_id);
break;
default:
@@ -12815,12 +12815,12 @@ enum mapinfo_info {
BUILDIN(getmapinfo)
{
enum mapinfo_info mode = script_getnum(st, 2);
- int16 m;
+ int16 m = -1;
if (script_hasdata(st, 3)) {
if (script_isstringtype(st, 3)) {
const char *str = script_getstr(st, 3);
- m = map->mapname2mapid(str);
+ m = map->mapindex2mapid(strdb_iget(mapindex->db, str));
} else {
m = script_getnum(st, 3);
}
@@ -23943,7 +23943,7 @@ BUILDIN(clan_master)
{
struct npc_data *nd = map->id2nd(st->oid);
int clan_id = script_getnum(st, 2);
-
+
if (nd == NULL) {
script_pushint(st, false);
return false;
@@ -24700,7 +24700,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(clan_join,"i?"),
BUILDIN_DEF(clan_leave,"?"),
BUILDIN_DEF(clan_master,"i"),
-
+
BUILDIN_DEF(channelmes, "ss"),
BUILDIN_DEF(addchannelhandler, "ss"),
BUILDIN_DEF(removechannelhandler, "ss"),
@@ -25219,6 +25219,7 @@ void script_defaults(void)
script->search_str = script_search_str;
script->setd_sub = setd_sub;
script->attach_state = script_attach_state;
+ script->sprintf = script_sprintf;
script->queue = script_hqueue_get;
script->queue_add = script_hqueue_add;
diff --git a/src/map/script.h b/src/map/script.h
index 14d20838d..2dc3b2327 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -909,6 +909,7 @@ struct script_interface {
int (*buildin_mobuseskill_sub) (struct block_list *bl, va_list ap);
int (*cleanfloor_sub) (struct block_list *bl, va_list ap);
int (*run_func) (struct script_state *st);
+ bool (*sprintf) (struct script_state *st, int start, struct StringBuf *out);
const char *(*getfuncname) (struct script_state *st);
// for ENABLE_CASE_CHECK
unsigned int (*calc_hash_ci) (const char *p);
diff --git a/src/map/skill.h b/src/map/skill.h
index bd4d82df2..d7590921a 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1371,7 +1371,7 @@ enum e_skill {
GM_FORCE_TRANSFER,
GM_WIDE_RESURRECTION,
ALL_NIFLHEIM_RECALL,
- ALL_PRONTERA_RECALL,
+ ALL_PRONTERA_RECALL,
ALL_GLASTHEIM_RECALL,
ALL_THANATOS_RECALL,
diff --git a/src/map/status.c b/src/map/status.c
index 3bb511970..3e4b4a45c 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -9763,8 +9763,8 @@ int status_get_val_flag(enum sc_type type)
{
int val_flag = 0;
switch (type) {
- case SC_CLAN_INFO:
- val_flag |= 1 | 2;
+ case SC_CLAN_INFO:
+ val_flag |= 1 | 2;
break;
case SC_FIGHTINGSPIRIT:
val_flag |= 1 | 2;
diff --git a/src/map/status.h b/src/map/status.h
index 66e773720..5a031fa48 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -838,9 +838,9 @@ typedef enum sc_type {
SC_BITESCAR,
SC_ARCLOUSEDASH,
SC_TUNAPARTY,
- SC_SHRIMP, // 650
+ SC_SHRIMP, // 650
SC_FRESHSHRIMP,
-
+
SC_DRESS_UP,
// Rodex
diff --git a/src/map/unit.c b/src/map/unit.c
index fcad73188..64bd17edc 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2058,7 +2058,7 @@ bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range,
#ifdef OFFICIAL_WALKPATH
if( !path->search_long(NULL, bl, bl->m, bl->x, bl->y, tbl->x-dx, tbl->y-dy, CELL_CHKNOPASS) // Check if there is an obstacle between
- && wpd.path_len > 14 // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
+ && wpd.path_len > 14 // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
&& (bl->type != BL_NPC) ) // If type is a NPC, please disregard.
return false;
#endif
@@ -2210,6 +2210,7 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick)
//Non-players use the sync packet on the walk timer. [Skotlex]
if (tid == INVALID_TIMER && sd) clif->fixpos(src);
+ map->freeblock_lock();
if( DIFF_TICK(ud->attackabletime,tick) <= 0 ) {
if (battle_config.attack_direction_change && (src->type&battle_config.attack_direction_change)) {
ud->dir = map->calc_dir(src, target->x,target->y );
@@ -2219,8 +2220,10 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick)
if(md) {
//First attack is always a normal attack
if(md->state.skillstate == MSS_ANGRY || md->state.skillstate == MSS_BERSERK) {
- if (mob->skill_use(md,tick,-1))
+ if (mob->skill_use(md,tick,-1)) {
+ map->freeblock_unlock();
return 1;
+ }
} else {
// Set mob's ANGRY/BERSERK states.
md->state.skillstate = md->state.aggressive?MSS_ANGRY:MSS_BERSERK;
@@ -2232,21 +2235,23 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick)
map->foreachinrange(mob->linksearch, src, md->db->range2, BL_MOB, md->class_, target, tick);
}
}
- if (src->type == BL_PET && pet->attackskill(BL_UCAST(BL_PET, src), target->id))
+ if (src->type == BL_PET && pet->attackskill(BL_UCAST(BL_PET, src), target->id)) {
+ map->freeblock_unlock();
return 1;
+ }
- map->freeblock_lock();
ud->attacktarget_lv = battle->weapon_attack(src,target,tick,0);
if(sd && sd->status.pet_id > 0 && sd->pd && battle_config.pet_attack_support)
pet->target_check(sd,target,0);
- map->freeblock_unlock();
/**
* Applied when you're unable to attack (e.g. out of ammo)
* We should stop here otherwise timer keeps on and this happens endlessly
**/
- if( ud->attacktarget_lv == ATK_NONE )
+ if (ud->attacktarget_lv == ATK_NONE) {
+ map->freeblock_unlock();
return 1;
+ }
ud->attackabletime = tick + sstatus->adelay;
// You can't move if you can't attack neither.
@@ -2260,6 +2265,7 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick)
pc->update_idle_time(sd, BCIDLE_ATTACK);
ud->attacktimer = timer->add(ud->attackabletime,unit->attack_timer,src->id,0);
}
+ map->freeblock_unlock();
if (sd != NULL && battle_config.prevent_logout_trigger & PLT_ATTACK)
sd->canlog_tick = timer->gettick();
diff --git a/src/plugins/HPMHooking.c b/src/plugins/HPMHooking.c
index 99b4e63e7..8686a07be 100644
--- a/src/plugins/HPMHooking.c
+++ b/src/plugins/HPMHooking.c
@@ -34,9 +34,12 @@ PRAGMA_GCC5(GCC diagnostic ignored "-Wdiscarded-qualifiers")
#define HPM_HOOKS_INCLUDE "HPMHooking/HPMHooking_login.Hooks.inc"
#define HPM_POINTS_INCLUDE "HPMHooking/HPMHooking_login.HookingPoints.inc"
#define HPM_SOURCES_INCLUDE "HPMHooking/HPMHooking_login.sources.inc"
+#include "login/account.h"
+#include "login/ipban.h"
#include "login/lclif.h"
#include "login/lclif.p.h"
#include "login/login.h"
+#include "login/loginlog.h"
#elif defined (HPMHOOKING_CHAR)
#define HPM_SERVER_TYPE SERVER_TYPE_CHAR
#define HPM_CORE_INCLUDE "HPMHooking/HPMHooking_char.HPMHooksCore.inc"
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index c293eb1f7..bd17dc7fe 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -33,6 +33,46 @@ typedef bool (*HPMHOOK_post_HCache_check) (bool retVal___, const char *file);
typedef FILE* (*HPMHOOK_pre_HCache_open) (const char **file, const char **opt);
typedef FILE* (*HPMHOOK_post_HCache_open) (FILE* retVal___, const char *file, const char *opt);
#endif // COMMON_UTILS_H
+#ifdef LOGIN_ACCOUNT_H /* account */
+typedef struct Sql* (*HPMHOOK_pre_account_db_sql_up) (AccountDB **self);
+typedef struct Sql* (*HPMHOOK_post_account_db_sql_up) (struct Sql* retVal___, AccountDB *self);
+typedef void (*HPMHOOK_pre_account_mmo_send_accreg2) (AccountDB **self, int *fd, int *account_id, int *char_id);
+typedef void (*HPMHOOK_post_account_mmo_send_accreg2) (AccountDB *self, int fd, int account_id, int char_id);
+typedef void (*HPMHOOK_pre_account_mmo_save_accreg2) (AccountDB **self, int *fd, int *account_id, int *char_id);
+typedef void (*HPMHOOK_post_account_mmo_save_accreg2) (AccountDB *self, int fd, int account_id, int char_id);
+typedef bool (*HPMHOOK_pre_account_mmo_auth_fromsql) (AccountDB_SQL **db, struct mmo_account **acc, int *account_id);
+typedef bool (*HPMHOOK_post_account_mmo_auth_fromsql) (bool retVal___, AccountDB_SQL *db, struct mmo_account *acc, int account_id);
+typedef bool (*HPMHOOK_pre_account_mmo_auth_tosql) (AccountDB_SQL **db, const struct mmo_account **acc, bool *is_new);
+typedef bool (*HPMHOOK_post_account_mmo_auth_tosql) (bool retVal___, AccountDB_SQL *db, const struct mmo_account *acc, bool is_new);
+typedef AccountDB* (*HPMHOOK_pre_account_db_sql) (void);
+typedef AccountDB* (*HPMHOOK_post_account_db_sql) (AccountDB* retVal___);
+typedef bool (*HPMHOOK_pre_account_db_sql_init) (AccountDB **self);
+typedef bool (*HPMHOOK_post_account_db_sql_init) (bool retVal___, AccountDB *self);
+typedef void (*HPMHOOK_pre_account_db_sql_destroy) (AccountDB **self);
+typedef void (*HPMHOOK_post_account_db_sql_destroy) (AccountDB *self);
+typedef bool (*HPMHOOK_pre_account_db_sql_get_property) (AccountDB **self, const char **key, char **buf, size_t *buflen);
+typedef bool (*HPMHOOK_post_account_db_sql_get_property) (bool retVal___, AccountDB *self, const char *key, char *buf, size_t buflen);
+typedef bool (*HPMHOOK_pre_account_db_sql_set_property) (AccountDB **self, struct config_t **config, bool *imported);
+typedef bool (*HPMHOOK_post_account_db_sql_set_property) (bool retVal___, AccountDB *self, struct config_t *config, bool imported);
+typedef bool (*HPMHOOK_pre_account_db_sql_create) (AccountDB **self, struct mmo_account **acc);
+typedef bool (*HPMHOOK_post_account_db_sql_create) (bool retVal___, AccountDB *self, struct mmo_account *acc);
+typedef bool (*HPMHOOK_pre_account_db_sql_remove) (AccountDB **self, const int *account_id);
+typedef bool (*HPMHOOK_post_account_db_sql_remove) (bool retVal___, AccountDB *self, const int account_id);
+typedef bool (*HPMHOOK_pre_account_db_sql_save) (AccountDB **self, const struct mmo_account **acc);
+typedef bool (*HPMHOOK_post_account_db_sql_save) (bool retVal___, AccountDB *self, const struct mmo_account *acc);
+typedef bool (*HPMHOOK_pre_account_db_sql_load_num) (AccountDB **self, struct mmo_account **acc, const int *account_id);
+typedef bool (*HPMHOOK_post_account_db_sql_load_num) (bool retVal___, AccountDB *self, struct mmo_account *acc, const int account_id);
+typedef bool (*HPMHOOK_pre_account_db_sql_load_str) (AccountDB **self, struct mmo_account **acc, const char **userid);
+typedef bool (*HPMHOOK_post_account_db_sql_load_str) (bool retVal___, AccountDB *self, struct mmo_account *acc, const char *userid);
+typedef AccountDBIterator* (*HPMHOOK_pre_account_db_sql_iterator) (AccountDB **self);
+typedef AccountDBIterator* (*HPMHOOK_post_account_db_sql_iterator) (AccountDBIterator* retVal___, AccountDB *self);
+typedef void (*HPMHOOK_pre_account_db_sql_iter_destroy) (AccountDBIterator **self);
+typedef void (*HPMHOOK_post_account_db_sql_iter_destroy) (AccountDBIterator *self);
+typedef bool (*HPMHOOK_pre_account_db_sql_iter_next) (AccountDBIterator **self, struct mmo_account **acc);
+typedef bool (*HPMHOOK_post_account_db_sql_iter_next) (bool retVal___, AccountDBIterator *self, struct mmo_account *acc);
+typedef bool (*HPMHOOK_pre_account_db_read_inter) (AccountDB_SQL **db, const char **filename, bool *imported);
+typedef bool (*HPMHOOK_post_account_db_read_inter) (bool retVal___, AccountDB_SQL *db, const char *filename, bool imported);
+#endif // LOGIN_ACCOUNT_H
#ifdef MAP_ATCOMMAND_H /* atcommand */
typedef void (*HPMHOOK_pre_atcommand_init) (bool *minimal);
typedef void (*HPMHOOK_post_atcommand_init) (bool minimal);
@@ -2318,8 +2358,8 @@ typedef void (*HPMHOOK_pre_clif_rodex_send_maillist) (int *fd, struct map_sessio
typedef void (*HPMHOOK_post_clif_rodex_send_maillist) (int fd, struct map_session_data *sd, int8 open_type, int64 page_start);
typedef void (*HPMHOOK_pre_clif_rodex_send_refresh) (int *fd, struct map_session_data **sd, int8 *open_type, int *count);
typedef void (*HPMHOOK_post_clif_rodex_send_refresh) (int fd, struct map_session_data *sd, int8 open_type, int count);
-typedef void (*HPMHOOK_pre_clif_rodex_send_mails_all) (int *fd, struct map_session_data **sd);
-typedef void (*HPMHOOK_post_clif_rodex_send_mails_all) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_rodex_send_mails_all) (int *fd, struct map_session_data **sd, int64 *mail_id);
+typedef void (*HPMHOOK_post_clif_rodex_send_mails_all) (int fd, struct map_session_data *sd, int64 mail_id);
typedef void (*HPMHOOK_pre_clif_pRodexReadMail) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pRodexReadMail) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_rodex_read_mail) (struct map_session_data **sd, int8 *opentype, struct rodex_message **msg);
@@ -3429,6 +3469,26 @@ typedef void (*HPMHOOK_post_intif_pRodexCheckName) (int fd);
typedef void (*HPMHOOK_pre_intif_pRecvClanMemberAction) (int *fd);
typedef void (*HPMHOOK_post_intif_pRecvClanMemberAction) (int fd);
#endif // MAP_INTIF_H
+#ifdef LOGIN_IPBAN_H /* ipban */
+typedef void (*HPMHOOK_pre_ipban_init) (void);
+typedef void (*HPMHOOK_post_ipban_init) (void);
+typedef void (*HPMHOOK_pre_ipban_final) (void);
+typedef void (*HPMHOOK_post_ipban_final) (void);
+typedef int (*HPMHOOK_pre_ipban_cleanup) (int *tid, int64 *tick, int *id, intptr_t *data);
+typedef int (*HPMHOOK_post_ipban_cleanup) (int retVal___, int tid, int64 tick, int id, intptr_t data);
+typedef bool (*HPMHOOK_pre_ipban_config_read_inter) (const char **filename, bool *imported);
+typedef bool (*HPMHOOK_post_ipban_config_read_inter) (bool retVal___, const char *filename, bool imported);
+typedef bool (*HPMHOOK_pre_ipban_config_read_connection) (const char **filename, struct config_t **config, bool *imported);
+typedef bool (*HPMHOOK_post_ipban_config_read_connection) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+typedef bool (*HPMHOOK_pre_ipban_config_read_dynamic) (const char **filename, struct config_t **config, bool *imported);
+typedef bool (*HPMHOOK_post_ipban_config_read_dynamic) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+typedef bool (*HPMHOOK_pre_ipban_config_read) (const char **filename, struct config_t **config, bool *imported);
+typedef bool (*HPMHOOK_post_ipban_config_read) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+typedef bool (*HPMHOOK_pre_ipban_check) (uint32 *ip);
+typedef bool (*HPMHOOK_post_ipban_check) (bool retVal___, uint32 ip);
+typedef void (*HPMHOOK_pre_ipban_log) (uint32 *ip);
+typedef void (*HPMHOOK_post_ipban_log) (uint32 ip);
+#endif // LOGIN_IPBAN_H
#ifdef MAP_IRC_BOT_H /* ircbot */
typedef void (*HPMHOOK_pre_ircbot_init) (bool *minimal);
typedef void (*HPMHOOK_post_ircbot_init) (bool minimal);
@@ -3599,6 +3659,16 @@ typedef bool (*HPMHOOK_post_itemdb_lookup_const) (bool retVal___, const struct c
typedef bool (*HPMHOOK_pre_itemdb_lookup_const_mask) (const struct config_setting_t **it, const char **name, int **value);
typedef bool (*HPMHOOK_post_itemdb_lookup_const_mask) (bool retVal___, const struct config_setting_t *it, const char *name, int *value);
#endif // MAP_ITEMDB_H
+#ifdef LOGIN_LOGIN_H /* lchrif */
+typedef void (*HPMHOOK_pre_lchrif_server_init) (int *id);
+typedef void (*HPMHOOK_post_lchrif_server_init) (int id);
+typedef void (*HPMHOOK_pre_lchrif_server_destroy) (int *id);
+typedef void (*HPMHOOK_post_lchrif_server_destroy) (int id);
+typedef void (*HPMHOOK_pre_lchrif_server_reset) (int *id);
+typedef void (*HPMHOOK_post_lchrif_server_reset) (int id);
+typedef void (*HPMHOOK_pre_lchrif_on_disconnect) (int *id);
+typedef void (*HPMHOOK_post_lchrif_on_disconnect) (int id);
+#endif // LOGIN_LOGIN_H
#ifdef LOGIN_LCLIF_H /* lclif */
typedef void (*HPMHOOK_pre_lclif_init) (void);
typedef void (*HPMHOOK_post_lclif_init) (void);
@@ -3991,6 +4061,22 @@ typedef void (*HPMHOOK_post_loginif_send_users_count) (int users);
typedef void (*HPMHOOK_pre_loginif_connect_to_server) (void);
typedef void (*HPMHOOK_post_loginif_connect_to_server) (void);
#endif // CHAR_LOGINIF_H
+#ifdef LOGIN_LOGINLOG_H /* loginlog */
+typedef unsigned long (*HPMHOOK_pre_loginlog_failedattempts) (uint32 *ip, unsigned int *minutes);
+typedef unsigned long (*HPMHOOK_post_loginlog_failedattempts) (unsigned long retVal___, uint32 ip, unsigned int minutes);
+typedef void (*HPMHOOK_pre_loginlog_log) (uint32 *ip, const char **username, int *rcode, const char **message);
+typedef void (*HPMHOOK_post_loginlog_log) (uint32 ip, const char *username, int rcode, const char *message);
+typedef bool (*HPMHOOK_pre_loginlog_init) (void);
+typedef bool (*HPMHOOK_post_loginlog_init) (bool retVal___);
+typedef bool (*HPMHOOK_pre_loginlog_final) (void);
+typedef bool (*HPMHOOK_post_loginlog_final) (bool retVal___);
+typedef bool (*HPMHOOK_pre_loginlog_config_read_names) (const char **filename, struct config_t **config, bool *imported);
+typedef bool (*HPMHOOK_post_loginlog_config_read_names) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+typedef bool (*HPMHOOK_pre_loginlog_config_read_log) (const char **filename, struct config_t **config, bool *imported);
+typedef bool (*HPMHOOK_post_loginlog_config_read_log) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+typedef bool (*HPMHOOK_pre_loginlog_config_read) (const char **filename, bool *imported);
+typedef bool (*HPMHOOK_post_loginlog_config_read) (bool retVal___, const char *filename, bool imported);
+#endif // LOGIN_LOGINLOG_H
#ifdef MAP_MAIL_H /* mail */
typedef void (*HPMHOOK_pre_mail_clear) (struct map_session_data **sd);
typedef void (*HPMHOOK_post_mail_clear) (struct map_session_data *sd);
@@ -4218,10 +4304,10 @@ typedef struct DBData (*HPMHOOK_pre_map_create_map_data_other_server) (union DBK
typedef struct DBData (*HPMHOOK_post_map_create_map_data_other_server) (struct DBData retVal___, union DBKey key, va_list args);
typedef int (*HPMHOOK_pre_map_eraseallipport_sub) (union DBKey *key, struct DBData **data, va_list va);
typedef int (*HPMHOOK_post_map_eraseallipport_sub) (int retVal___, union DBKey key, struct DBData *data, va_list va);
-typedef char* (*HPMHOOK_pre_map_init_mapcache) (FILE **fp);
-typedef char* (*HPMHOOK_post_map_init_mapcache) (char* retVal___, FILE *fp);
-typedef int (*HPMHOOK_pre_map_readfromcache) (struct map_data **m, char **buffer);
-typedef int (*HPMHOOK_post_map_readfromcache) (int retVal___, struct map_data *m, char *buffer);
+typedef bool (*HPMHOOK_pre_map_readfromcache) (struct map_data **m);
+typedef bool (*HPMHOOK_post_map_readfromcache) (bool retVal___, struct map_data *m);
+typedef bool (*HPMHOOK_pre_map_readfromcache_v1) (FILE **fp, struct map_data **m, unsigned int *file_size);
+typedef bool (*HPMHOOK_post_map_readfromcache_v1) (bool retVal___, FILE *fp, struct map_data *m, unsigned int file_size);
typedef int (*HPMHOOK_pre_map_addmap) (const char **mapname);
typedef int (*HPMHOOK_post_map_addmap) (int retVal___, const char *mapname);
typedef void (*HPMHOOK_pre_map_delmapid) (int *id);
@@ -4576,8 +4662,8 @@ typedef int (*HPMHOOK_pre_mapif_parse_quest_load) (int *fd);
typedef int (*HPMHOOK_post_mapif_parse_quest_load) (int retVal___, int fd);
typedef int (*HPMHOOK_pre_mapif_parse_rodex_requestinbox) (int *fd);
typedef int (*HPMHOOK_post_mapif_parse_rodex_requestinbox) (int retVal___, int fd);
-typedef void (*HPMHOOK_pre_mapif_rodex_sendinbox) (int *fd, int *char_id, int8 *opentype, int8 *flag, int *count, struct rodex_maillist **mails);
-typedef void (*HPMHOOK_post_mapif_rodex_sendinbox) (int fd, int char_id, int8 opentype, int8 flag, int count, struct rodex_maillist *mails);
+typedef void (*HPMHOOK_pre_mapif_rodex_sendinbox) (int *fd, int *char_id, int8 *opentype, int8 *flag, int *count, int64 *mail_id, struct rodex_maillist **mails);
+typedef void (*HPMHOOK_post_mapif_rodex_sendinbox) (int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails);
typedef int (*HPMHOOK_pre_mapif_parse_rodex_checkhasnew) (int *fd);
typedef int (*HPMHOOK_post_mapif_parse_rodex_checkhasnew) (int retVal___, int fd);
typedef void (*HPMHOOK_pre_mapif_rodex_sendhasnew) (int *fd, int *char_id, bool *has_new);
@@ -6348,6 +6434,8 @@ typedef int (*HPMHOOK_pre_script_cleanfloor_sub) (struct block_list **bl, va_lis
typedef int (*HPMHOOK_post_script_cleanfloor_sub) (int retVal___, struct block_list *bl, va_list ap);
typedef int (*HPMHOOK_pre_script_run_func) (struct script_state **st);
typedef int (*HPMHOOK_post_script_run_func) (int retVal___, struct script_state *st);
+typedef bool (*HPMHOOK_pre_script_sprintf) (struct script_state **st, int *start, struct StringBuf **out);
+typedef bool (*HPMHOOK_post_script_sprintf) (bool retVal___, struct script_state *st, int start, struct StringBuf *out);
typedef const char* (*HPMHOOK_pre_script_getfuncname) (struct script_state **st);
typedef const char* (*HPMHOOK_post_script_getfuncname) (const char* retVal___, struct script_state *st);
typedef unsigned int (*HPMHOOK_pre_script_calc_hash_ci) (const char **p);
diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
index cfd6caee1..6ea10f78f 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
@@ -14647,14 +14647,14 @@ int HP_mapif_parse_rodex_requestinbox(int fd) {
}
return retVal___;
}
-void HP_mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int count, struct rodex_maillist *mails) {
+void HP_mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails) {
int hIndex = 0;
if (HPMHooks.count.HP_mapif_rodex_sendinbox_pre > 0) {
- void (*preHookFunc) (int *fd, int *char_id, int8 *opentype, int8 *flag, int *count, struct rodex_maillist **mails);
+ void (*preHookFunc) (int *fd, int *char_id, int8 *opentype, int8 *flag, int *count, int64 *mail_id, struct rodex_maillist **mails);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_rodex_sendinbox_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_mapif_rodex_sendinbox_pre[hIndex].func;
- preHookFunc(&fd, &char_id, &opentype, &flag, &count, &mails);
+ preHookFunc(&fd, &char_id, &opentype, &flag, &count, &mail_id, &mails);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -14662,13 +14662,13 @@ void HP_mapif_rodex_sendinbox(int fd, int char_id, int8 opentype, int8 flag, int
}
}
{
- HPMHooks.source.mapif.rodex_sendinbox(fd, char_id, opentype, flag, count, mails);
+ HPMHooks.source.mapif.rodex_sendinbox(fd, char_id, opentype, flag, count, mail_id, mails);
}
if (HPMHooks.count.HP_mapif_rodex_sendinbox_post > 0) {
- void (*postHookFunc) (int fd, int char_id, int8 opentype, int8 flag, int count, struct rodex_maillist *mails);
+ void (*postHookFunc) (int fd, int char_id, int8 opentype, int8 flag, int count, int64 mail_id, struct rodex_maillist *mails);
for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_rodex_sendinbox_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_mapif_rodex_sendinbox_post[hIndex].func;
- postHookFunc(fd, char_id, opentype, flag, count, mails);
+ postHookFunc(fd, char_id, opentype, flag, count, mail_id, mails);
}
}
return;
diff --git a/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
index f8c270de3..5300ca3a6 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
@@ -32,6 +32,44 @@ struct {
struct HPMHookPoint *HP_HCache_check_post;
struct HPMHookPoint *HP_HCache_open_pre;
struct HPMHookPoint *HP_HCache_open_post;
+ struct HPMHookPoint *HP_account_db_sql_up_pre;
+ struct HPMHookPoint *HP_account_db_sql_up_post;
+ struct HPMHookPoint *HP_account_mmo_send_accreg2_pre;
+ struct HPMHookPoint *HP_account_mmo_send_accreg2_post;
+ struct HPMHookPoint *HP_account_mmo_save_accreg2_pre;
+ struct HPMHookPoint *HP_account_mmo_save_accreg2_post;
+ struct HPMHookPoint *HP_account_mmo_auth_fromsql_pre;
+ struct HPMHookPoint *HP_account_mmo_auth_fromsql_post;
+ struct HPMHookPoint *HP_account_mmo_auth_tosql_pre;
+ struct HPMHookPoint *HP_account_mmo_auth_tosql_post;
+ struct HPMHookPoint *HP_account_db_sql_pre;
+ struct HPMHookPoint *HP_account_db_sql_post;
+ struct HPMHookPoint *HP_account_db_sql_init_pre;
+ struct HPMHookPoint *HP_account_db_sql_init_post;
+ struct HPMHookPoint *HP_account_db_sql_destroy_pre;
+ struct HPMHookPoint *HP_account_db_sql_destroy_post;
+ struct HPMHookPoint *HP_account_db_sql_get_property_pre;
+ struct HPMHookPoint *HP_account_db_sql_get_property_post;
+ struct HPMHookPoint *HP_account_db_sql_set_property_pre;
+ struct HPMHookPoint *HP_account_db_sql_set_property_post;
+ struct HPMHookPoint *HP_account_db_sql_create_pre;
+ struct HPMHookPoint *HP_account_db_sql_create_post;
+ struct HPMHookPoint *HP_account_db_sql_remove_pre;
+ struct HPMHookPoint *HP_account_db_sql_remove_post;
+ struct HPMHookPoint *HP_account_db_sql_save_pre;
+ struct HPMHookPoint *HP_account_db_sql_save_post;
+ struct HPMHookPoint *HP_account_db_sql_load_num_pre;
+ struct HPMHookPoint *HP_account_db_sql_load_num_post;
+ struct HPMHookPoint *HP_account_db_sql_load_str_pre;
+ struct HPMHookPoint *HP_account_db_sql_load_str_post;
+ struct HPMHookPoint *HP_account_db_sql_iterator_pre;
+ struct HPMHookPoint *HP_account_db_sql_iterator_post;
+ struct HPMHookPoint *HP_account_db_sql_iter_destroy_pre;
+ struct HPMHookPoint *HP_account_db_sql_iter_destroy_post;
+ struct HPMHookPoint *HP_account_db_sql_iter_next_pre;
+ struct HPMHookPoint *HP_account_db_sql_iter_next_post;
+ struct HPMHookPoint *HP_account_db_read_inter_pre;
+ struct HPMHookPoint *HP_account_db_read_inter_post;
struct HPMHookPoint *HP_cmdline_init_pre;
struct HPMHookPoint *HP_cmdline_init_post;
struct HPMHookPoint *HP_cmdline_final_pre;
@@ -96,6 +134,32 @@ struct {
struct HPMHookPoint *HP_des_decrypt_block_post;
struct HPMHookPoint *HP_des_decrypt_pre;
struct HPMHookPoint *HP_des_decrypt_post;
+ struct HPMHookPoint *HP_ipban_init_pre;
+ struct HPMHookPoint *HP_ipban_init_post;
+ struct HPMHookPoint *HP_ipban_final_pre;
+ struct HPMHookPoint *HP_ipban_final_post;
+ struct HPMHookPoint *HP_ipban_cleanup_pre;
+ struct HPMHookPoint *HP_ipban_cleanup_post;
+ struct HPMHookPoint *HP_ipban_config_read_inter_pre;
+ struct HPMHookPoint *HP_ipban_config_read_inter_post;
+ struct HPMHookPoint *HP_ipban_config_read_connection_pre;
+ struct HPMHookPoint *HP_ipban_config_read_connection_post;
+ struct HPMHookPoint *HP_ipban_config_read_dynamic_pre;
+ struct HPMHookPoint *HP_ipban_config_read_dynamic_post;
+ struct HPMHookPoint *HP_ipban_config_read_pre;
+ struct HPMHookPoint *HP_ipban_config_read_post;
+ struct HPMHookPoint *HP_ipban_check_pre;
+ struct HPMHookPoint *HP_ipban_check_post;
+ struct HPMHookPoint *HP_ipban_log_pre;
+ struct HPMHookPoint *HP_ipban_log_post;
+ struct HPMHookPoint *HP_lchrif_server_init_pre;
+ struct HPMHookPoint *HP_lchrif_server_init_post;
+ struct HPMHookPoint *HP_lchrif_server_destroy_pre;
+ struct HPMHookPoint *HP_lchrif_server_destroy_post;
+ struct HPMHookPoint *HP_lchrif_server_reset_pre;
+ struct HPMHookPoint *HP_lchrif_server_reset_post;
+ struct HPMHookPoint *HP_lchrif_on_disconnect_pre;
+ struct HPMHookPoint *HP_lchrif_on_disconnect_post;
struct HPMHookPoint *HP_lclif_init_pre;
struct HPMHookPoint *HP_lclif_init_post;
struct HPMHookPoint *HP_lclif_final_pre;
@@ -406,6 +470,20 @@ struct {
struct HPMHookPoint *HP_login_config_set_md5hash_post;
struct HPMHookPoint *HP_login_convert_users_to_colors_pre;
struct HPMHookPoint *HP_login_convert_users_to_colors_post;
+ struct HPMHookPoint *HP_loginlog_failedattempts_pre;
+ struct HPMHookPoint *HP_loginlog_failedattempts_post;
+ struct HPMHookPoint *HP_loginlog_log_pre;
+ struct HPMHookPoint *HP_loginlog_log_post;
+ struct HPMHookPoint *HP_loginlog_init_pre;
+ struct HPMHookPoint *HP_loginlog_init_post;
+ struct HPMHookPoint *HP_loginlog_final_pre;
+ struct HPMHookPoint *HP_loginlog_final_post;
+ struct HPMHookPoint *HP_loginlog_config_read_names_pre;
+ struct HPMHookPoint *HP_loginlog_config_read_names_post;
+ struct HPMHookPoint *HP_loginlog_config_read_log_pre;
+ struct HPMHookPoint *HP_loginlog_config_read_log_post;
+ struct HPMHookPoint *HP_loginlog_config_read_pre;
+ struct HPMHookPoint *HP_loginlog_config_read_post;
struct HPMHookPoint *HP_md5_string_pre;
struct HPMHookPoint *HP_md5_string_post;
struct HPMHookPoint *HP_md5_binary_pre;
@@ -735,6 +813,44 @@ struct {
int HP_HCache_check_post;
int HP_HCache_open_pre;
int HP_HCache_open_post;
+ int HP_account_db_sql_up_pre;
+ int HP_account_db_sql_up_post;
+ int HP_account_mmo_send_accreg2_pre;
+ int HP_account_mmo_send_accreg2_post;
+ int HP_account_mmo_save_accreg2_pre;
+ int HP_account_mmo_save_accreg2_post;
+ int HP_account_mmo_auth_fromsql_pre;
+ int HP_account_mmo_auth_fromsql_post;
+ int HP_account_mmo_auth_tosql_pre;
+ int HP_account_mmo_auth_tosql_post;
+ int HP_account_db_sql_pre;
+ int HP_account_db_sql_post;
+ int HP_account_db_sql_init_pre;
+ int HP_account_db_sql_init_post;
+ int HP_account_db_sql_destroy_pre;
+ int HP_account_db_sql_destroy_post;
+ int HP_account_db_sql_get_property_pre;
+ int HP_account_db_sql_get_property_post;
+ int HP_account_db_sql_set_property_pre;
+ int HP_account_db_sql_set_property_post;
+ int HP_account_db_sql_create_pre;
+ int HP_account_db_sql_create_post;
+ int HP_account_db_sql_remove_pre;
+ int HP_account_db_sql_remove_post;
+ int HP_account_db_sql_save_pre;
+ int HP_account_db_sql_save_post;
+ int HP_account_db_sql_load_num_pre;
+ int HP_account_db_sql_load_num_post;
+ int HP_account_db_sql_load_str_pre;
+ int HP_account_db_sql_load_str_post;
+ int HP_account_db_sql_iterator_pre;
+ int HP_account_db_sql_iterator_post;
+ int HP_account_db_sql_iter_destroy_pre;
+ int HP_account_db_sql_iter_destroy_post;
+ int HP_account_db_sql_iter_next_pre;
+ int HP_account_db_sql_iter_next_post;
+ int HP_account_db_read_inter_pre;
+ int HP_account_db_read_inter_post;
int HP_cmdline_init_pre;
int HP_cmdline_init_post;
int HP_cmdline_final_pre;
@@ -799,6 +915,32 @@ struct {
int HP_des_decrypt_block_post;
int HP_des_decrypt_pre;
int HP_des_decrypt_post;
+ int HP_ipban_init_pre;
+ int HP_ipban_init_post;
+ int HP_ipban_final_pre;
+ int HP_ipban_final_post;
+ int HP_ipban_cleanup_pre;
+ int HP_ipban_cleanup_post;
+ int HP_ipban_config_read_inter_pre;
+ int HP_ipban_config_read_inter_post;
+ int HP_ipban_config_read_connection_pre;
+ int HP_ipban_config_read_connection_post;
+ int HP_ipban_config_read_dynamic_pre;
+ int HP_ipban_config_read_dynamic_post;
+ int HP_ipban_config_read_pre;
+ int HP_ipban_config_read_post;
+ int HP_ipban_check_pre;
+ int HP_ipban_check_post;
+ int HP_ipban_log_pre;
+ int HP_ipban_log_post;
+ int HP_lchrif_server_init_pre;
+ int HP_lchrif_server_init_post;
+ int HP_lchrif_server_destroy_pre;
+ int HP_lchrif_server_destroy_post;
+ int HP_lchrif_server_reset_pre;
+ int HP_lchrif_server_reset_post;
+ int HP_lchrif_on_disconnect_pre;
+ int HP_lchrif_on_disconnect_post;
int HP_lclif_init_pre;
int HP_lclif_init_post;
int HP_lclif_final_pre;
@@ -1109,6 +1251,20 @@ struct {
int HP_login_config_set_md5hash_post;
int HP_login_convert_users_to_colors_pre;
int HP_login_convert_users_to_colors_post;
+ int HP_loginlog_failedattempts_pre;
+ int HP_loginlog_failedattempts_post;
+ int HP_loginlog_log_pre;
+ int HP_loginlog_log_post;
+ int HP_loginlog_init_pre;
+ int HP_loginlog_init_post;
+ int HP_loginlog_final_pre;
+ int HP_loginlog_final_post;
+ int HP_loginlog_config_read_names_pre;
+ int HP_loginlog_config_read_names_post;
+ int HP_loginlog_config_read_log_pre;
+ int HP_loginlog_config_read_log_post;
+ int HP_loginlog_config_read_pre;
+ int HP_loginlog_config_read_post;
int HP_md5_string_pre;
int HP_md5_string_post;
int HP_md5_binary_pre;
@@ -1433,15 +1589,19 @@ struct {
struct {
struct HCache_interface HCache;
+ struct account_interface account;
struct cmdline_interface cmdline;
struct console_interface console;
struct core_interface core;
struct db_interface DB;
struct des_interface des;
+ struct ipban_interface ipban;
+ struct lchrif_interface lchrif;
struct lclif_interface lclif;
struct lclif_interface_private PRIV__lclif;
struct libconfig_interface libconfig;
struct login_interface login;
+ struct loginlog_interface loginlog;
struct md5_interface md5;
struct mutex_interface mutex;
struct nullpo_interface nullpo;
diff --git a/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
index 8cec39974..6eb2e8121 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
@@ -30,6 +30,26 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(HCache->init, HP_HCache_init) },
{ HP_POP(HCache->check, HP_HCache_check) },
{ HP_POP(HCache->open, HP_HCache_open) },
+/* account_interface */
+ { HP_POP(account->db_sql_up, HP_account_db_sql_up) },
+ { HP_POP(account->mmo_send_accreg2, HP_account_mmo_send_accreg2) },
+ { HP_POP(account->mmo_save_accreg2, HP_account_mmo_save_accreg2) },
+ { HP_POP(account->mmo_auth_fromsql, HP_account_mmo_auth_fromsql) },
+ { HP_POP(account->mmo_auth_tosql, HP_account_mmo_auth_tosql) },
+ { HP_POP(account->db_sql, HP_account_db_sql) },
+ { HP_POP(account->db_sql_init, HP_account_db_sql_init) },
+ { HP_POP(account->db_sql_destroy, HP_account_db_sql_destroy) },
+ { HP_POP(account->db_sql_get_property, HP_account_db_sql_get_property) },
+ { HP_POP(account->db_sql_set_property, HP_account_db_sql_set_property) },
+ { HP_POP(account->db_sql_create, HP_account_db_sql_create) },
+ { HP_POP(account->db_sql_remove, HP_account_db_sql_remove) },
+ { HP_POP(account->db_sql_save, HP_account_db_sql_save) },
+ { HP_POP(account->db_sql_load_num, HP_account_db_sql_load_num) },
+ { HP_POP(account->db_sql_load_str, HP_account_db_sql_load_str) },
+ { HP_POP(account->db_sql_iterator, HP_account_db_sql_iterator) },
+ { HP_POP(account->db_sql_iter_destroy, HP_account_db_sql_iter_destroy) },
+ { HP_POP(account->db_sql_iter_next, HP_account_db_sql_iter_next) },
+ { HP_POP(account->db_read_inter, HP_account_db_read_inter) },
/* cmdline_interface */
{ HP_POP(cmdline->init, HP_cmdline_init) },
{ HP_POP(cmdline->final, HP_cmdline_final) },
@@ -67,6 +87,21 @@ struct HookingPointData HookingPoints[] = {
/* des_interface */
{ HP_POP(des->decrypt_block, HP_des_decrypt_block) },
{ HP_POP(des->decrypt, HP_des_decrypt) },
+/* ipban_interface */
+ { HP_POP(ipban->init, HP_ipban_init) },
+ { HP_POP(ipban->final, HP_ipban_final) },
+ { HP_POP(ipban->cleanup, HP_ipban_cleanup) },
+ { HP_POP(ipban->config_read_inter, HP_ipban_config_read_inter) },
+ { HP_POP(ipban->config_read_connection, HP_ipban_config_read_connection) },
+ { HP_POP(ipban->config_read_dynamic, HP_ipban_config_read_dynamic) },
+ { HP_POP(ipban->config_read, HP_ipban_config_read) },
+ { HP_POP(ipban->check, HP_ipban_check) },
+ { HP_POP(ipban->log, HP_ipban_log) },
+/* lchrif_interface */
+ { HP_POP(lchrif->server_init, HP_lchrif_server_init) },
+ { HP_POP(lchrif->server_destroy, HP_lchrif_server_destroy) },
+ { HP_POP(lchrif->server_reset, HP_lchrif_server_reset) },
+ { HP_POP(lchrif->on_disconnect, HP_lchrif_on_disconnect) },
/* lclif_interface */
{ HP_POP(lclif->init, HP_lclif_init) },
{ HP_POP(lclif->final, HP_lclif_final) },
@@ -226,6 +261,14 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(login->clear_client_hash_nodes, HP_login_clear_client_hash_nodes) },
{ HP_POP(login->config_set_md5hash, HP_login_config_set_md5hash) },
{ HP_POP(login->convert_users_to_colors, HP_login_convert_users_to_colors) },
+/* loginlog_interface */
+ { HP_POP(loginlog->failedattempts, HP_loginlog_failedattempts) },
+ { HP_POP(loginlog->log, HP_loginlog_log) },
+ { HP_POP(loginlog->init, HP_loginlog_init) },
+ { HP_POP(loginlog->final, HP_loginlog_final) },
+ { HP_POP(loginlog->config_read_names, HP_loginlog_config_read_names) },
+ { HP_POP(loginlog->config_read_log, HP_loginlog_config_read_log) },
+ { HP_POP(loginlog->config_read, HP_loginlog_config_read) },
/* md5_interface */
{ HP_POP(md5->string, HP_md5_string) },
{ HP_POP(md5->binary, HP_md5_binary) },
diff --git a/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
index 658ee874d..e432da70d 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
@@ -106,6 +106,516 @@ FILE* HP_HCache_open(const char *file, const char *opt) {
}
return retVal___;
}
+/* account_interface */
+struct Sql* HP_account_db_sql_up(AccountDB *self) {
+ int hIndex = 0;
+ struct Sql* retVal___ = NULL;
+ if (HPMHooks.count.HP_account_db_sql_up_pre > 0) {
+ struct Sql* (*preHookFunc) (AccountDB **self);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_up_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_up_pre[hIndex].func;
+ retVal___ = preHookFunc(&self);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_up(self);
+ }
+ if (HPMHooks.count.HP_account_db_sql_up_post > 0) {
+ struct Sql* (*postHookFunc) (struct Sql* retVal___, AccountDB *self);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_up_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_up_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self);
+ }
+ }
+ return retVal___;
+}
+void HP_account_mmo_send_accreg2(AccountDB *self, int fd, int account_id, int char_id) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_account_mmo_send_accreg2_pre > 0) {
+ void (*preHookFunc) (AccountDB **self, int *fd, int *account_id, int *char_id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_mmo_send_accreg2_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_mmo_send_accreg2_pre[hIndex].func;
+ preHookFunc(&self, &fd, &account_id, &char_id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.account.mmo_send_accreg2(self, fd, account_id, char_id);
+ }
+ if (HPMHooks.count.HP_account_mmo_send_accreg2_post > 0) {
+ void (*postHookFunc) (AccountDB *self, int fd, int account_id, int char_id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_mmo_send_accreg2_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_mmo_send_accreg2_post[hIndex].func;
+ postHookFunc(self, fd, account_id, char_id);
+ }
+ }
+ return;
+}
+void HP_account_mmo_save_accreg2(AccountDB *self, int fd, int account_id, int char_id) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_account_mmo_save_accreg2_pre > 0) {
+ void (*preHookFunc) (AccountDB **self, int *fd, int *account_id, int *char_id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_mmo_save_accreg2_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_mmo_save_accreg2_pre[hIndex].func;
+ preHookFunc(&self, &fd, &account_id, &char_id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.account.mmo_save_accreg2(self, fd, account_id, char_id);
+ }
+ if (HPMHooks.count.HP_account_mmo_save_accreg2_post > 0) {
+ void (*postHookFunc) (AccountDB *self, int fd, int account_id, int char_id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_mmo_save_accreg2_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_mmo_save_accreg2_post[hIndex].func;
+ postHookFunc(self, fd, account_id, char_id);
+ }
+ }
+ return;
+}
+bool HP_account_mmo_auth_fromsql(AccountDB_SQL *db, struct mmo_account *acc, int account_id) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_mmo_auth_fromsql_pre > 0) {
+ bool (*preHookFunc) (AccountDB_SQL **db, struct mmo_account **acc, int *account_id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_mmo_auth_fromsql_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_mmo_auth_fromsql_pre[hIndex].func;
+ retVal___ = preHookFunc(&db, &acc, &account_id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.mmo_auth_fromsql(db, acc, account_id);
+ }
+ if (HPMHooks.count.HP_account_mmo_auth_fromsql_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB_SQL *db, struct mmo_account *acc, int account_id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_mmo_auth_fromsql_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_mmo_auth_fromsql_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, db, acc, account_id);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_mmo_auth_tosql(AccountDB_SQL *db, const struct mmo_account *acc, bool is_new) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_mmo_auth_tosql_pre > 0) {
+ bool (*preHookFunc) (AccountDB_SQL **db, const struct mmo_account **acc, bool *is_new);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_mmo_auth_tosql_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_mmo_auth_tosql_pre[hIndex].func;
+ retVal___ = preHookFunc(&db, &acc, &is_new);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.mmo_auth_tosql(db, acc, is_new);
+ }
+ if (HPMHooks.count.HP_account_mmo_auth_tosql_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB_SQL *db, const struct mmo_account *acc, bool is_new);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_mmo_auth_tosql_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_mmo_auth_tosql_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, db, acc, is_new);
+ }
+ }
+ return retVal___;
+}
+AccountDB* HP_account_db_sql(void) {
+ int hIndex = 0;
+ AccountDB* retVal___ = NULL;
+ if (HPMHooks.count.HP_account_db_sql_pre > 0) {
+ AccountDB* (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_pre[hIndex].func;
+ retVal___ = preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql();
+ }
+ if (HPMHooks.count.HP_account_db_sql_post > 0) {
+ AccountDB* (*postHookFunc) (AccountDB* retVal___);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_db_sql_init(AccountDB *self) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_init_pre > 0) {
+ bool (*preHookFunc) (AccountDB **self);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_init_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_init_pre[hIndex].func;
+ retVal___ = preHookFunc(&self);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_init(self);
+ }
+ if (HPMHooks.count.HP_account_db_sql_init_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB *self);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_init_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_init_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self);
+ }
+ }
+ return retVal___;
+}
+void HP_account_db_sql_destroy(AccountDB *self) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_account_db_sql_destroy_pre > 0) {
+ void (*preHookFunc) (AccountDB **self);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_destroy_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_destroy_pre[hIndex].func;
+ preHookFunc(&self);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.account.db_sql_destroy(self);
+ }
+ if (HPMHooks.count.HP_account_db_sql_destroy_post > 0) {
+ void (*postHookFunc) (AccountDB *self);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_destroy_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_destroy_post[hIndex].func;
+ postHookFunc(self);
+ }
+ }
+ return;
+}
+bool HP_account_db_sql_get_property(AccountDB *self, const char *key, char *buf, size_t buflen) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_get_property_pre > 0) {
+ bool (*preHookFunc) (AccountDB **self, const char **key, char **buf, size_t *buflen);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_get_property_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_get_property_pre[hIndex].func;
+ retVal___ = preHookFunc(&self, &key, &buf, &buflen);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_get_property(self, key, buf, buflen);
+ }
+ if (HPMHooks.count.HP_account_db_sql_get_property_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB *self, const char *key, char *buf, size_t buflen);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_get_property_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_get_property_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self, key, buf, buflen);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_db_sql_set_property(AccountDB *self, struct config_t *config, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_set_property_pre > 0) {
+ bool (*preHookFunc) (AccountDB **self, struct config_t **config, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_set_property_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_set_property_pre[hIndex].func;
+ retVal___ = preHookFunc(&self, &config, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_set_property(self, config, imported);
+ }
+ if (HPMHooks.count.HP_account_db_sql_set_property_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB *self, struct config_t *config, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_set_property_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_set_property_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self, config, imported);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_db_sql_create(AccountDB *self, struct mmo_account *acc) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_create_pre > 0) {
+ bool (*preHookFunc) (AccountDB **self, struct mmo_account **acc);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_create_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_create_pre[hIndex].func;
+ retVal___ = preHookFunc(&self, &acc);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_create(self, acc);
+ }
+ if (HPMHooks.count.HP_account_db_sql_create_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB *self, struct mmo_account *acc);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_create_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_create_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self, acc);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_db_sql_remove(AccountDB *self, const int account_id) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_remove_pre > 0) {
+ bool (*preHookFunc) (AccountDB **self, const int *account_id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_remove_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_remove_pre[hIndex].func;
+ retVal___ = preHookFunc(&self, &account_id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_remove(self, account_id);
+ }
+ if (HPMHooks.count.HP_account_db_sql_remove_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB *self, const int account_id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_remove_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_remove_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self, account_id);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_db_sql_save(AccountDB *self, const struct mmo_account *acc) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_save_pre > 0) {
+ bool (*preHookFunc) (AccountDB **self, const struct mmo_account **acc);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_save_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_save_pre[hIndex].func;
+ retVal___ = preHookFunc(&self, &acc);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_save(self, acc);
+ }
+ if (HPMHooks.count.HP_account_db_sql_save_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB *self, const struct mmo_account *acc);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_save_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_save_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self, acc);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_db_sql_load_num(AccountDB *self, struct mmo_account *acc, const int account_id) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_load_num_pre > 0) {
+ bool (*preHookFunc) (AccountDB **self, struct mmo_account **acc, const int *account_id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_load_num_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_load_num_pre[hIndex].func;
+ retVal___ = preHookFunc(&self, &acc, &account_id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_load_num(self, acc, account_id);
+ }
+ if (HPMHooks.count.HP_account_db_sql_load_num_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB *self, struct mmo_account *acc, const int account_id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_load_num_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_load_num_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self, acc, account_id);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_db_sql_load_str(AccountDB *self, struct mmo_account *acc, const char *userid) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_load_str_pre > 0) {
+ bool (*preHookFunc) (AccountDB **self, struct mmo_account **acc, const char **userid);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_load_str_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_load_str_pre[hIndex].func;
+ retVal___ = preHookFunc(&self, &acc, &userid);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_load_str(self, acc, userid);
+ }
+ if (HPMHooks.count.HP_account_db_sql_load_str_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB *self, struct mmo_account *acc, const char *userid);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_load_str_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_load_str_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self, acc, userid);
+ }
+ }
+ return retVal___;
+}
+AccountDBIterator* HP_account_db_sql_iterator(AccountDB *self) {
+ int hIndex = 0;
+ AccountDBIterator* retVal___ = NULL;
+ if (HPMHooks.count.HP_account_db_sql_iterator_pre > 0) {
+ AccountDBIterator* (*preHookFunc) (AccountDB **self);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_iterator_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_iterator_pre[hIndex].func;
+ retVal___ = preHookFunc(&self);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_iterator(self);
+ }
+ if (HPMHooks.count.HP_account_db_sql_iterator_post > 0) {
+ AccountDBIterator* (*postHookFunc) (AccountDBIterator* retVal___, AccountDB *self);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_iterator_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_iterator_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self);
+ }
+ }
+ return retVal___;
+}
+void HP_account_db_sql_iter_destroy(AccountDBIterator *self) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_account_db_sql_iter_destroy_pre > 0) {
+ void (*preHookFunc) (AccountDBIterator **self);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_iter_destroy_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_iter_destroy_pre[hIndex].func;
+ preHookFunc(&self);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.account.db_sql_iter_destroy(self);
+ }
+ if (HPMHooks.count.HP_account_db_sql_iter_destroy_post > 0) {
+ void (*postHookFunc) (AccountDBIterator *self);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_iter_destroy_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_iter_destroy_post[hIndex].func;
+ postHookFunc(self);
+ }
+ }
+ return;
+}
+bool HP_account_db_sql_iter_next(AccountDBIterator *self, struct mmo_account *acc) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_sql_iter_next_pre > 0) {
+ bool (*preHookFunc) (AccountDBIterator **self, struct mmo_account **acc);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_iter_next_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_sql_iter_next_pre[hIndex].func;
+ retVal___ = preHookFunc(&self, &acc);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_sql_iter_next(self, acc);
+ }
+ if (HPMHooks.count.HP_account_db_sql_iter_next_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDBIterator *self, struct mmo_account *acc);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_sql_iter_next_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_sql_iter_next_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, self, acc);
+ }
+ }
+ return retVal___;
+}
+bool HP_account_db_read_inter(AccountDB_SQL *db, const char *filename, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_account_db_read_inter_pre > 0) {
+ bool (*preHookFunc) (AccountDB_SQL **db, const char **filename, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_read_inter_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_account_db_read_inter_pre[hIndex].func;
+ retVal___ = preHookFunc(&db, &filename, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.account.db_read_inter(db, filename, imported);
+ }
+ if (HPMHooks.count.HP_account_db_read_inter_post > 0) {
+ bool (*postHookFunc) (bool retVal___, AccountDB_SQL *db, const char *filename, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_account_db_read_inter_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_account_db_read_inter_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, db, filename, imported);
+ }
+ }
+ return retVal___;
+}
/* cmdline_interface */
void HP_cmdline_init(void) {
int hIndex = 0;
@@ -964,6 +1474,352 @@ void HP_des_decrypt(unsigned char *data, size_t size) {
}
return;
}
+/* ipban_interface */
+void HP_ipban_init(void) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_ipban_init_pre > 0) {
+ void (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_init_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_init_pre[hIndex].func;
+ preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.ipban.init();
+ }
+ if (HPMHooks.count.HP_ipban_init_post > 0) {
+ void (*postHookFunc) (void);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_init_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_init_post[hIndex].func;
+ postHookFunc();
+ }
+ }
+ return;
+}
+void HP_ipban_final(void) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_ipban_final_pre > 0) {
+ void (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_final_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_final_pre[hIndex].func;
+ preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.ipban.final();
+ }
+ if (HPMHooks.count.HP_ipban_final_post > 0) {
+ void (*postHookFunc) (void);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_final_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_final_post[hIndex].func;
+ postHookFunc();
+ }
+ }
+ return;
+}
+int HP_ipban_cleanup(int tid, int64 tick, int id, intptr_t data) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_ipban_cleanup_pre > 0) {
+ int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_cleanup_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_cleanup_pre[hIndex].func;
+ retVal___ = preHookFunc(&tid, &tick, &id, &data);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.ipban.cleanup(tid, tick, id, data);
+ }
+ if (HPMHooks.count.HP_ipban_cleanup_post > 0) {
+ int (*postHookFunc) (int retVal___, int tid, int64 tick, int id, intptr_t data);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_cleanup_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_cleanup_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, tid, tick, id, data);
+ }
+ }
+ return retVal___;
+}
+bool HP_ipban_config_read_inter(const char *filename, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_ipban_config_read_inter_pre > 0) {
+ bool (*preHookFunc) (const char **filename, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_config_read_inter_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_config_read_inter_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.ipban.config_read_inter(filename, imported);
+ }
+ if (HPMHooks.count.HP_ipban_config_read_inter_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_config_read_inter_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_config_read_inter_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, imported);
+ }
+ }
+ return retVal___;
+}
+bool HP_ipban_config_read_connection(const char *filename, struct config_t *config, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_ipban_config_read_connection_pre > 0) {
+ bool (*preHookFunc) (const char **filename, struct config_t **config, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_config_read_connection_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_config_read_connection_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &config, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.ipban.config_read_connection(filename, config, imported);
+ }
+ if (HPMHooks.count.HP_ipban_config_read_connection_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_config_read_connection_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_config_read_connection_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, config, imported);
+ }
+ }
+ return retVal___;
+}
+bool HP_ipban_config_read_dynamic(const char *filename, struct config_t *config, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_ipban_config_read_dynamic_pre > 0) {
+ bool (*preHookFunc) (const char **filename, struct config_t **config, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_config_read_dynamic_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_config_read_dynamic_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &config, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.ipban.config_read_dynamic(filename, config, imported);
+ }
+ if (HPMHooks.count.HP_ipban_config_read_dynamic_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_config_read_dynamic_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_config_read_dynamic_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, config, imported);
+ }
+ }
+ return retVal___;
+}
+bool HP_ipban_config_read(const char *filename, struct config_t *config, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_ipban_config_read_pre > 0) {
+ bool (*preHookFunc) (const char **filename, struct config_t **config, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_config_read_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_config_read_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &config, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.ipban.config_read(filename, config, imported);
+ }
+ if (HPMHooks.count.HP_ipban_config_read_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_config_read_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_config_read_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, config, imported);
+ }
+ }
+ return retVal___;
+}
+bool HP_ipban_check(uint32 ip) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_ipban_check_pre > 0) {
+ bool (*preHookFunc) (uint32 *ip);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_check_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_check_pre[hIndex].func;
+ retVal___ = preHookFunc(&ip);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.ipban.check(ip);
+ }
+ if (HPMHooks.count.HP_ipban_check_post > 0) {
+ bool (*postHookFunc) (bool retVal___, uint32 ip);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_check_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_check_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, ip);
+ }
+ }
+ return retVal___;
+}
+void HP_ipban_log(uint32 ip) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_ipban_log_pre > 0) {
+ void (*preHookFunc) (uint32 *ip);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_log_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_ipban_log_pre[hIndex].func;
+ preHookFunc(&ip);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.ipban.log(ip);
+ }
+ if (HPMHooks.count.HP_ipban_log_post > 0) {
+ void (*postHookFunc) (uint32 ip);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_ipban_log_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_ipban_log_post[hIndex].func;
+ postHookFunc(ip);
+ }
+ }
+ return;
+}
+/* lchrif_interface */
+void HP_lchrif_server_init(int id) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_lchrif_server_init_pre > 0) {
+ void (*preHookFunc) (int *id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_lchrif_server_init_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_lchrif_server_init_pre[hIndex].func;
+ preHookFunc(&id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.lchrif.server_init(id);
+ }
+ if (HPMHooks.count.HP_lchrif_server_init_post > 0) {
+ void (*postHookFunc) (int id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_lchrif_server_init_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_lchrif_server_init_post[hIndex].func;
+ postHookFunc(id);
+ }
+ }
+ return;
+}
+void HP_lchrif_server_destroy(int id) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_lchrif_server_destroy_pre > 0) {
+ void (*preHookFunc) (int *id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_lchrif_server_destroy_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_lchrif_server_destroy_pre[hIndex].func;
+ preHookFunc(&id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.lchrif.server_destroy(id);
+ }
+ if (HPMHooks.count.HP_lchrif_server_destroy_post > 0) {
+ void (*postHookFunc) (int id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_lchrif_server_destroy_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_lchrif_server_destroy_post[hIndex].func;
+ postHookFunc(id);
+ }
+ }
+ return;
+}
+void HP_lchrif_server_reset(int id) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_lchrif_server_reset_pre > 0) {
+ void (*preHookFunc) (int *id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_lchrif_server_reset_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_lchrif_server_reset_pre[hIndex].func;
+ preHookFunc(&id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.lchrif.server_reset(id);
+ }
+ if (HPMHooks.count.HP_lchrif_server_reset_post > 0) {
+ void (*postHookFunc) (int id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_lchrif_server_reset_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_lchrif_server_reset_post[hIndex].func;
+ postHookFunc(id);
+ }
+ }
+ return;
+}
+void HP_lchrif_on_disconnect(int id) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_lchrif_on_disconnect_pre > 0) {
+ void (*preHookFunc) (int *id);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_lchrif_on_disconnect_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_lchrif_on_disconnect_pre[hIndex].func;
+ preHookFunc(&id);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.lchrif.on_disconnect(id);
+ }
+ if (HPMHooks.count.HP_lchrif_on_disconnect_post > 0) {
+ void (*postHookFunc) (int id);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_lchrif_on_disconnect_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_lchrif_on_disconnect_post[hIndex].func;
+ postHookFunc(id);
+ }
+ }
+ return;
+}
/* lclif_interface */
void HP_lclif_init(void) {
int hIndex = 0;
@@ -5117,6 +5973,195 @@ uint16 HP_login_convert_users_to_colors(uint16 users) {
}
return retVal___;
}
+/* loginlog_interface */
+unsigned long HP_loginlog_failedattempts(uint32 ip, unsigned int minutes) {
+ int hIndex = 0;
+ unsigned long retVal___ = 0;
+ if (HPMHooks.count.HP_loginlog_failedattempts_pre > 0) {
+ unsigned long (*preHookFunc) (uint32 *ip, unsigned int *minutes);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_failedattempts_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_loginlog_failedattempts_pre[hIndex].func;
+ retVal___ = preHookFunc(&ip, &minutes);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.loginlog.failedattempts(ip, minutes);
+ }
+ if (HPMHooks.count.HP_loginlog_failedattempts_post > 0) {
+ unsigned long (*postHookFunc) (unsigned long retVal___, uint32 ip, unsigned int minutes);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_failedattempts_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_loginlog_failedattempts_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, ip, minutes);
+ }
+ }
+ return retVal___;
+}
+void HP_loginlog_log(uint32 ip, const char *username, int rcode, const char *message) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_loginlog_log_pre > 0) {
+ void (*preHookFunc) (uint32 *ip, const char **username, int *rcode, const char **message);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_log_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_loginlog_log_pre[hIndex].func;
+ preHookFunc(&ip, &username, &rcode, &message);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.loginlog.log(ip, username, rcode, message);
+ }
+ if (HPMHooks.count.HP_loginlog_log_post > 0) {
+ void (*postHookFunc) (uint32 ip, const char *username, int rcode, const char *message);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_log_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_loginlog_log_post[hIndex].func;
+ postHookFunc(ip, username, rcode, message);
+ }
+ }
+ return;
+}
+bool HP_loginlog_init(void) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_loginlog_init_pre > 0) {
+ bool (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_init_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_loginlog_init_pre[hIndex].func;
+ retVal___ = preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.loginlog.init();
+ }
+ if (HPMHooks.count.HP_loginlog_init_post > 0) {
+ bool (*postHookFunc) (bool retVal___);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_init_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_loginlog_init_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___);
+ }
+ }
+ return retVal___;
+}
+bool HP_loginlog_final(void) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_loginlog_final_pre > 0) {
+ bool (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_final_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_loginlog_final_pre[hIndex].func;
+ retVal___ = preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.loginlog.final();
+ }
+ if (HPMHooks.count.HP_loginlog_final_post > 0) {
+ bool (*postHookFunc) (bool retVal___);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_final_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_loginlog_final_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___);
+ }
+ }
+ return retVal___;
+}
+bool HP_loginlog_config_read_names(const char *filename, struct config_t *config, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_loginlog_config_read_names_pre > 0) {
+ bool (*preHookFunc) (const char **filename, struct config_t **config, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_config_read_names_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_loginlog_config_read_names_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &config, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.loginlog.config_read_names(filename, config, imported);
+ }
+ if (HPMHooks.count.HP_loginlog_config_read_names_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_config_read_names_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_loginlog_config_read_names_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, config, imported);
+ }
+ }
+ return retVal___;
+}
+bool HP_loginlog_config_read_log(const char *filename, struct config_t *config, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_loginlog_config_read_log_pre > 0) {
+ bool (*preHookFunc) (const char **filename, struct config_t **config, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_config_read_log_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_loginlog_config_read_log_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &config, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.loginlog.config_read_log(filename, config, imported);
+ }
+ if (HPMHooks.count.HP_loginlog_config_read_log_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, struct config_t *config, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_config_read_log_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_loginlog_config_read_log_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, config, imported);
+ }
+ }
+ return retVal___;
+}
+bool HP_loginlog_config_read(const char *filename, bool imported) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_loginlog_config_read_pre > 0) {
+ bool (*preHookFunc) (const char **filename, bool *imported);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_config_read_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_loginlog_config_read_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &imported);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.loginlog.config_read(filename, imported);
+ }
+ if (HPMHooks.count.HP_loginlog_config_read_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, bool imported);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_loginlog_config_read_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_loginlog_config_read_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, imported);
+ }
+ }
+ return retVal___;
+}
/* md5_interface */
void HP_md5_string(const char *string, char *output) {
int hIndex = 0;
diff --git a/src/plugins/HPMHooking/HPMHooking_login.sources.inc b/src/plugins/HPMHooking/HPMHooking_login.sources.inc
index 55ced3025..78c506043 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.sources.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.sources.inc
@@ -26,15 +26,19 @@
/* GENERATED FILE DO NOT EDIT */
HPMHooks.source.HCache = *HCache;
+HPMHooks.source.account = *account;
HPMHooks.source.cmdline = *cmdline;
HPMHooks.source.console = *console;
HPMHooks.source.core = *core;
HPMHooks.source.DB = *DB;
HPMHooks.source.des = *des;
+HPMHooks.source.ipban = *ipban;
+HPMHooks.source.lchrif = *lchrif;
HPMHooks.source.lclif = *lclif;
HPMHooks.source.PRIV__lclif = *lclif->p;
HPMHooks.source.libconfig = *libconfig;
HPMHooks.source.login = *login;
+HPMHooks.source.loginlog = *loginlog;
HPMHooks.source.md5 = *md5;
HPMHooks.source.mutex = *mutex;
HPMHooks.source.nullpo = *nullpo;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 7e9d5589b..9d531e370 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -3356,10 +3356,10 @@ struct {
struct HPMHookPoint *HP_map_create_map_data_other_server_post;
struct HPMHookPoint *HP_map_eraseallipport_sub_pre;
struct HPMHookPoint *HP_map_eraseallipport_sub_post;
- struct HPMHookPoint *HP_map_init_mapcache_pre;
- struct HPMHookPoint *HP_map_init_mapcache_post;
struct HPMHookPoint *HP_map_readfromcache_pre;
struct HPMHookPoint *HP_map_readfromcache_post;
+ struct HPMHookPoint *HP_map_readfromcache_v1_pre;
+ struct HPMHookPoint *HP_map_readfromcache_v1_post;
struct HPMHookPoint *HP_map_addmap_pre;
struct HPMHookPoint *HP_map_addmap_post;
struct HPMHookPoint *HP_map_delmapid_pre;
@@ -5054,6 +5054,8 @@ struct {
struct HPMHookPoint *HP_script_cleanfloor_sub_post;
struct HPMHookPoint *HP_script_run_func_pre;
struct HPMHookPoint *HP_script_run_func_post;
+ struct HPMHookPoint *HP_script_sprintf_pre;
+ struct HPMHookPoint *HP_script_sprintf_post;
struct HPMHookPoint *HP_script_getfuncname_pre;
struct HPMHookPoint *HP_script_getfuncname_post;
struct HPMHookPoint *HP_script_calc_hash_ci_pre;
@@ -9635,10 +9637,10 @@ struct {
int HP_map_create_map_data_other_server_post;
int HP_map_eraseallipport_sub_pre;
int HP_map_eraseallipport_sub_post;
- int HP_map_init_mapcache_pre;
- int HP_map_init_mapcache_post;
int HP_map_readfromcache_pre;
int HP_map_readfromcache_post;
+ int HP_map_readfromcache_v1_pre;
+ int HP_map_readfromcache_v1_post;
int HP_map_addmap_pre;
int HP_map_addmap_post;
int HP_map_delmapid_pre;
@@ -11333,6 +11335,8 @@ struct {
int HP_script_cleanfloor_sub_post;
int HP_script_run_func_pre;
int HP_script_run_func_post;
+ int HP_script_sprintf_pre;
+ int HP_script_sprintf_post;
int HP_script_getfuncname_pre;
int HP_script_getfuncname_post;
int HP_script_calc_hash_ci_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index f023731aa..5551668d2 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -1720,8 +1720,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(map->iwall_nextxy, HP_map_iwall_nextxy) },
{ HP_POP(map->create_map_data_other_server, HP_map_create_map_data_other_server) },
{ HP_POP(map->eraseallipport_sub, HP_map_eraseallipport_sub) },
- { HP_POP(map->init_mapcache, HP_map_init_mapcache) },
{ HP_POP(map->readfromcache, HP_map_readfromcache) },
+ { HP_POP(map->readfromcache_v1, HP_map_readfromcache_v1) },
{ HP_POP(map->addmap, HP_map_addmap) },
{ HP_POP(map->delmapid, HP_map_delmapid) },
{ HP_POP(map->zone_db_clear, HP_map_zone_db_clear) },
@@ -2589,6 +2589,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(script->buildin_mobuseskill_sub, HP_script_buildin_mobuseskill_sub) },
{ HP_POP(script->cleanfloor_sub, HP_script_cleanfloor_sub) },
{ HP_POP(script->run_func, HP_script_run_func) },
+ { HP_POP(script->sprintf, HP_script_sprintf) },
{ HP_POP(script->getfuncname, HP_script_getfuncname) },
{ HP_POP(script->calc_hash_ci, HP_script_calc_hash_ci) },
{ HP_POP(script->array_src, HP_script_array_src) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 467c57dd9..2e20ab157 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -25420,14 +25420,14 @@ void HP_clif_rodex_send_refresh(int fd, struct map_session_data *sd, int8 open_t
}
return;
}
-void HP_clif_rodex_send_mails_all(int fd, struct map_session_data *sd) {
+void HP_clif_rodex_send_mails_all(int fd, struct map_session_data *sd, int64 mail_id) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_rodex_send_mails_all_pre > 0) {
- void (*preHookFunc) (int *fd, struct map_session_data **sd);
+ void (*preHookFunc) (int *fd, struct map_session_data **sd, int64 *mail_id);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_rodex_send_mails_all_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_clif_rodex_send_mails_all_pre[hIndex].func;
- preHookFunc(&fd, &sd);
+ preHookFunc(&fd, &sd, &mail_id);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -25435,13 +25435,13 @@ void HP_clif_rodex_send_mails_all(int fd, struct map_session_data *sd) {
}
}
{
- HPMHooks.source.clif.rodex_send_mails_all(fd, sd);
+ HPMHooks.source.clif.rodex_send_mails_all(fd, sd, mail_id);
}
if (HPMHooks.count.HP_clif_rodex_send_mails_all_post > 0) {
- void (*postHookFunc) (int fd, struct map_session_data *sd);
+ void (*postHookFunc) (int fd, struct map_session_data *sd, int64 mail_id);
for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_rodex_send_mails_all_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_clif_rodex_send_mails_all_post[hIndex].func;
- postHookFunc(fd, sd);
+ postHookFunc(fd, sd, mail_id);
}
}
return;
@@ -44370,15 +44370,15 @@ int HP_map_eraseallipport_sub(union DBKey key, struct DBData *data, va_list va)
}
return retVal___;
}
-char* HP_map_init_mapcache(FILE *fp) {
+bool HP_map_readfromcache(struct map_data *m) {
int hIndex = 0;
- char* retVal___ = NULL;
- if (HPMHooks.count.HP_map_init_mapcache_pre > 0) {
- char* (*preHookFunc) (FILE **fp);
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_map_readfromcache_pre > 0) {
+ bool (*preHookFunc) (struct map_data **m);
*HPMforce_return = false;
- for (hIndex = 0; hIndex < HPMHooks.count.HP_map_init_mapcache_pre; hIndex++) {
- preHookFunc = HPMHooks.list.HP_map_init_mapcache_pre[hIndex].func;
- retVal___ = preHookFunc(&fp);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_map_readfromcache_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_map_readfromcache_pre[hIndex].func;
+ retVal___ = preHookFunc(&m);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -44386,26 +44386,26 @@ char* HP_map_init_mapcache(FILE *fp) {
}
}
{
- retVal___ = HPMHooks.source.map.init_mapcache(fp);
+ retVal___ = HPMHooks.source.map.readfromcache(m);
}
- if (HPMHooks.count.HP_map_init_mapcache_post > 0) {
- char* (*postHookFunc) (char* retVal___, FILE *fp);
- for (hIndex = 0; hIndex < HPMHooks.count.HP_map_init_mapcache_post; hIndex++) {
- postHookFunc = HPMHooks.list.HP_map_init_mapcache_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, fp);
+ if (HPMHooks.count.HP_map_readfromcache_post > 0) {
+ bool (*postHookFunc) (bool retVal___, struct map_data *m);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_map_readfromcache_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_map_readfromcache_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, m);
}
}
return retVal___;
}
-int HP_map_readfromcache(struct map_data *m, char *buffer) {
+bool HP_map_readfromcache_v1(FILE *fp, struct map_data *m, unsigned int file_size) {
int hIndex = 0;
- int retVal___ = 0;
- if (HPMHooks.count.HP_map_readfromcache_pre > 0) {
- int (*preHookFunc) (struct map_data **m, char **buffer);
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_map_readfromcache_v1_pre > 0) {
+ bool (*preHookFunc) (FILE **fp, struct map_data **m, unsigned int *file_size);
*HPMforce_return = false;
- for (hIndex = 0; hIndex < HPMHooks.count.HP_map_readfromcache_pre; hIndex++) {
- preHookFunc = HPMHooks.list.HP_map_readfromcache_pre[hIndex].func;
- retVal___ = preHookFunc(&m, &buffer);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_map_readfromcache_v1_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_map_readfromcache_v1_pre[hIndex].func;
+ retVal___ = preHookFunc(&fp, &m, &file_size);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -44413,13 +44413,13 @@ int HP_map_readfromcache(struct map_data *m, char *buffer) {
}
}
{
- retVal___ = HPMHooks.source.map.readfromcache(m, buffer);
+ retVal___ = HPMHooks.source.map.readfromcache_v1(fp, m, file_size);
}
- if (HPMHooks.count.HP_map_readfromcache_post > 0) {
- int (*postHookFunc) (int retVal___, struct map_data *m, char *buffer);
- for (hIndex = 0; hIndex < HPMHooks.count.HP_map_readfromcache_post; hIndex++) {
- postHookFunc = HPMHooks.list.HP_map_readfromcache_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, m, buffer);
+ if (HPMHooks.count.HP_map_readfromcache_v1_post > 0) {
+ bool (*postHookFunc) (bool retVal___, FILE *fp, struct map_data *m, unsigned int file_size);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_map_readfromcache_v1_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_map_readfromcache_v1_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, fp, m, file_size);
}
}
return retVal___;
@@ -67480,6 +67480,33 @@ int HP_script_run_func(struct script_state *st) {
}
return retVal___;
}
+bool HP_script_sprintf(struct script_state *st, int start, struct StringBuf *out) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_script_sprintf_pre > 0) {
+ bool (*preHookFunc) (struct script_state **st, int *start, struct StringBuf **out);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_script_sprintf_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_script_sprintf_pre[hIndex].func;
+ retVal___ = preHookFunc(&st, &start, &out);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.script.sprintf(st, start, out);
+ }
+ if (HPMHooks.count.HP_script_sprintf_post > 0) {
+ bool (*postHookFunc) (bool retVal___, struct script_state *st, int start, struct StringBuf *out);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_script_sprintf_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_script_sprintf_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, st, start, out);
+ }
+ }
+ return retVal___;
+}
const char* HP_script_getfuncname(struct script_state *st) {
int hIndex = 0;
const char* retVal___ = NULL;
diff --git a/src/plugins/mapcache.c b/src/plugins/mapcache.c
new file mode 100644
index 000000000..5e44492f6
--- /dev/null
+++ b/src/plugins/mapcache.c
@@ -0,0 +1,490 @@
+/**
+* This file is part of Hercules.
+* http://herc.ws - http://github.com/HerculesWS/Hercules
+*
+* Copyright (C) 2013-2015 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * Mapcache Plugin
+ * This Plugin is made to handle the creation and update the new format of mapcache
+ * it also handles the convertion from the old to the new mapcache format
+ **/
+
+#include "common/hercules.h" /* Should always be the first Hercules file included! (if you don't make it first, you won't be able to use interfaces) */
+
+#include "common/memmgr.h"
+#include "common/md5calc.h"
+#include "common/nullpo.h"
+#include "common/grfio.h"
+#include "common/utils.h"
+#include "map/map.h"
+
+#include "common/HPMDataCheck.h" /* should always be the last Hercules file included! (if you don't make it last, it'll intentionally break compile time) */
+
+#include <stdio.h>
+#include <string.h>
+
+HPExport struct hplugin_info pinfo = {
+ "Mapcache", ///< Plugin name
+ SERVER_TYPE_MAP, ///< Which server types this plugin works with?
+ "1.0.0", ///< Plugin version
+ HPM_VERSION, ///< HPM Version (don't change, macro is automatically updated)
+};
+
+/**
+ * Yes.. old mapcache was never packed, and we loaded and wrote a compiler paded structs
+ * DON'T BLAME IF SOMETHING EXPLODED [hemagx]
+ **/
+// This is the main header found at the very beginning of the map cache
+struct old_mapcache_main_header {
+ uint32 file_size;
+ uint16 map_count;
+};
+
+// This is the header appended before every compressed map cells info in the map cache
+struct old_mapcache_map_info {
+ char name[MAP_NAME_LENGTH];
+ int16 xs;
+ int16 ys;
+ int32 len;
+};
+
+/**
+ *
+ */
+
+#define NO_WATER 1000000
+
+VECTOR_DECL(char *) maplist;
+bool needs_grfio;
+
+
+/**
+ * code from utlis.c until it's interfaced
+ **/
+
+#ifdef WIN32
+# ifndef F_OK
+# define F_OK 0x0
+# endif /* F_OK */
+#else
+# include <unistd.h>
+#endif
+
+
+// Reads an uint32 in little-endian from the buffer
+uint32 GetULong(const unsigned char* buf)
+{
+ return (((uint32)(buf[0])))
+ | (((uint32)(buf[1])) << 0x08)
+ | (((uint32)(buf[2])) << 0x10)
+ | (((uint32)(buf[3])) << 0x18);
+}
+
+// Reads a float (32 bits) from the buffer
+float GetFloat(const unsigned char* buf)
+{
+ uint32 val = GetULong(buf);
+ return *((float*)(void*)&val);
+}
+
+bool write_mapcache(const uint8 *buf, int32 buf_len, bool is_compressed, const char *mapname, int16 xs, int16 ys)
+{
+ struct map_cache_header header = { 0 };
+ char file_path[255];
+ int mapname_len;
+ unsigned long compressed_buf_len;
+ uint8 *compressed_buf = NULL;
+ FILE *new_mapcache_fp;
+
+ nullpo_retr(false, buf);
+ nullpo_retr(false, mapname);
+
+ mapname_len = (int)strlen(mapname);
+
+ if (mapname_len > MAP_NAME_LENGTH || mapname_len < 1) {
+ ShowError("write_mapcache: A map with invalid name length has beed passed '%s' size (%d)\n", mapname, mapname_len);
+ return false;
+ }
+
+ if ((xs < 0 || ys < 0)) {
+ ShowError("write_mapcache: '%s' given with invalid coords xs = %d, ys = %d\n", mapname, xs, ys);
+ return false;
+ }
+
+ if (((int)xs * ys) > MAX_MAP_SIZE) {
+ ShowError("write_mapcache: map '%s' exceeded MAX_MAP_SIZE of %d\n", mapname, MAX_MAP_SIZE);
+ return false;
+ }
+
+
+
+ snprintf(file_path, sizeof(file_path), "%s%s%s.%s", "maps/", DBPATH, mapname, "mcache");
+ new_mapcache_fp = fopen(file_path, "wb");
+
+ if (new_mapcache_fp == NULL) {
+ ShowWarning("Could not open file '%s', map cache creating failed.\n", file_path);
+ return false;
+ }
+
+ header.version = 0x1;
+ header.xs = xs;
+ header.ys = ys;
+
+ if (is_compressed == false) {
+ compressed_buf_len = buf_len * 2; //Creating big enough buffer to ensure ability to hold compressed data
+ CREATE(compressed_buf, uint8, compressed_buf_len);
+ grfio->encode_zip(compressed_buf, &compressed_buf_len, buf, buf_len);
+
+ header.len = (int)compressed_buf_len;
+ md5->binary(compressed_buf, (int)compressed_buf_len, header.md5_checksum);
+ } else {
+ header.len = buf_len;
+ md5->binary(buf, buf_len, header.md5_checksum);
+ }
+
+
+ fwrite(&header, sizeof(header), 1, new_mapcache_fp);
+ if (is_compressed == false)
+ fwrite(compressed_buf, compressed_buf_len, 1, new_mapcache_fp);
+ else
+ fwrite(buf, buf_len, 1, new_mapcache_fp);
+
+ fclose(new_mapcache_fp);
+ if (compressed_buf != NULL)
+ aFree(compressed_buf);
+
+ return true;
+}
+
+bool convert_old_mapcache(void)
+{
+ const char *path = "db/"DBPATH"map_cache.dat";
+ FILE *mapcache_fp = fopen(path, "rb");
+ struct old_mapcache_main_header header = { 0 };
+ uint8 *p, *cursor;
+ uint32 file_size;
+ int i;
+
+ if (mapcache_fp == NULL) {
+ ShowError("Could not open mapcache file in the following path '%s' \n", path);
+ return false;
+ }
+
+ if (fread(&header, sizeof(header), 1, mapcache_fp) != 1) {
+ ShowError("Failed to read mapcache header \n");
+ fclose(mapcache_fp);
+ return false;
+ }
+
+ fseek(mapcache_fp, 0, SEEK_END);
+ file_size = (int)ftell(mapcache_fp);
+ fseek(mapcache_fp, 0, SEEK_SET);
+
+ if (file_size != header.file_size) {
+ ShowError("File size in mapcache header doesn't match actual mapcache file size \n");
+ fclose(mapcache_fp);
+ return false;
+ }
+
+ CREATE(p, uint8, header.file_size);
+ cursor = p + sizeof(header);
+
+ if (fread(p, header.file_size, 1, mapcache_fp) != 1) {
+ ShowError("Could not load mapcache file into memory, fread failed.\n");
+ aFree(p);
+ fclose(mapcache_fp);
+ return false;
+ }
+
+ for (i = 0; i < header.map_count; ++i) {
+ struct old_mapcache_map_info *info = (struct old_mapcache_map_info *)cursor;
+
+ ShowStatus("Creating mapcache: %s"CL_CLL"\n", info->name);
+
+ if (write_mapcache((uint8 *)info + sizeof(*info), info->len, true, info->name, info->xs, info->ys) == false) {
+ ShowError("failed To convert map '%s'\n", info->name);
+ }
+
+ cursor += sizeof(*info) + info->len;
+ }
+
+ aFree(p);
+ fclose(mapcache_fp);
+ return true;
+}
+
+bool mapcache_read_maplist(const char *filepath)
+{
+ char line[4096] = { 0 };
+ FILE *fp;
+
+ nullpo_retr(false, filepath);
+
+ fp = fopen(filepath, "r");
+
+ if (fp == NULL)
+ return false;
+
+ while (fgets(line, sizeof(line), fp)) {
+ char map_name[MAP_NAME_LENGTH];
+ if (line[0] == '/' && line[1] == '/')
+ continue;
+
+ if (sscanf(line, "%11s", map_name) == 1) {
+ VECTOR_ENSURE(maplist, 1, 1);
+ VECTOR_PUSH(maplist, aStrdup(map_name));
+ }
+ }
+
+ ShowStatus("%d map loaded from map_index.txt\n", VECTOR_LENGTH(maplist));
+ fclose(fp);
+ return true;
+}
+
+bool mapcache_cache_map(const char *mapname)
+{
+ char filepath[255] = { 0 };
+ uint8 *gat, *rsw, *gat_cursor;
+ uint8 *cells;
+ int water_height, map_size, xy;
+ int16 xs, ys;
+
+ nullpo_retr(false, mapname);
+
+ snprintf(filepath, sizeof(filepath), "data\\%s.gat", mapname);
+ gat = grfio_read(filepath);
+
+ if (gat == NULL) {
+ ShowError("mapcache_cache_map: Could not read %s, aborting caching map %s\n", filepath, mapname);
+ return false;
+ }
+
+ snprintf(filepath, sizeof(filepath), "data\\%s.rsw", mapname);
+
+ rsw = grfio_read(filepath);
+
+ if (rsw == NULL) {
+ water_height = NO_WATER;
+ } else {
+ water_height = (int)GetFloat(rsw + 166);
+ aFree(rsw);
+ }
+
+ xs = (int16)GetULong(gat + 6);
+ ys = (int16)GetULong(gat + 10);
+
+ if (xs <= 0 || ys <= 0) {
+ ShowError("mapcache_cache_map: map '%s' doesn't have valid size xs = %d, ys = %d\n", mapname, xs, ys);
+ aFree(gat);
+ return false;
+ }
+
+ map_size = xs * ys;
+ CREATE(cells, uint8, map_size);
+
+ gat_cursor = gat;
+ for (xy = 0; xy < map_size; ++xy) {
+ float height = GetFloat(gat_cursor + 14);
+ uint32 type = GetULong(gat_cursor + 30);
+ gat_cursor += 20;
+
+ if (type == 0 && water_height != NO_WATER && height > water_height)
+ type = 3;
+
+ cells[xy] = (uint8)type;
+ }
+
+ write_mapcache(cells, map_size, false, mapname, xs, ys);
+
+ aFree(gat);
+ aFree(cells);
+ return true;
+}
+
+bool mapcache_rebuild(void)
+{
+ int i;
+ char file_path[255];
+
+ if (mapcache_read_maplist("db/map_index.txt") == false) {
+ ShowError("mapcache_rebuild: Could not read maplist, aborting\n");
+ return false;
+ }
+
+ for (i = 0; i < VECTOR_LENGTH(maplist); ++i) {
+ snprintf(file_path, sizeof(file_path), "%s%s%s.%s", "maps/", DBPATH, VECTOR_INDEX(maplist, i), "mcache");
+ if (access(file_path, F_OK) == 0 && remove(file_path) != 0) {
+ ShowWarning("mapcache_rebuild: Could not remove file '%s' \n", file_path);
+ }
+ }
+
+ for (i = 0; i < VECTOR_LENGTH(maplist); ++i) {
+ ShowStatus("Creating mapcache: %s"CL_CLL"\r", VECTOR_INDEX(maplist, i));
+ mapcache_cache_map(VECTOR_INDEX(maplist, i));
+ }
+
+ return true;
+}
+
+bool fix_md5_truncation_sub(FILE *fp, const char *map_name)
+{
+ unsigned int file_size;
+ struct map_cache_header mheader = { 0 };
+ uint8 *buf = NULL;
+
+ nullpo_retr(false, fp);
+ nullpo_retr(false, map_name);
+
+ fseek(fp, 0, SEEK_END);
+ file_size = (unsigned int)ftell(fp);
+ fseek(fp, 0, SEEK_SET); // Rewind file pointer before passing it to the read function.
+
+ if (file_size <= sizeof(mheader) || fread(&mheader, sizeof(mheader), 1, fp) < 1) {
+ ShowError("fix_md5_truncation: Failed to read cache header for map '%s'.\n", map_name);
+ return false;
+ }
+
+ if (mheader.len <= 0) {
+ ShowError("fix_md5_truncation: A file with negative or zero compressed length passed '%d'.\n", mheader.len);
+ return false;
+ }
+
+ if (file_size < sizeof(mheader) + mheader.len) {
+ ShowError("fix_md5_truncation: An incomplete file passed for map '%s'.\n", map_name);
+ return false;
+ }
+
+ CREATE(buf, uint8, mheader.len);
+ if (fread(buf, mheader.len, 1, fp) < 1) {
+ ShowError("fix_md5_truncation: Could not load the compressed cell data for map '%s'.\n", map_name);
+ aFree(buf);
+ return false;
+ }
+
+ md5->binary(buf, mheader.len, mheader.md5_checksum);
+ aFree(buf);
+
+ fseek(fp, 0, SEEK_SET);
+ fwrite(&mheader, sizeof(mheader), 1, fp);
+ fclose(fp);
+
+ return true;
+}
+
+bool fix_md5_truncation(void)
+{
+ int i;
+ bool retval = true;
+
+ if (mapcache_read_maplist("db/map_index.txt") == false) {
+ ShowError("mapcache_rebuild: Could not read maplist, aborting\n");
+ return false;
+ }
+
+ for (i = 0; i < VECTOR_LENGTH(maplist); ++i) {
+ const char *map_name = VECTOR_INDEX(maplist, i);
+ char file_path[255];
+ FILE *fp = NULL;
+ int16 version;
+
+ snprintf(file_path, sizeof(file_path), "%s%s%s.%s", "maps/", DBPATH, map_name, "mcache");
+
+ fp = fopen(file_path, "r+b");
+
+ if (fp == NULL) {
+ ShowWarning("fix_md5_truncation: Could not open the mapcache file for map '%s' at path '%s'.\n", map_name, file_path);
+ retval = false;
+ continue;
+ }
+
+ if (fread(&version, sizeof(version), 1, fp) < 1) {
+ ShowError("fix_md5_truncation: Could not read file version for map '%s'.\n", map_name);
+ fclose(fp);
+ retval = false;
+ continue;
+ }
+
+ if (version != 1) {
+ ShowError("fix_md5_truncation: Mapcache for map '%s' has version %d. The update is only applied to version 1.\n", map_name, version);
+ fclose(fp);
+ continue;
+ }
+
+ ShowStatus("Updating mapcache: %s'\n", map_name);
+ if (!fix_md5_truncation_sub(fp, map_name))
+ retval = false;
+
+ fclose(fp);
+ }
+
+ return retval;
+}
+
+CMDLINEARG(convertmapcache)
+{
+ map->minimal = true;
+ return convert_old_mapcache();
+}
+
+CMDLINEARG(rebuild)
+{
+ needs_grfio = true;
+ grfio->init("conf/grf-files.txt");
+ map->minimal = true;
+ return mapcache_rebuild();
+}
+
+CMDLINEARG(cachemap)
+{
+ needs_grfio = true;
+ grfio->init("conf/grf-files.txt");
+ map->minimal = true;
+ return mapcache_cache_map(params);
+}
+
+CMDLINEARG(fixmd5)
+{
+ map->minimal = true;
+ return fix_md5_truncation();
+}
+
+HPExport void server_preinit(void)
+{
+ addArg("--convert-old-mapcache", false, convertmapcache,
+ "Converts an old db/"DBPATH"map_cache.dat file to the new format.");
+ addArg("--rebuild-mapcache", false, rebuild,
+ "Rebuilds the entire mapcache folder (maps/"DBPATH"), using db/map_index.txt as index.");
+ addArg("--map", true, cachemap,
+ "Rebuilds an individual map's cache into maps/"DBPATH" (usage: --map <map_name_without_extension>).");
+ addArg("--fix-md5", false, fixmd5,
+ "Updates the checksum for the files in maps/"DBPATH", using db/map_index.txt as index (see PR #1981).");
+
+ needs_grfio = false;
+ VECTOR_INIT(maplist);
+}
+
+HPExport void plugin_final(void)
+{
+ while (VECTOR_LENGTH(maplist) > 0) {
+ char *name = VECTOR_POP(maplist);
+ aFree(name);
+ }
+ VECTOR_CLEAR(maplist);
+ if (needs_grfio)
+ grfio->final();
+}
diff --git a/src/tool/Makefile.in b/src/tool/Makefile.in
index 6e8643c56..fff29145e 100644
--- a/src/tool/Makefile.in
+++ b/src/tool/Makefile.in
@@ -36,26 +36,15 @@ LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \
LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \
scanctx.h scanner.h strbuf.h wincompat.h)
-MAPCACHE_OBJ = obj_all/mapcache.o
-MAPCACHE_C = mapcache.c
-MAPCACHE_H =
-MAPCACHE_DEPENDS = $(MAPCACHE_OBJ) $(COMMON_D)/obj_all/common_mini.a $(LIBCONFIG_OBJ) $(SYSINFO_INC)
-
@SET_MAKE@
CC = @CC@
export CC
#####################################################################
-.PHONY: all mapcache clean buildclean help
-
-all: mapcache Makefile
-
-mapcache: ../../mapcache@EXEEXT@
+.PHONY: all clean buildclean help
-../../mapcache@EXEEXT@: $(MAPCACHE_DEPENDS) Makefile
- @echo " LD $(notdir $@)"
- @$(CC) @STATIC@ @LDFLAGS@ -o ../../mapcache@EXEEXT@ $(MAPCACHE_OBJ) $(COMMON_D)/obj_all/common_mini.a $(LIBCONFIG_OBJ) @LIBS@
+all: Makefile
buildclean:
@echo " CLEAN tool (build temp files)"
@@ -63,11 +52,9 @@ buildclean:
clean: buildclean
@echo " CLEAN tool"
- @rm -rf ../../mapcache@EXEEXT@
help:
- @echo "possible targets are 'mapcache' 'all' 'clean' 'help'"
- @echo "'mapcache' - mapcache generator"
+ @echo "possible targets are 'all' 'clean' 'help'"
@echo "'all' - builds all above targets"
@echo "'clean' - cleans builds and objects"
@echo "'buildclean' - cleans build temporary (object) files, without deleting the"
@@ -79,7 +66,7 @@ help:
Makefile: Makefile.in
@$(MAKE) -C ../.. src/tool/Makefile
-$(SYSINFO_INC): $(MAPCACHE_C) $(MAPCACHE_H) $(COMMON_H) $(CONFIG_H) $(LIBCONFIG_H)
+$(SYSINFO_INC): $(COMMON_H) $(CONFIG_H) $(LIBCONFIG_H)
@echo " MAKE $@"
@$(MAKE) -C ../.. sysinfo
@@ -87,7 +74,7 @@ obj_all:
@echo " MKDIR obj_all"
@-mkdir obj_all
-obj_all/%.o: %.c $(MAPCACHE_H) $(COMMON_H) $(CONFIG_H) $(LIBCONFIG_H) | obj_all
+obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(LIBCONFIG_H) | obj_all
@echo " CC $<"
@$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
diff --git a/src/tool/mapcache.c b/src/tool/mapcache.c
deleted file mode 100644
index 5eb0843aa..000000000
--- a/src/tool/mapcache.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/**
- * This file is part of Hercules.
- * http://herc.ws - http://github.com/HerculesWS/Hercules
- *
- * Copyright (C) 2012-2016 Hercules Dev Team
- * Copyright (C) Athena Dev Teams
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-#define HERCULES_CORE
-
-#include "common/cbasetypes.h"
-#include "common/core.h"
-#include "common/grfio.h"
-#include "common/memmgr.h"
-#include "common/mmo.h"
-#include "common/showmsg.h"
-#include "common/strlib.h"
-#include "common/utils.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
-#define NO_WATER 1000000
-
-char *grf_list_file;
-char *map_list_file;
-char *map_cache_file;
-int rebuild = 0;
-
-FILE *map_cache_fp;
-
-unsigned long file_size;
-
-// Used internally, this structure contains the physical map cells
-struct map_data {
- int16 xs;
- int16 ys;
- unsigned char *cells;
-};
-
-// This is the main header found at the very beginning of the file
-struct main_header {
- uint32 file_size;
- uint16 map_count;
-} header;
-
-// This is the header appended before every compressed map cells info
-struct map_info {
- char name[MAP_NAME_LENGTH];
- int16 xs;
- int16 ys;
- int32 len;
-};
-
-// Reads a map from GRF's GAT and RSW files
-int read_map(char *name, struct map_data *m)
-{
- char filename[256];
- unsigned char *gat, *rsw;
- int water_height;
- size_t xy, off, num_cells;
-
- // Open map GAT
- sprintf(filename,"data\\%s.gat", name);
- gat = grfio_read(filename);
- if (gat == NULL)
- return 0;
-
- // Open map RSW
- sprintf(filename,"data\\%s.rsw", name);
- rsw = grfio_read(filename);
-
- // Read water height
- if (rsw) {
- water_height = (int)GetFloat(rsw+166);
- aFree(rsw);
- } else
- water_height = NO_WATER;
-
- // Read map size and allocate needed memory
- m->xs = (int16)GetULong(gat+6);
- m->ys = (int16)GetULong(gat+10);
- if (m->xs <= 0 || m->ys <= 0) {
- aFree(gat);
- return 0;
- }
- num_cells = (size_t)m->xs*(size_t)m->ys;
- m->cells = (unsigned char *)aMalloc(num_cells);
-
- // Set cell properties
- off = 14;
- for (xy = 0; xy < num_cells; xy++) {
- // Height of the bottom-left corner
- float height = GetFloat(gat + off);
- // Type of cell
- uint32 type = GetULong(gat + off + 16);
- off += 20;
-
- if (type == 0 && water_height != NO_WATER && height > water_height)
- type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
-
- m->cells[xy] = (unsigned char)type;
- }
-
- aFree(gat);
-
- return 1;
-}
-
-/**
- * Adds a map to the cache.
- *
- * @param name The map name.
- * @param m Map data to cache.
- * @retval true if the map was successfully added to the cache.
- */
-bool cache_map(char *name, struct map_data *m)
-{
- struct map_info info;
- unsigned long len;
- unsigned char *write_buf;
-
- // Create an output buffer twice as big as the uncompressed map... this way we're sure it fits
- len = (unsigned long)m->xs*(unsigned long)m->ys*2;
- write_buf = (unsigned char *)aMalloc(len);
- // Compress the cells and get the compressed length
- grfio->encode_zip(write_buf, &len, m->cells, m->xs*m->ys);
-
- // Fill the map header
- safestrncpy(info.name, name, MAP_NAME_LENGTH);
- if (strlen(name) > MAP_NAME_LENGTH) // It does not hurt to warn that there are maps with name longer than allowed.
- ShowWarning("Map name '%s' (length %"PRIuS") is too long. Truncating to '%s' (length %d).\n",
- name, strlen(name), info.name, MAP_NAME_LENGTH);
- info.xs = MakeShortLE(m->xs);
- info.ys = MakeShortLE(m->ys);
- info.len = MakeLongLE((uint32)len);
-
- // Append map header then compressed cells at the end of the file
- if (fseek(map_cache_fp, header.file_size, SEEK_SET) != 0) {
- aFree(write_buf);
- aFree(m->cells);
- return false;
- }
- fwrite(&info, sizeof(struct map_info), 1, map_cache_fp);
- fwrite(write_buf, 1, len, map_cache_fp);
- header.file_size += sizeof(struct map_info) + len;
- header.map_count++;
-
- aFree(write_buf);
- aFree(m->cells);
-
- return true;
-}
-
-/**
- * Checks whether a map is already is the cache.
- *
- * @param name The map name.
- * @retval true if the map is already cached.
- */
-bool find_map(char *name)
-{
- int i;
- struct map_info info;
-
- if (fseek(map_cache_fp, sizeof(struct main_header), SEEK_SET) != 0)
- return false;
-
- for (i = 0; i < header.map_count; i++) {
- if (fread(&info, sizeof(info), 1, map_cache_fp) != 1)
- printf("An error as occured in fread while reading map_cache\n");
- if (strcmp(name, info.name) == 0) // Map found
- return true;
- // Map not found, jump to the beginning of the next map info header
- if (fseek(map_cache_fp, GetLong((unsigned char *)&(info.len)), SEEK_CUR) != 0)
- return false;
- }
-
- return false;
-}
-
-// Cuts the extension from a map name
-char *remove_extension(char *mapname)
-{
- char *ptr, *ptr2;
- ptr = strchr(mapname, '.');
- if (ptr) { //Check and remove extension.
- while (ptr[1] && (ptr2 = strchr(ptr+1, '.')) != NULL)
- ptr = ptr2; //Skip to the last dot.
- if (strcmp(ptr,".gat") == 0)
- *ptr = '\0'; //Remove extension.
- }
- return mapname;
-}
-
-/**
- * --grf-list handler
- *
- * Overrides the default grf list filename.
- * @see cmdline->exec
- */
-static CMDLINEARG(grflist)
-{
- aFree(grf_list_file);
- grf_list_file = aStrdup(params);
- return true;
-}
-
-/**
- * --map-list handler
- *
- * Overrides the default map list filename.
- * @see cmdline->exec
- */
-static CMDLINEARG(maplist)
-{
- aFree(map_list_file);
- map_list_file = aStrdup(params);
- return true;
-}
-
-/**
- * --map-cache handler
- *
- * Overrides the default map cache filename.
- * @see cmdline->exec
- */
-static CMDLINEARG(mapcache)
-{
- aFree(map_cache_file);
- map_cache_file = aStrdup(params);
- return true;
-}
-
-/**
- * --rebuild handler
- *
- * Forces a rebuild of the mapcache, rather than only adding missing maps.
- * @see cmdline->exec
- */
-static CMDLINEARG(rebuild)
-{
- rebuild = 1;
- return true;
-}
-
-/**
- * Defines the local command line arguments
- */
-void cmdline_args_init_local(void)
-{
- CMDLINEARG_DEF2(grf-list, grflist, "Alternative grf list file", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM);
- CMDLINEARG_DEF2(map-list, maplist, "Alternative map list file", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM);
- CMDLINEARG_DEF2(map-cache, mapcache, "Alternative map cache file", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM);
- CMDLINEARG_DEF2(rebuild, rebuild, "Forces a rebuild of the map cache, rather than only adding missing maps", CMDLINE_OPT_NORMAL);
-}
-
-int do_init(int argc, char** argv)
-{
- FILE *list;
- char line[1024];
- struct map_data map;
- char name[MAP_NAME_LENGTH_EXT];
-
- grf_list_file = aStrdup("conf/grf-files.txt");
- map_list_file = aStrdup("db/map_index.txt");
- /* setup pre-defined, #define-dependant */
- map_cache_file = aStrdup("db/"DBPATH"map_cache.dat");
-
- cmdline->exec(argc, argv, CMDLINE_OPT_PREINIT);
- cmdline->exec(argc, argv, CMDLINE_OPT_NORMAL);
-
- ShowStatus("Initializing grfio with %s\n", grf_list_file);
- grfio->init(grf_list_file);
-
- // Attempt to open the map cache file and force rebuild if not found
- ShowStatus("Opening map cache: %s\n", map_cache_file);
- if(!rebuild) {
- map_cache_fp = fopen(map_cache_file, "rb");
- if(map_cache_fp == NULL) {
- ShowNotice("Existing map cache not found, forcing rebuild mode\n");
- rebuild = 1;
- } else
- fclose(map_cache_fp);
- }
- if(rebuild)
- map_cache_fp = fopen(map_cache_file, "w+b");
- else
- map_cache_fp = fopen(map_cache_file, "r+b");
- if(map_cache_fp == NULL) {
- ShowError("Failure when opening map cache file %s\n", map_cache_file);
- exit(EXIT_FAILURE);
- }
-
- // Open the map list
- ShowStatus("Opening map list: %s\n", map_list_file);
- list = fopen(map_list_file, "r");
- if(list == NULL) {
- ShowError("Failure when opening maps list file %s\n", map_list_file);
- exit(EXIT_FAILURE);
- }
-
- // Initialize the main header
- if(rebuild) {
- header.file_size = sizeof(struct main_header);
- header.map_count = 0;
- } else {
- if(fread(&header, sizeof(struct main_header), 1, map_cache_fp) != 1){ printf("An error as occured while reading map_cache_fp \n"); }
- header.file_size = GetULong((unsigned char *)&(header.file_size));
- header.map_count = GetUShort((unsigned char *)&(header.map_count));
- }
-
- // Read and process the map list
- while(fgets(line, sizeof(line), list))
- {
- if(line[0] == '/' && line[1] == '/')
- continue;
-
- if(sscanf(line, "%15s", name) < 1)
- continue;
-
- if(strcmp("map:", name) == 0 && sscanf(line, "%*s %15s", name) < 1)
- continue;
-
- name[MAP_NAME_LENGTH_EXT-1] = '\0';
- remove_extension(name);
- if (find_map(name)) {
- ShowInfo("Map '"CL_WHITE"%s"CL_RESET"' already in cache.\n", name);
- } else if(!read_map(name, &map)) {
- ShowError("Map '"CL_WHITE"%s"CL_RESET"' not found!\n", name);
- } else if (!cache_map(name, &map)) {
- ShowError("Map '"CL_WHITE"%s"CL_RESET"' failed to cache (write error).\n", name);
- } else {
- ShowInfo("Map '"CL_WHITE"%s"CL_RESET"' successfully cached.\n", name);
- }
- }
-
- ShowStatus("Closing map list: %s\n", map_list_file);
- fclose(list);
-
- // Write the main header and close the map cache
- ShowStatus("Closing map cache: %s\n", map_cache_file);
- fseek(map_cache_fp, 0, SEEK_SET);
- fwrite(&header, sizeof(struct main_header), 1, map_cache_fp);
- fclose(map_cache_fp);
-
- ShowStatus("Finalizing grfio\n");
- grfio->final();
-
- ShowInfo("%d maps now in cache\n", header.map_count);
-
- aFree(grf_list_file);
- aFree(map_list_file);
- aFree(map_cache_file);
-
- return 0;
-}
-
-int do_final(void)
-{
- return EXIT_SUCCESS;
-}