diff options
Diffstat (limited to 'src/char')
-rw-r--r-- | src/char/HPMchar.c | 1 | ||||
-rw-r--r-- | src/char/Makefile.in | 2 | ||||
-rw-r--r-- | src/char/char.c | 181 | ||||
-rw-r--r-- | src/char/char.h | 4 | ||||
-rw-r--r-- | src/char/packets_hc_struct.h | 45 |
5 files changed, 178 insertions, 55 deletions
diff --git a/src/char/HPMchar.c b/src/char/HPMchar.c index db2c3702e..f3cf2cff4 100644 --- a/src/char/HPMchar.c +++ b/src/char/HPMchar.c @@ -57,6 +57,7 @@ #include "common/mapindex.h" #include "common/mmo.h" #include "common/nullpo.h" +#include "common/packets.h" #include "common/random.h" #include "common/showmsg.h" #include "common/socket.h" diff --git a/src/char/Makefile.in b/src/char/Makefile.in index 95c8df813..f159a443f 100644 --- a/src/char/Makefile.in +++ b/src/char/Makefile.in @@ -46,7 +46,7 @@ CHAR_C = char.c HPMchar.c loginif.c mapif.c geoip.c inter.c int_achievement.c in CHAR_OBJ = $(addprefix obj_sql/, $(patsubst %.c,%.o,$(CHAR_C))) CHAR_H = char.h HPMchar.h loginif.h mapif.h geoip.h inter.h int_achievement.h int_auction.h int_clan.h int_elemental.h \ int_guild.h int_homun.h int_mail.h int_mercenary.h int_party.h int_pet.h \ - int_quest.h int_rodex.h int_storage.h pincode.h + int_quest.h int_rodex.h int_storage.h pincode.h packets_hc_struct.h CHAR_PH = HAVE_MYSQL=@HAVE_MYSQL@ diff --git a/src/char/char.c b/src/char/char.c index 54f6ca7d1..0546e49df 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -21,7 +21,7 @@ #define HERCULES_CORE #include "config/core.h" // CONSOLE_INPUT -#include "char.h" +#include "char/char.h" #include "char/HPMchar.h" #include "char/geoip.h" @@ -41,6 +41,7 @@ #include "char/inter.h" #include "char/loginif.h" #include "char/mapif.h" +#include "char/packets_hc_struct.h" #include "char/pincode.h" #include "common/HPM.h" @@ -53,6 +54,7 @@ #include "common/mapindex.h" #include "common/mmo.h" #include "common/nullpo.h" +#include "common/packetsstatic_len.h" #include "common/showmsg.h" #include "common/socket.h" #include "common/strlib.h" @@ -139,6 +141,7 @@ char char_name_letters[1024] = ""; // list of letters/symbols allowed (or not) i static int char_del_level = 0; ///< From which level you can delete character [Lupus] static int char_del_delay = 86400; static bool char_aegis_delete = false; ///< Verify if char is in guild/party or char and reacts as Aegis does (disallow deletion), @see chr->delete2_req. +static bool char_aegis_rename = false; // whether or not the player can be renamed while in party/guild static int max_connect_user = -1; static int gm_allow_group = -1; @@ -476,11 +479,18 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) (p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font) || (p->uniqueitem_counter != cp->uniqueitem_counter) || (p->hotkey_rowshift != cp->hotkey_rowshift) || (p->clan_id != cp->clan_id) || (p->last_login != cp->last_login) || (p->attendance_count != cp->attendance_count) || - (p->attendance_timer != cp->attendance_timer) || (p->title_id != cp->title_id) + (p->attendance_timer != cp->attendance_timer) || (p->title_id != cp->title_id) || (p->inventorySize != cp->inventorySize) ) { //Save status unsigned int opt = 0; + if (p->inventorySize <= 0 || p->inventorySize > MAX_INVENTORY) { + ShowError("Wrong inventorySize field: %d. Must be in range 1 to %d. Character %s (CID: %d, AID: %d)\n", + p->inventorySize, MAX_INVENTORY, p->name, p->char_id, p->account_id); + Assert_report(0); + p->inventorySize = FIXED_INVENTORY_SIZE; + } + if( p->allow_party ) opt |= OPT_ALLOW_PARTY; if( p->show_equip ) @@ -495,7 +505,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) "`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d'," "`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u'," "`hotkey_rowshift`='%d',`clan_id`='%d',`last_login`='%"PRId64"',`attendance_count`='%d',`attendance_timer`='%"PRId64"'," - "`title_id`='%d'" + "`title_id`='%d', `inventory_size`='%d'" " WHERE `account_id`='%d' AND `char_id` = '%d'", char_db, p->base_level, p->job_level, p->base_exp, p->job_exp, p->zeny, @@ -508,7 +518,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) (unsigned long)p->delete_date, // FIXME: platform-dependent size p->look.robe,p->slotchange,opt,p->font,p->uniqueitem_counter, p->hotkey_rowshift,p->clan_id,p->last_login, p->attendance_count, p->attendance_timer, - p->title_id, + p->title_id, p->inventorySize, p->account_id, p->char_id) ) { Sql_ShowDebug(inter->sql_handle); @@ -1049,7 +1059,7 @@ static int char_mmo_gender(const struct char_session_data *sd, const struct mmo_ //===================================================================================================== // Loads the basic character rooster for the given account. Returns total buffer used. -static int char_mmo_chars_fromsql(struct char_session_data *sd, uint8 *buf) +static int char_mmo_chars_fromsql(struct char_session_data *sd, uint8 *buf, int *count) { struct SqlStmt *stmt; struct mmo_charstatus p; @@ -1058,6 +1068,9 @@ static int char_mmo_chars_fromsql(struct char_session_data *sd, uint8 *buf) time_t unban_time = 0; char sex[2]; + if (count) + *count = 0; + nullpo_ret(sd); nullpo_ret(buf); @@ -1079,7 +1092,7 @@ static int char_mmo_chars_fromsql(struct char_session_data *sd, uint8 *buf) "`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`," "`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`," "`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`," - "`robe`,`slotchange`,`unban_time`,`sex`,`title_id`" + "`robe`,`slotchange`,`unban_time`,`sex`,`title_id`,`inventory_size`" " FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS) || SQL_ERROR == SQL->StmtExecute(stmt) || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &p.char_id, sizeof p.char_id, NULL, NULL) @@ -1123,25 +1136,36 @@ static int char_mmo_chars_fromsql(struct char_session_data *sd, uint8 *buf) || SQL_ERROR == SQL->StmtBindColumn(stmt, 38, SQLDT_TIME, &unban_time, sizeof unban_time, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 39, SQLDT_ENUM, &sex, sizeof sex, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 40, SQLDT_INT, &p.title_id, sizeof p.title_id, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 41, SQLDT_INT, &p.inventorySize, sizeof p.inventorySize, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return 0; } - for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->StmtNextRow(stmt); i++ ) { + int tmpCount = 0; + for (i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->StmtNextRow(stmt); i++) { if (p.slot >= MAX_CHARS) continue; + if (p.inventorySize <= 0 || p.inventorySize > MAX_INVENTORY) { + ShowError("Wrong inventorySize field: %d. Must be in range 1 to %d. Character %s (CID: %d, AID: %d)\n", + p.inventorySize, MAX_INVENTORY, p.name, p.char_id, p.account_id); + Assert_report(0); + p.inventorySize = FIXED_INVENTORY_SIZE; + } p.last_point.map = mapindex->name2id(last_map); sd->found_char[p.slot] = p.char_id; sd->unban_time[p.slot] = unban_time; p.sex = chr->mmo_gender(sd, &p, sex[0]); j += chr->mmo_char_tobuf(WBUFP(buf, j), &p); + tmpCount ++; } - memset(sd->new_name,0,sizeof(sd->new_name)); + memset(sd->new_name, 0, sizeof(sd->new_name)); SQL->StmtFree(stmt); + if (count) + *count = tmpCount; return j; } @@ -1169,6 +1193,7 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa nullpo_ret(p); memset(p, 0, sizeof(struct mmo_charstatus)); + p->inventorySize = FIXED_INVENTORY_SIZE; if (chr->show_save_log) ShowInfo("Char load request (%d)\n", char_id); @@ -1188,7 +1213,7 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa "`hair_color`,`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`," "`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`,`slotchange`," "`char_opt`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`, `attendance_count`, `attendance_timer`," - "`title_id`" + "`title_id`, `inventory_size`" " FROM `%s` WHERE `char_id`=? LIMIT 1", char_db) || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, sizeof char_id) || SQL_ERROR == SQL->StmtExecute(stmt) @@ -1256,6 +1281,7 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa || SQL_ERROR == SQL->StmtBindColumn(stmt, 61, SQLDT_SHORT, &p->attendance_count, sizeof p->attendance_count, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 62, SQLDT_INT64, &p->attendance_timer, sizeof p->attendance_timer, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 63, SQLDT_INT, &p->title_id, sizeof p->title_id, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 64, SQLDT_INT, &p->inventorySize, sizeof p->inventorySize, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); @@ -1287,6 +1313,13 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa p->save_point.y = mapindex->default_y; } + if (p->inventorySize <= 0 || p->inventorySize > MAX_INVENTORY) { + ShowError("Wrong inventorySize field: %d. Must be in range 1 to %d. Character %s (CID: %d, AID: %d)\n", + p->inventorySize, MAX_INVENTORY, p->name, p->char_id, p->account_id); + Assert_report(0); + p->inventorySize = FIXED_INVENTORY_SIZE; + } + strcat(t_msg, " status"); if (!load_everything) // For quick selection of data when displaying the char menu @@ -1514,6 +1547,14 @@ static int char_rename_char_sql(struct char_session_data *sd, int char_id) if( char_dat.rename == 0 ) return 1; + if (char_aegis_rename) { + if (char_dat.guild_id > 0) { + return 5; // MSG_FAILED_RENAME_BELONGS_TO_GUILD + } else if (char_dat.party_id > 0) { + return 6; // MSG_FAILED_RENAME_BELONGS_TO_PARTY + } + } + SQL->EscapeStringLen(inter->sql_handle, esc_name, sd->new_name, strnlen(sd->new_name, NAME_LENGTH)); // check if the char exist @@ -1539,9 +1580,20 @@ static int char_rename_char_sql(struct char_session_data *sd, int char_id) // log change if (chr->enable_logs) { if (SQL_ERROR == SQL->Query(inter->sql_handle, - "INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)" - "VALUES (NOW(), '%s', '%d', '%d', '%d', '%s', '0', '0', '0', '0', '0', '0', '0', '0')", - charlog_db, "change char name", sd->account_id, char_dat.char_id, char_dat.slot, esc_name)) + "INSERT INTO `%s` (" + " `time`, `char_msg`, `account_id`, `char_id`, `char_num`, `class`, `name`," + " `str`, `agi`, `vit`, `int`, `dex`, `luk`," + " `hair`, `hair_color`" + ") VALUES (" + " NOW(), 'change char name', '%d', '%d', '%d', '%d', '%s'," + " '%d', '%d', '%d', '%d', '%d', '%d'," + " '%d', '%d'" + ")", + charlog_db, + sd->account_id, char_dat.char_id, char_dat.slot, char_dat.class, esc_name, + char_dat.str, char_dat.agi, char_dat.vit, char_dat.int_, char_dat.dex, char_dat.luk, + char_dat.hair, char_dat.hair_color + )) Sql_ShowDebug(inter->sql_handle); } @@ -1967,7 +2019,7 @@ static int char_count_users(void) // Writes char data to the buffer in the format used by the client. // Used in packets 0x6b (chars info) and 0x6d (new char info) // Returns the size -#define MAX_CHAR_BUF 150 //Max size (for WFIFOHEAD calls) +#define MAX_CHAR_BUF (PACKET_LEN_0x006d - 2) static int char_mmo_char_tobuf(uint8 *buffer, struct mmo_charstatus *p) { unsigned short offset = 0; @@ -2072,18 +2124,29 @@ static int char_mmo_char_tobuf(uint8 *buffer, struct mmo_charstatus *p) #endif #endif - return 106+offset; + if (106 + offset != MAX_CHAR_BUF) + Assert_report("Wrong buffer size in char_mmo_char_tobuf"); + return 106 + offset; } /* Made Possible by Yommy~! <3 */ -static void char_mmo_char_send099d(int fd, struct char_session_data *sd) -{ -// support added for client between 20121010 and 20130320 -#if PACKETVER > 20120418 - WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF)); - WFIFOW(fd,0) = 0x99d; - WFIFOW(fd,2) = chr->mmo_chars_fromsql(sd, WFIFOP(fd,4)) + 4; - WFIFOSET(fd,WFIFOW(fd,2)); +static void char_send_HC_ACK_CHARINFO_PER_PAGE(int fd, struct char_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20130522 || PACKETVER_RE_NUM >= 20130327 || defined(PACKETVER_ZERO) + WFIFOHEAD(fd, sizeof(struct PACKET_HC_ACK_CHARINFO_PER_PAGE) + (MAX_CHARS * MAX_CHAR_BUF)); + struct PACKET_HC_ACK_CHARINFO_PER_PAGE *p = WFIFOP(fd, 0); + int count = 0; + p->packetId = HEADER_HC_ACK_CHARINFO_PER_PAGE; + p->packetLen = chr->mmo_chars_fromsql(sd, WFIFOP(fd, 4), &count) + sizeof(struct PACKET_HC_ACK_CHARINFO_PER_PAGE); + WFIFOSET(fd, p->packetLen); + // send empty packet if chars count is 3*N, for trigger final code in client + if (count % 3 != 0) { + WFIFOHEAD(fd, sizeof(struct PACKET_HC_ACK_CHARINFO_PER_PAGE)); + p = WFIFOP(fd, 0); + p->packetId = HEADER_HC_ACK_CHARINFO_PER_PAGE; + p->packetLen = sizeof(struct PACKET_HC_ACK_CHARINFO_PER_PAGE); + WFIFOSET(fd, p->packetLen); + } #endif } @@ -2132,17 +2195,20 @@ static void char_mmo_char_send_ban_list(int fd, struct char_session_data *sd) //---------------------------------------- static void char_mmo_char_send_slots_info(int fd, struct char_session_data *sd) { +// also probably supported client 2013-02-15aRagexe but not 2013-02-15bRagexe [4144] +#if PACKETVER_MAIN_NUM >= 20130612 || PACKETVER_RE_NUM >= 20130115 || defined(PACKETVER_ZERO) nullpo_retv(sd); - WFIFOHEAD(fd,29); - WFIFOW(fd,0) = 0x82d; - WFIFOW(fd,2) = 29; - WFIFOB(fd,4) = sd->char_slots; - WFIFOB(fd,5) = MAX_CHARS - sd->char_slots; - WFIFOB(fd,6) = 0; - WFIFOB(fd,7) = sd->char_slots; - WFIFOB(fd,8) = sd->char_slots; - memset(WFIFOP(fd,9), 0, 20); // unused bytes - WFIFOSET(fd,29); + WFIFOHEAD(fd, 29); + WFIFOW(fd, 0) = 0x82d; + WFIFOW(fd, 2) = 29; + WFIFOB(fd, 4) = sd->char_slots; + WFIFOB(fd, 5) = MAX_CHARS - sd->char_slots; + WFIFOB(fd, 6) = 0; + WFIFOB(fd, 7) = sd->char_slots; + WFIFOB(fd, 8) = sd->char_slots; + memset(WFIFOP(fd, 9), 0, 20); // unused bytes + WFIFOSET(fd, 29); +#endif } //---------------------------------------- // Function to send characters to a player @@ -2166,7 +2232,7 @@ static int char_mmo_char_send_characters(int fd, struct char_session_data *sd) WFIFOB(fd,6) = MAX_CHARS; // Premium slots. AKA any existent chars past sd->char_slots but within MAX_CHARS will show a 'Premium Service' in red #endif memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes - j+=chr->mmo_chars_fromsql(sd, WFIFOP(fd,j)); + j += chr->mmo_chars_fromsql(sd, WFIFOP(fd, j), NULL); WFIFOW(fd,2) = j; // packet len WFIFOSET(fd,j); @@ -2409,12 +2475,8 @@ static void char_parse_fromlogin_account_data(int fd) chr->auth_error(i, 0); } else { // send characters to player - #if PACKETVER >= 20130000 chr->mmo_char_send_slots_info(i, sd); chr->mmo_char_send_characters(i, sd); - #else - chr->mmo_char_send_characters(i, sd); - #endif #if PACKETVER >= 20060819 chr->mmo_char_send_ban_list(i, sd); #endif @@ -4151,10 +4213,10 @@ static void char_delete2_accept_actual_ack(int fd, int char_id, uint32 result) /// Any (0x718): An unknown error has occurred. static void char_delete2_accept_ack(int fd, int char_id, uint32 result) {// HC: <082a>.W <char id>.L <Msg:0-5>.L -#if PACKETVER >= 20130000 /* not sure the exact date -- must refresh or client gets stuck */ +#if PACKETVER_MAIN_NUM >= 20130522 || PACKETVER_RE_NUM >= 20130327 || defined(PACKETVER_ZERO) if( result == 1 ) { struct char_session_data* sd = (struct char_session_data*)sockt->session[fd]->session_data; - chr->mmo_char_send099d(fd, sd); + chr->send_HC_ACK_CHARINFO_PER_PAGE(fd, sd); } #endif chr->delete2_accept_actual_ack(fd, char_id, result); @@ -4345,9 +4407,9 @@ static void char_delete2_cancel(int fd, struct char_session_data *sd) static void char_send_account_id(int fd, int account_id) { - WFIFOHEAD(fd,4); - WFIFOL(fd,0) = account_id; - WFIFOSET(fd,4); + WFIFOHEAD(fd, 4); + WFIFOL(fd, 0) = account_id; + WFIFOSET2(fd, 4); } static void char_parse_char_connect(int fd, struct char_session_data *sd, uint32 ipl) @@ -4558,8 +4620,19 @@ static void char_parse_char_select(int fd, struct char_session_data *sd, uint32 // FIXME: Why are we re-escaping the name if it was already escaped in rename/make_new_char? [Panikon] SQL->EscapeStringLen(inter->sql_handle, esc_name, char_dat.name, strnlen(char_dat.name, NAME_LENGTH)); if (SQL_ERROR == SQL->Query(inter->sql_handle, - "INSERT INTO `%s`(`time`, `account_id`, `char_id`, `char_num`, `name`) VALUES (NOW(), '%d', '%d', '%d', '%s')", - charlog_db, sd->account_id, cd->char_id, slot, esc_name)) + "INSERT INTO `%s`(" + " `time`, `char_msg`, `account_id`, `char_id`, `char_num`, `class`, `name`," + " `str`, `agi`, `vit`, `int`, `dex`, `luk`," + " `hair`, `hair_color`" + ") VALUES (" + " NOW(), 'char select', '%d', '%d', '%d', '%d', '%s'," + " '%d', '%d', '%d', '%d', '%d', '%d'," + " '%d', '%d')", + charlog_db, + sd->account_id, cd->char_id, slot, char_dat.class, esc_name, + char_dat.str, char_dat.agi, char_dat.vit, char_dat.int_, char_dat.dex, char_dat.luk, + char_dat.hair, char_dat.hair_color + )) Sql_ShowDebug(inter->sql_handle); } ShowInfo("Selected char: (Account %d: %d - %s)\n", sd->account_id, slot, char_dat.name); @@ -4900,10 +4973,10 @@ static void char_parse_char_delete2_cancel(int fd, struct char_session_data *sd) // 3 - error static void char_login_map_server_ack(int fd, uint8 flag) { - WFIFOHEAD(fd,3); - WFIFOW(fd,0) = 0x2af9; - WFIFOB(fd,2) = flag; - WFIFOSET(fd,3); + WFIFOHEAD(fd, 3); + WFIFOW(fd, 0) = 0x2af9; + WFIFOB(fd, 2) = flag; + WFIFOSET2(fd, 3); } static void char_parse_char_login_map_server(int fd, uint32 ipl) @@ -4930,6 +5003,7 @@ static void char_parse_char_login_map_server(int fd, uint32 ipl) chr->server[i].users = 0; sockt->session[fd]->func_parse = chr->parse_frommap; sockt->session[fd]->flag.server = 1; + sockt->session[fd]->flag.validate = 0; sockt->realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); chr->mapif_init(fd); } @@ -4975,7 +5049,7 @@ static void char_parse_char_pincode_first_pin(int fd, struct char_session_data * static void char_parse_char_request_chars(int fd, struct char_session_data *sd) { - chr->mmo_char_send099d(fd, sd); + chr->send_HC_ACK_CHARINFO_PER_PAGE(fd, sd); RFIFOSKIP(fd,2); } @@ -4995,8 +5069,8 @@ static void char_parse_char_move_character(int fd, struct char_session_data *sd) chr->change_character_slot_ack(fd, ret); /* for some stupid reason it requires the char data again (gravity -_-) */ if( ret ) -#if PACKETVER >= 20130000 - chr->mmo_char_send099d(fd, sd); +#if PACKETVER_MAIN_NUM >= 20130522 || PACKETVER_RE_NUM >= 20130327 || defined(PACKETVER_ZERO) + chr->send_HC_ACK_CHARINFO_PER_PAGE(fd, sd); #else chr->mmo_char_send_characters(fd, sd); #endif @@ -5299,6 +5373,7 @@ static int char_check_connect_login_server(int tid, int64 tick, int id, intptr_t sockt->session[chr->login_fd]->func_parse = chr->parse_fromlogin; sockt->session[chr->login_fd]->flag.server = 1; + sockt->session[chr->login_fd]->flag.validate = 0; sockt->realloc_fifo(chr->login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); loginif->connect_to_server(); @@ -5848,6 +5923,7 @@ static bool char_config_read_player_name(const char *filename, const struct conf libconfig->setting_lookup_mutable_string(setting, "name_letters", char_name_letters, sizeof(char_name_letters)); libconfig->setting_lookup_int(setting, "name_option", &char_name_option); libconfig->setting_lookup_bool_real(setting, "name_ignoring_case", &name_ignoring_case); + libconfig->setting_lookup_bool_real(setting, "use_aegis_rename", &char_aegis_rename); return true; } @@ -6290,6 +6366,7 @@ int do_init(int argc, char **argv) Sql_ShowDebug(inter->sql_handle); sockt->set_defaultparse(chr->parse_char); + sockt->validate = true; if ((chr->char_fd = sockt->make_listen_bind(bind_ip,chr->port)) == -1) { ShowFatalError("Failed to bind to port '"CL_WHITE"%d"CL_RESET"'\n",chr->port); @@ -6390,7 +6467,7 @@ void char_defaults(void) chr->divorce_char_sql = char_divorce_char_sql; chr->count_users = char_count_users; chr->mmo_char_tobuf = char_mmo_char_tobuf; - chr->mmo_char_send099d = char_mmo_char_send099d; + chr->send_HC_ACK_CHARINFO_PER_PAGE = char_send_HC_ACK_CHARINFO_PER_PAGE; chr->mmo_char_send_ban_list = char_mmo_char_send_ban_list; chr->mmo_char_send_slots_info = char_mmo_char_send_slots_info; chr->mmo_char_send_characters = char_mmo_char_send_characters; diff --git a/src/char/char.h b/src/char/char.h index 81cab1eaf..914530537 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -142,7 +142,7 @@ struct char_interface { int (*getitemdata_from_sql) (struct item *items, int max, int guid, enum inventory_table_type table); int (*memitemdata_to_sql) (const struct item items[], int id, enum inventory_table_type table); int (*mmo_gender) (const struct char_session_data *sd, const struct mmo_charstatus *p, char sex); - int (*mmo_chars_fromsql) (struct char_session_data* sd, uint8* buf); + int (*mmo_chars_fromsql) (struct char_session_data* sd, uint8* buf, int *count); int (*mmo_char_fromsql) (int char_id, struct mmo_charstatus* p, bool load_everything); int (*mmo_char_sql_init) (void); bool (*char_slotchange) (struct char_session_data *sd, int fd, unsigned short from, unsigned short to); @@ -153,7 +153,7 @@ struct char_interface { int (*divorce_char_sql) (int partner_id1, int partner_id2); int (*count_users) (void); int (*mmo_char_tobuf) (uint8* buffer, struct mmo_charstatus* p); - void (*mmo_char_send099d) (int fd, struct char_session_data *sd); + void (*send_HC_ACK_CHARINFO_PER_PAGE) (int fd, struct char_session_data *sd); void (*mmo_char_send_ban_list) (int fd, struct char_session_data *sd); void (*mmo_char_send_slots_info) (int fd, struct char_session_data* sd); int (*mmo_char_send_characters) (int fd, struct char_session_data* sd); diff --git a/src/char/packets_hc_struct.h b/src/char/packets_hc_struct.h new file mode 100644 index 000000000..196493cac --- /dev/null +++ b/src/char/packets_hc_struct.h @@ -0,0 +1,45 @@ +/** + * This file is part of Hercules. + * http://herc.ws - http://github.com/HerculesWS/Hercules + * + * Copyright (C) 2016-2018 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/>. + */ +#ifndef CHAR_PACKETS_HC_STRUCT_H +#define CHAR_PACKETS_HC_STRUCT_H + +#include "common/hercules.h" +#include "common/mmo.h" +#include "common/packetsstatic_len.h" + +/* Packets Structs */ +#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 + +#if PACKETVER_MAIN_NUM >= 20130522 || PACKETVER_RE_NUM >= 20130327 || defined(PACKETVER_ZERO) +struct PACKET_HC_ACK_CHARINFO_PER_PAGE { + int16 packetId; + int16 packetLen; + // chars list[] +} __attribute__((packed)); +DEFINE_PACKET_HEADER(HC_ACK_CHARINFO_PER_PAGE, 0x099d); +#endif + +#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 + +#endif // CHAR_PACKETS_HC_STRUCT_H |