From 14cb61d598f3516ba1d88ecc12b9f29b5f130df2 Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Wed, 11 Jan 2023 16:54:53 +0100 Subject: [PATCH] Removed mapindex from char-server (#7533) Converted last_point to mapname Converted save_point to mapname Converted memo to mapname Converted start point to mapname Removed default map Converted party member to mapname Converted maplists to mapname Removed mapindex loading Fixed instance loading with multiple map-servers Fixed castle loading with multiple map-servers Fixed battleground loading with multiple map-servers Fixed warping between map-servers Thanks to @aleos89 for his help! --- src/char/char.cpp | 101 ++++++++++++--------------------------- src/char/char.hpp | 10 ++-- src/char/char_clif.cpp | 58 +++++++++++----------- src/char/char_logif.cpp | 2 +- src/char/char_mapif.cpp | 88 ++++++++++++++++++---------------- src/char/int_party.cpp | 32 +++++++------ src/char/inter.cpp | 2 +- src/common/mmo.hpp | 11 ++++- src/map/atcommand.cpp | 16 +++---- src/map/battleground.cpp | 7 ++- src/map/chrif.cpp | 75 +++++++++++------------------ src/map/clif.cpp | 27 ++++++----- src/map/clif.hpp | 4 +- src/map/guild.cpp | 16 +++---- src/map/instance.cpp | 13 +++-- src/map/intif.cpp | 14 +++--- src/map/map.cpp | 26 +--------- src/map/map.hpp | 7 --- src/map/party.cpp | 19 ++++---- src/map/party.hpp | 2 +- src/map/pc.cpp | 77 ++++++++++++++++++++--------- src/map/pc.hpp | 1 + src/map/script.cpp | 20 ++++---- src/map/skill.cpp | 18 +++---- src/map/status.cpp | 2 +- 25 files changed, 311 insertions(+), 337 deletions(-) diff --git a/src/char/char.cpp b/src/char/char.cpp index 557bce631f..faabae4098 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -277,8 +277,10 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){ (p->base_exp != cp->base_exp) || (p->base_level != cp->base_level) || (p->job_level != cp->job_level) || (p->job_exp != cp->job_exp) || (p->zeny != cp->zeny) || - (p->last_point.map != cp->last_point.map) || + ( strncmp( p->last_point.map, cp->last_point.map, sizeof( p->last_point.map ) ) != 0 ) || (p->last_point.x != cp->last_point.x) || (p->last_point.y != cp->last_point.y) || + ( strncmp( p->save_point.map, cp->save_point.map, sizeof( p->save_point.map ) ) != 0 ) || + ( p->save_point.x != cp->save_point.x ) || ( p->save_point.y != cp->save_point.y ) || (p->max_hp != cp->max_hp) || (p->hp != cp->hp) || (p->max_sp != cp->max_sp) || (p->sp != cp->sp) || (p->status_point != cp->status_point) || (p->skill_point != cp->skill_point) || @@ -316,8 +318,8 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){ p->str, p->agi, p->vit, p->int_, p->dex, p->luk, p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id, p->ele_id, p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom, - mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y, - mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename, + p->last_point.map, p->last_point.x, p->last_point.y, + p->save_point.map, p->save_point.x, p->save_point.y, p->rename, (unsigned long)p->delete_date, // FIXME: platform-dependent size p->robe, p->character_moves, p->font, p->uniqueitem_counter, p->hotkey_rowshift, p->clan_id, p->title_id, p->show_equip, p->hotkey_rowshift2, @@ -390,11 +392,10 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){ StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", schema_config.memo_db); for( i = 0, count = 0; i < MAX_MEMOPOINTS; ++i ) { - if( p->memo_point[i].map ) - { + if( strcmp( "", p->memo_point[i].map ) != 0 ){ if( count ) StringBuf_AppendStr(&buf, ","); - Sql_EscapeString(sql_handle, esc_mapname, mapindex_id2name(p->memo_point[i].map)); + Sql_EscapeString( sql_handle, esc_mapname, p->memo_point[i].map ); StringBuf_Printf(&buf, "('%d', '%s', '%d', '%d')", char_id, esc_mapname, p->memo_point[i].x, p->memo_point[i].y); ++count; } @@ -910,7 +911,6 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun SqlStmt* stmt; struct mmo_charstatus p; int j = 0, i; - char last_map[MAP_NAME_LENGTH_EXT]; char sex[2]; stmt = SqlStmt_Malloc(sql_handle); @@ -970,7 +970,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun || SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p.head_top, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_STRING, &p.last_point.map, sizeof(p.last_point.map), NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p.rename, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p.robe, 0, NULL, NULL) @@ -1004,7 +1004,6 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SqlStmt_NextRow(stmt); i++ ) { - p.last_point.map = mapindex_name2id(last_map); sd->found_char[p.slot] = p.char_id; sd->unban_time[p.slot] = p.unban_time; p.sex = char_mmo_gender(sd, &p, sex[0]); @@ -1029,10 +1028,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything) { int i; SqlStmt* stmt; - char last_map[MAP_NAME_LENGTH_EXT]; - char save_map[MAP_NAME_LENGTH_EXT]; - char point_map[MAP_NAME_LENGTH_EXT]; - struct point tmp_point; + struct s_point_str tmp_point; struct s_skill tmp_skill; uint16 skill_count = 0; struct s_friend tmp_friend; @@ -1106,10 +1102,10 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev || SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_top, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_STRING, &p->last_point.map, sizeof(p->last_point.map), NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_STRING, &p->save_point.map, sizeof(p->save_point.map), NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_UINT32, &p->partner_id, 0, NULL, NULL) @@ -1155,20 +1151,6 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev return 0; } p->sex = char_mmo_gender(NULL, p, sex[0]); - p->last_point.map = mapindex_name2id(last_map); - p->save_point.map = mapindex_name2id(save_map); - - if( p->last_point.map == 0 ) { - p->last_point.map = mapindex_name2id(charserv_config.default_map); - p->last_point.x = charserv_config.default_map_x; - p->last_point.y = charserv_config.default_map_y; - } - - if( p->save_point.map == 0 ) { - p->save_point.map = mapindex_name2id(charserv_config.default_map); - p->save_point.x = charserv_config.default_map_x; - p->save_point.y = charserv_config.default_map_y; - } StringBuf_Init(&msg_buf); StringBuf_AppendStr(&msg_buf, " status"); @@ -1185,14 +1167,13 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`=? ORDER by `memo_id` LIMIT %d", schema_config.memo_db, MAX_MEMOPOINTS) || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SqlStmt_Execute(stmt) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &point_map, sizeof(point_map), NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &tmp_point.map, sizeof(tmp_point.map), NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_point.x, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_point.y, 0, NULL, NULL) ) SqlStmt_ShowDebug(stmt); for( i = 0; i < MAX_MEMOPOINTS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) { - tmp_point.map = mapindex_name2id(point_map); memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point)); } StringBuf_AppendStr(&msg_buf, " memo"); @@ -1426,7 +1407,7 @@ int char_check_char_name(char * name, char * esc_name) int char_make_new_char( struct char_session_data* sd, char* name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short start_job, int sex ){ char name[NAME_LENGTH]; char esc_name[NAME_LENGTH*2+1]; - struct point tmp_start_point[MAX_STARTPOINT]; + struct s_point_str tmp_start_point[MAX_STARTPOINT]; struct startitem tmp_start_items[MAX_STARTITEM]; uint32 char_id; int flag, k, start_point_idx = rnd() % charserv_config.start_point_count; @@ -1436,9 +1417,9 @@ int char_make_new_char( struct char_session_data* sd, char* name_, int str, int normalize_name(name,TRIM_CHARS); Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); - memset(tmp_start_point, 0, MAX_STARTPOINT * sizeof(struct point)); + memset( tmp_start_point, 0, sizeof( tmp_start_point ) ); memset(tmp_start_items, 0, MAX_STARTITEM * sizeof(struct startitem)); - memcpy(tmp_start_point, charserv_config.start_point, MAX_STARTPOINT * sizeof(struct point)); + memcpy( tmp_start_point, charserv_config.start_point, sizeof( tmp_start_point ) ); memcpy(tmp_start_items, charserv_config.start_items, MAX_STARTITEM * sizeof(struct startitem)); flag = char_check_char_name(name,esc_name); @@ -1524,9 +1505,9 @@ int char_make_new_char( struct char_session_data* sd, char* name_, int str, int // Check for Doram based information. if (start_job == JOB_SUMMONER) { // Check for just this job for now. - memset(tmp_start_point, 0, MAX_STARTPOINT * sizeof(struct point)); + memset( tmp_start_point, 0, sizeof( tmp_start_point ) ); memset(tmp_start_items, 0, MAX_STARTITEM * sizeof(struct startitem)); - memcpy(tmp_start_point, charserv_config.start_point_doram, MAX_STARTPOINT * sizeof(struct point)); + memcpy( tmp_start_point, charserv_config.start_point_doram, sizeof( tmp_start_point ) ); memcpy(tmp_start_items, charserv_config.start_items_doram, MAX_STARTITEM * sizeof(struct startitem)); start_point_idx = rnd() % charserv_config.start_point_count_doram; } @@ -1538,7 +1519,7 @@ int char_make_new_char( struct char_session_data* sd, char* name_, int str, int "'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%u', '%u', '%u', '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%c')", schema_config.char_db, sd->account_id , slot, esc_name, start_job, charserv_config.start_zeny, status_points, str, agi, vit, int_, dex, luk, (40 * (100 + vit)/100) , (40 * (100 + vit)/100 ), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color, - mapindex_id2name(tmp_start_point[start_point_idx].map), tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, mapindex_id2name(tmp_start_point[start_point_idx].map), tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, sex) ) + tmp_start_point[start_point_idx].map, tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, tmp_start_point[start_point_idx].map, tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, sex ) ) { Sql_ShowDebug(sql_handle); return -2; //No, stop the procedure! @@ -1863,7 +1844,7 @@ int char_mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p){ info->hairColor = (uint8)u16min( p->hair_color, UINT8_MAX ); info->bIsChangedCharName = ( p->rename > 0 ) ? 0 : 1; #if (PACKETVER >= 20100720 && PACKETVER <= 20100727) || PACKETVER >= 20100803 - mapindex_getmapname_ext( mapindex_id2name( p->last_point.map ), info->mapName ); + mapindex_getmapname_ext( p->last_point.map, info->mapName ); #endif #if PACKETVER >= 20100803 #if PACKETVER_CHAR_DELETEDATE @@ -2114,16 +2095,18 @@ int char_loadName(uint32 char_id, char* name){ // Searches for the mapserver that has a given map (and optionally ip/port, if not -1). // If found, returns the server's index in the 'server' array (otherwise returns -1). -int char_search_mapserver(unsigned short map, uint32 ip, uint16 port){ +int char_search_mapserver( const std::string& map, uint32 ip, uint16 port ){ for(int i = 0; i < ARRAYLENGTH(map_server); i++) { if (session_isValid(map_server[i].fd) && (ip == (uint32)-1 || map_server[i].ip == ip) && (port == (uint16)-1 || map_server[i].port == port)) { - for (int j = 0; map_server[i].map[j]; j++) - if (map_server[i].map[j] == map) + for( std::string& m : map_server[i].maps ){ + if( m == map ){ return i; + } + } } } @@ -2774,13 +2757,13 @@ void char_set_defaults(){ charserv_config.char_check_db =1; // See const.hpp to change the default values - charserv_config.start_point[0].map = mapindex_name2id(MAP_DEFAULT_NAME); + safestrncpy( charserv_config.start_point[0].map, MAP_DEFAULT_NAME, sizeof( charserv_config.start_point[0].map ) ); charserv_config.start_point[0].x = MAP_DEFAULT_X; charserv_config.start_point[0].y = MAP_DEFAULT_Y; charserv_config.start_point_count = 1; #if PACKETVER >= 20151001 - charserv_config.start_point_doram[0].map = mapindex_name2id(MAP_DEFAULT_NAME); + safestrncpy( charserv_config.start_point_doram[0].map, MAP_DEFAULT_NAME, sizeof( charserv_config.start_point_doram[0].map ) ); charserv_config.start_point_doram[0].x = MAP_DEFAULT_X; charserv_config.start_point_doram[0].y = MAP_DEFAULT_Y; charserv_config.start_point_count_doram = 1; @@ -2811,10 +2794,6 @@ void char_set_defaults(){ charserv_config.start_zeny = 0; charserv_config.guild_exp_rate = 100; - safestrncpy(charserv_config.default_map, "prontera", MAP_NAME_LENGTH); - charserv_config.default_map_x = 156; - charserv_config.default_map_y = 191; - charserv_config.clan_remove_inactive_days = 14; charserv_config.mail_return_days = 14; charserv_config.mail_delete_days = 14; @@ -2836,8 +2815,7 @@ void char_set_defaults(){ * @param start: Start point reference * @param count: Start point count reference */ -void char_config_split_startpoint(char *w1_value, char *w2_value, struct point start_point[MAX_STARTPOINT], short *count) -{ +void char_config_split_startpoint( char* w1_value, char* w2_value, struct s_point_str start_point[MAX_STARTPOINT], short* count ){ char *lineitem, **fields; int i = 0, fields_length = 3 + 1; @@ -2857,16 +2835,9 @@ void char_config_split_startpoint(char *w1_value, char *w2_value, struct point s continue; } - start_point[i].map = mapindex_name2id(fields[1]); - if (!start_point[i].map) { - ShowError("Start point %s not found in map-index cache. Setting to default location.\n", fields[1]); - start_point[i].map = mapindex_name2id(MAP_DEFAULT_NAME); - start_point[i].x = MAP_DEFAULT_X; - start_point[i].y = MAP_DEFAULT_Y; - } else { - start_point[i].x = max(0, atoi(fields[2])); - start_point[i].y = max(0, atoi(fields[3])); - } + safestrncpy( start_point[i].map, fields[1], sizeof( start_point[i].map ) ); + start_point[i].x = max( 0, atoi( fields[2] ) ); + start_point[i].y = max( 0, atoi( fields[3] ) ); (*count)++; lineitem = strtok(NULL, ":"); //next lineitem @@ -3098,12 +3069,6 @@ bool char_config_read(const char* cfgName, bool normal){ charserv_config.charmove_config.char_moves_unlimited = config_switch(w2); } else if (strcmpi(w1, "char_checkdb") == 0) { charserv_config.char_check_db = config_switch(w2); - } else if (strcmpi(w1, "default_map") == 0) { - safestrncpy(charserv_config.default_map, w2, MAP_NAME_LENGTH); - } else if (strcmpi(w1, "default_map_x") == 0) { - charserv_config.default_map_x = atoi(w2); - } else if (strcmpi(w1, "default_map_y") == 0) { - charserv_config.default_map_y = atoi(w2); } else if (strcmpi(w1, "clan_remove_inactive_days") == 0) { charserv_config.clan_remove_inactive_days = atoi(w2); } else if (strcmpi(w1, "mail_return_days") == 0) { @@ -3176,7 +3141,6 @@ void CharacterServer::finalize(){ } Sql_Free(sql_handle); - mapindex_final(); ShowStatus("Finished.\n"); } @@ -3191,9 +3155,6 @@ void CharacterServer::handle_shutdown(){ } bool CharacterServer::initialize( int argc, char *argv[] ){ - //Read map indexes - mapindex_init(); - // Init default value CHAR_CONF_NAME = "conf/char_athena.conf"; LAN_CONF_NAME = "conf/subnet_athena.conf"; @@ -3295,8 +3256,6 @@ bool CharacterServer::initialize( int argc, char *argv[] ){ } do_init_chcnslif(); - mapindex_check_mapdefault(charserv_config.default_map); - ShowInfo("Default map: '" CL_WHITE "%s %d,%d" CL_RESET "'\n", charserv_config.default_map, charserv_config.default_map_x, charserv_config.default_map_y); ShowStatus("The char-server is " CL_GREEN "ready" CL_RESET " (Server is listening on the port %d).\n\n", charserv_config.char_port); diff --git a/src/char/char.hpp b/src/char/char.hpp index b9febad347..75a6d61356 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -186,7 +186,7 @@ struct CharServ_Config { int log_inter; // loggin inter or not [devil] int char_check_db; ///cheking sql-table at begining ? - struct point start_point[MAX_STARTPOINT], start_point_doram[MAX_STARTPOINT]; // Initial position the player will spawn on the server + struct s_point_str start_point[MAX_STARTPOINT], start_point_doram[MAX_STARTPOINT]; // Initial position the player will spawn on the server short start_point_count, start_point_count_doram; // Number of positions read struct startitem start_items[MAX_STARTITEM], start_items_doram[MAX_STARTITEM]; // Initial items the player with spawn with on the server uint32 start_status_points; @@ -197,10 +197,6 @@ struct CharServ_Config { int start_zeny; int guild_exp_rate; - char default_map[MAP_NAME_LENGTH]; - unsigned short default_map_x; - unsigned short default_map_y; - int clan_remove_inactive_days; int mail_return_days; int mail_delete_days; @@ -218,7 +214,7 @@ struct mmo_map_server { uint32 ip; uint16 port; int users; - std::vector map; + std::vector maps; }; extern struct mmo_map_server map_server[MAX_MAP_SERVERS]; @@ -292,7 +288,7 @@ extern struct fame_list taekwon_fame_list[MAX_FAME_LIST]; #define DEFAULT_AUTOSAVE_INTERVAL 300*1000 #define MAX_CHAR_BUF sizeof( struct CHARACTER_INFO ) //Max size (for WFIFOHEAD calls) -int char_search_mapserver(unsigned short map, uint32 ip, uint16 port); +int char_search_mapserver( const std::string& map, uint32 ip, uint16 port ); int char_lan_subnetcheck(uint32 ip); int char_count_users(void); diff --git a/src/char/char_clif.cpp b/src/char/char_clif.cpp index 552ee7e113..d226400a6f 100644 --- a/src/char/char_clif.cpp +++ b/src/char/char_clif.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -29,6 +30,15 @@ using namespace rathena; +std::vector accessible_maps{ + s_point_str{ MAP_PRONTERA, 273, 354 }, + s_point_str{ MAP_GEFFEN, 120, 100 }, + s_point_str{ MAP_MORROC, 160, 94 }, + s_point_str{ MAP_ALBERTA, 116, 57 }, + s_point_str{ MAP_PAYON, 87, 117 }, + s_point_str{ MAP_IZLUDE, 94, 103 } +}; + #if PACKETVER_SUPPORTS_PINCODE bool pincode_allowed( char* pincode ); #endif @@ -693,7 +703,7 @@ int chclif_parse_maplogin(int fd){ map_server[i].ip = ntohl(RFIFOL(fd,54)); map_server[i].port = ntohs(RFIFOW(fd,58)); map_server[i].users = 0; - map_server[i].map = {}; + map_server[i].maps = {}; session[fd]->func_parse = chmapif_parse; session[fd]->flag.server = 1; realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); @@ -796,7 +806,7 @@ void chclif_send_map_data( int fd, std::shared_ptr cd, ui WFIFOHEAD(fd,size); WFIFOW(fd,0) = cmd; WFIFOL(fd,2) = cd->char_id; - mapindex_getmapname_ext(mapindex_id2name(cd->last_point.map), WFIFOCP(fd,6)); + mapindex_getmapname_ext( cd->last_point.map, WFIFOCP( fd, 6 ) ); uint32 subnet_map_ip = char_lan_subnetcheck(ipl); // Advanced subnet check [LuzZza] WFIFOL(fd,22) = htonl((subnet_map_ip) ? subnet_map_ip : map_server[map_server_index].ip); WFIFOW(fd,26) = ntows(htons(map_server[map_server_index].port)); // [!] LE byte order here [!] @@ -817,7 +827,7 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){ int slot = RFIFOB(fd,2); RFIFOSKIP(fd,3); - ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, session_isValid(map_server[server_id].fd) && !map_server[server_id].map.empty() ); + ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, session_isValid(map_server[server_id].fd) && !map_server[server_id].maps.empty() ); // Map-server not available, tell the client to wait (client wont close, char select will respawn) if (server_id == ARRAYLENGTH(map_server)) { WFIFOHEAD(fd, 24); @@ -877,43 +887,35 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){ ShowInfo("Selected char: (Account %d: %d - %s)\n", sd->account_id, slot, char_dat.name); // searching map server - i = char_search_mapserver(cd->last_point.map, -1, -1); + i = char_search_mapserver( cd->last_point.map, -1, -1 ); // if map is not found, we check major cities - if (i < 0 || !cd->last_point.map) { + if( i < 0 ){ unsigned short j; //First check that there's actually a map server online. - ARR_FIND( 0, ARRAYLENGTH(map_server), j, session_isValid(map_server[j].fd) && !map_server[j].map.empty() ); + ARR_FIND( 0, ARRAYLENGTH(map_server), j, session_isValid(map_server[j].fd) && !map_server[j].maps.empty() ); if (j == ARRAYLENGTH(map_server)) { ShowInfo("Connection Closed. No map servers available.\n"); chclif_send_auth_result(fd,1); // 01 = Server closed return 1; } - if ((i = char_search_mapserver((j=mapindex_name2id(MAP_PRONTERA)),-1,-1)) >= 0) { - cd->last_point.x = 273; - cd->last_point.y = 354; - } else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_GEFFEN)),-1,-1)) >= 0) { - cd->last_point.x = 120; - cd->last_point.y = 100; - } else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_MORROC)),-1,-1)) >= 0) { - cd->last_point.x = 160; - cd->last_point.y = 94; - } else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_ALBERTA)),-1,-1)) >= 0) { - cd->last_point.x = 116; - cd->last_point.y = 57; - } else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_PAYON)),-1,-1)) >= 0) { - cd->last_point.x = 87; - cd->last_point.y = 117; - } else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_IZLUDE)),-1,-1)) >= 0) { - cd->last_point.x = 94; - cd->last_point.y = 103; - } else { - ShowInfo("Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", mapindex_id2name(cd->last_point.map)); + + for( struct s_point_str& accessible_map : accessible_maps ){ + i = char_search_mapserver( accessible_map.map, -1, -1 ); + + // Found a map-server for a map + if( i >= 0 ){ + ShowWarning( "Unable to find map-server for '%s', sending to major city '%s'.\n", cd->last_point.map, accessible_map.map ); + memcpy( &cd->last_point, &accessible_map, sizeof( cd->last_point ) ); + break; + } + } + + if( i < 0 ){ + ShowInfo( "Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", cd->last_point.map ); chclif_send_auth_result(fd,1); // 01 = Server closed return 1; } - ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(cd->last_point.map), mapindex_id2name(j)); - cd->last_point.map = j; } //Send NEW auth packet [Kevin] diff --git a/src/char/char_logif.cpp b/src/char/char_logif.cpp index 5fb9bf0321..2af0ccd1d0 100644 --- a/src/char/char_logif.cpp +++ b/src/char/char_logif.cpp @@ -823,7 +823,7 @@ void chlogif_on_ready(void) chlogif_send_acc_tologin(INVALID_TIMER, gettick(), 0, 0); // if no map-server already connected, display a message... - ARR_FIND( 0, ARRAYLENGTH(map_server), i, session_isValid(map_server[i].fd) && !map_server[i].map.empty() ); + ARR_FIND( 0, ARRAYLENGTH(map_server), i, session_isValid(map_server[i].fd) && !map_server[i].maps.empty() ); if( i == ARRAYLENGTH(map_server) ) ShowStatus("Awaiting maps from map-server.\n"); } diff --git a/src/char/char_mapif.cpp b/src/char/char_mapif.cpp index a4fe7109eb..b83d4a0fd0 100644 --- a/src/char/char_mapif.cpp +++ b/src/char/char_mapif.cpp @@ -167,25 +167,21 @@ void chmapif_sendall_playercount(int users){ * Send some misc info to new map-server. * - Server name for whisper name * - Default map - * HZ 0x2afb .W .B .24B .11B .W .W .24B + * HZ 0x2afb .W .B .24B .24B * @param fd **/ void chmapif_send_misc(int fd) { uint16 offs = 5; - unsigned char buf[45+NAME_LENGTH]; + unsigned char buf[5+NAME_LENGTH+NAME_LENGTH]; memset(buf, '\0', sizeof(buf)); WBUFW(buf, 0) = 0x2afb; // 0 succes, 1:failure WBUFB(buf, 4) = 0; // Send name for wisp to player - safestrncpy( WBUFCP( buf, 5 ), charserv_config.wisp_server_name, NAME_LENGTH ); - // Default map - safestrncpy( WBUFCP( buf, ( offs += NAME_LENGTH ) ), charserv_config.default_map, MAP_NAME_LENGTH ); // 29 - WBUFW(buf, (offs+=MAP_NAME_LENGTH)) = charserv_config.default_map_x; // 41 - WBUFW(buf, (offs+=2)) = charserv_config.default_map_y; // 43 - offs+=2; - safestrncpy( WBUFCP( buf, offs ), charserv_config.server_name, sizeof( charserv_config.server_name ) ); // 45 + safestrncpy( WBUFCP( buf, offs ), charserv_config.wisp_server_name, NAME_LENGTH ); + offs += NAME_LENGTH; + safestrncpy( WBUFCP( buf, offs ), charserv_config.server_name, sizeof( charserv_config.server_name ) ); offs += NAME_LENGTH; // Length @@ -207,29 +203,31 @@ void chmapif_send_maps(int fd, int map_id, int count, unsigned char *mapbuf) { ShowWarning("Map-server %d has NO maps.\n", map_id); } else { - unsigned char buf[16384]; + unsigned char buf[INT16_MAX]; // Transmitting maps information to the other map-servers WBUFW(buf,0) = 0x2b04; - WBUFW(buf,2) = count * 4 + 10; + WBUFW( buf, 2 ) = count * MAP_NAME_LENGTH_EXT + 10; WBUFL(buf,4) = htonl(map_server[map_id].ip); WBUFW(buf,8) = htons(map_server[map_id].port); - memcpy(WBUFP(buf,10), mapbuf, count * 4); + memcpy( WBUFP( buf, 10 ), mapbuf, count * MAP_NAME_LENGTH_EXT ); chmapif_sendallwos(fd, buf, WBUFW(buf,2)); } // Transmitting the maps of the other map-servers to the new map-server for (x = 0; x < ARRAYLENGTH(map_server); x++) { if (session_isValid(map_server[x].fd) && x != map_id) { - WFIFOHEAD(fd,10 +4*map_server[x].map.size()); + WFIFOHEAD( fd, 10 + MAP_NAME_LENGTH_EXT * map_server[x].maps.size() ); WFIFOW(fd,0) = 0x2b04; WFIFOL(fd,4) = htonl(map_server[x].ip); WFIFOW(fd,8) = htons(map_server[x].port); uint16 j = 0; - for(size_t i = 0; i < map_server[x].map.size(); i++) - if (map_server[x].map[i]) - WFIFOW(fd,10+(j++)*4) = map_server[x].map[i]; + for( std::string& map : map_server[x].maps ){ + safestrncpy( WFIFOCP( fd, 10 + j * MAP_NAME_LENGTH_EXT ), map.c_str(), MAP_NAME_LENGTH_EXT ); + j++; + } + if (j > 0) { - WFIFOW(fd,2) = j * 4 + 10; + WFIFOW( fd, 2 ) = j * MAP_NAME_LENGTH_EXT + 10; WFIFOSET(fd,WFIFOW(fd,2)); } } @@ -252,20 +250,26 @@ int chmapif_parse_getmapname(int fd, int id){ return 0; //Retain what map-index that map-serv contains - map_server[id].map = {}; - for(i = 4; i < RFIFOW(fd,2); i += 4) - map_server[id].map.push_back(RFIFOW(fd, i)); + map_server[id].maps.clear(); + + for( int i = 4; i < RFIFOW( fd, 2 ); i += MAP_NAME_LENGTH_EXT ){ + char mapname[MAP_NAME_LENGTH_EXT]; + + safestrncpy( mapname, RFIFOCP( fd, i ), sizeof( mapname ) ); + + map_server[id].maps.push_back( mapname ); + } mapbuf = RFIFOP(fd,4); RFIFOSKIP(fd,RFIFOW(fd,2)); ShowStatus("Map-Server %d connected: %" PRIuPTR " maps, from IP %d.%d.%d.%d port %d.\n", - id, map_server[id].map.size(), CONVIP(map_server[id].ip), map_server[id].port); + id, map_server[id].maps.size(), CONVIP(map_server[id].ip), map_server[id].port); ShowStatus("Map-server %d loading complete.\n", id); chmapif_send_misc(fd); chmapif_send_fame_list(fd); //Send fame list. - chmapif_send_maps(fd, id, map_server[id].map.size(), mapbuf); + chmapif_send_maps(fd, id, map_server[id].maps.size(), mapbuf); return 1; } @@ -589,12 +593,13 @@ int chmapif_parse_req_skillcooldown(int fd){ * @param nok : 0=accepted or no=1 */ void chmapif_changemapserv_ack(int fd, bool nok){ - WFIFOHEAD(fd,30); + // TODO: Refactor... You crazy *** [Lemongrass] + WFIFOHEAD( fd, 28 + MAP_NAME_LENGTH_EXT ); WFIFOW(fd,0) = 0x2b06; - memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28); + memcpy( WFIFOP( fd, 2 ), RFIFOP( fd, 2 ), 26 + MAP_NAME_LENGTH_EXT ); if(nok) WFIFOL(fd,6) = 0; //Set login1 to 0.(not ok) - WFIFOSET(fd,30); + WFIFOSET( fd, 28 + MAP_NAME_LENGTH_EXT ); } /** @@ -603,13 +608,15 @@ void chmapif_changemapserv_ack(int fd, bool nok){ * @return : 0 not enough data received, 1 success */ int chmapif_parse_reqchangemapserv(int fd){ - if (RFIFOREST(fd) < 39) + if( RFIFOREST( fd ) < ( 37 + MAP_NAME_LENGTH_EXT ) ){ return 0; + } else { int map_id, map_fd = -1; struct mmo_charstatus char_dat; + int offset = 18 + MAP_NAME_LENGTH_EXT; - map_id = char_search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port. + map_id = char_search_mapserver( RFIFOCP( fd, 18 ), ntohl( RFIFOL( fd, offset + 4 ) ), ntohs( RFIFOW( fd, offset + 8 ) ) ); //Locate mapserver by ip and port. if (map_id >= 0) map_fd = map_server[map_id].fd; @@ -631,10 +638,10 @@ int chmapif_parse_reqchangemapserv(int fd){ uint32 aid = RFIFOL( fd, 2 ); //Update the "last map" as this is where the player must be spawned on the new map server. - char_data->last_point.map = RFIFOW(fd,18); - char_data->last_point.x = RFIFOW(fd,20); - char_data->last_point.y = RFIFOW(fd,22); - char_data->sex = RFIFOB(fd,30); + safestrncpy( char_data->last_point.map, RFIFOCP( fd, 18 ), MAP_NAME_LENGTH_EXT ); + char_data->last_point.x = RFIFOW( fd, offset + 0 ); + char_data->last_point.y = RFIFOW( fd, offset + 2 ); + char_data->sex = RFIFOB( fd, offset + 10 ); // create temporary auth entry std::shared_ptr node = std::make_shared(); @@ -643,10 +650,10 @@ int chmapif_parse_reqchangemapserv(int fd){ node->char_id = char_id; node->login_id1 = RFIFOL(fd,6); node->login_id2 = RFIFOL(fd,10); - node->sex = RFIFOB(fd,30); + node->sex = char_data->sex; node->expiration_time = 0; // FIXME (this thing isn't really supported we could as well purge it instead of fixing) - node->ip = ntohl(RFIFOL(fd,31)); - node->group_id = RFIFOL(fd,35); + node->ip = ntohl( RFIFOL( fd, offset + 11 ) ); + node->group_id = RFIFOL( fd, offset + 15 ); node->changing_mapservers = 1; char_get_authdb()[node->account_id] = node; @@ -665,7 +672,7 @@ int chmapif_parse_reqchangemapserv(int fd){ } else { //Reply with nak chmapif_changemapserv_ack(fd,1); } - RFIFOSKIP(fd,39); + RFIFOSKIP( fd, 37 + MAP_NAME_LENGTH_EXT ); } return 1; } @@ -1503,18 +1510,19 @@ void do_init_chmapif(void){ */ void chmapif_server_reset(int id){ int j = 0; - unsigned char buf[16384]; + unsigned char buf[INT16_MAX]; int fd = map_server[id].fd; //Notify other map servers that this one is gone. [Skotlex] WBUFW(buf,0) = 0x2b20; WBUFL(buf,4) = htonl(map_server[id].ip); WBUFW(buf,8) = htons(map_server[id].port); - for(size_t i = 0; i < map_server[id].map.size(); i++) - if (map_server[id].map[i]) - WBUFW(buf,10+(j++)*4) = map_server[id].map[i]; + for( std::string& map : map_server[id].maps ){ + safestrncpy( WBUFCP( buf, 10 + j * MAP_NAME_LENGTH_EXT ), map.c_str(), MAP_NAME_LENGTH_EXT ); + j++; + } if (j > 0) { - WBUFW(buf,2) = j * 4 + 10; + WBUFW(buf,2) = j * MAP_NAME_LENGTH_EXT + 10; chmapif_sendallwos(fd, buf, WBUFW(buf,2)); } diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index 9d56baca5b..edf7d29707 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -11,7 +11,6 @@ #include "../common/cbasetypes.hpp" #include "../common/malloc.hpp" -#include "../common/mapindex.hpp" #include "../common/mmo.hpp" #include "../common/showmsg.hpp" #include "../common/socket.hpp" @@ -244,7 +243,7 @@ std::shared_ptr inter_party_fromsql( int party_id ){ Sql_GetData(sql_handle, 1, &data, NULL); m->char_id = atoi(data); Sql_GetData(sql_handle, 2, &data, &len); memcpy(m->name, data, zmin(len, NAME_LENGTH)); Sql_GetData(sql_handle, 3, &data, NULL); m->lv = atoi(data); - Sql_GetData(sql_handle, 4, &data, NULL); m->map = mapindex_name2id(data); + Sql_GetData(sql_handle, 4, &data, &len); memcpy(m->map, data, zmin(len, sizeof(m->map))); Sql_GetData(sql_handle, 5, &data, NULL); m->online = (atoi(data) ? 1 : 0); Sql_GetData(sql_handle, 6, &data, NULL); m->class_ = atoi(data); m->leader = (m->account_id == leader_id && m->char_id == leader_char ? 1 : 0); @@ -301,7 +300,7 @@ std::shared_ptr search_partyname( char* str ){ int party_check_family_share( std::shared_ptr p ){ int i; - unsigned short map = 0; + const char* map = nullptr; if (!p->family) return 0; for (i = 0; i < MAX_PARTY; i++) { @@ -311,6 +310,10 @@ int party_check_family_share( std::shared_ptr p ){ } } + if( map == nullptr ){ + return 0; + } + for (i = 0; i < MAX_PARTY; i++) { struct party_member * mem = &(p->party.member[i]); if (mem->lv == 0) @@ -322,7 +325,7 @@ int party_check_family_share( std::shared_ptr p ){ //everyone should be online to share return 0; } - if (mem->map != map) { + if( strncmp( mem->map, map, sizeof( mem->map ) ) != 0 ){ //everyone should be on the same map return 0; } @@ -455,16 +458,18 @@ int mapif_party_withdraw(int party_id, uint32 account_id, uint32 char_id, char * //Party map update notification int mapif_party_membermoved(struct party *p,int idx) { - unsigned char buf[20]; + unsigned char buf[17+MAP_NAME_LENGTH_EXT]; WBUFW(buf,0) = 0x3825; WBUFL(buf,2) = p->party_id; WBUFL(buf,6) = p->member[idx].account_id; WBUFL(buf,10) = p->member[idx].char_id; - WBUFW(buf,14) = p->member[idx].map; - WBUFB(buf,16) = p->member[idx].online; - WBUFW(buf,17) = p->member[idx].lv; - chmapif_sendall(buf, 19); + WBUFB(buf,14) = p->member[idx].online; + WBUFW(buf,15) = p->member[idx].lv; + safestrncpy( WBUFCP( buf, 17 ), p->member[idx].map, sizeof( p->member[idx].map ) ); + + chmapif_sendall( buf, sizeof( buf ) ); + return 0; } @@ -679,8 +684,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_ return 0; } // When member goes to other map or levels up. -int mapif_parse_PartyChangeMap(int fd, int party_id, uint32 account_id, uint32 char_id, unsigned short map, int online, unsigned int lv) -{ +int mapif_parse_PartyChangeMap( int fd, int party_id, uint32 account_id, uint32 char_id, int online, unsigned int lv, const char* map ){ int i; std::shared_ptr p = inter_party_fromsql( party_id ); @@ -729,8 +733,8 @@ int mapif_parse_PartyChangeMap(int fd, int party_id, uint32 account_id, uint32 c //since they do nothing with it. } - if (p->party.member[i].map != map) { - p->party.member[i].map = map; + if( strncmp( p->party.member[i].map, map, sizeof( p->party.member[i].map ) ) != 0 ){ + safestrncpy( p->party.member[i].map, map, sizeof( p->party.member[i].map ) ); mapif_party_membermoved(&p->party, i); int_party_check_lv(p); } @@ -814,7 +818,7 @@ int inter_party_parse_frommap(int fd) case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break; case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break; case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOCP(fd,14), (enum e_party_member_withdraw)RFIFOB(fd,14+NAME_LENGTH)); break; - case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOW(fd,14), RFIFOB(fd,16), RFIFOW(fd,17)); break; + case 0x3025: mapif_parse_PartyChangeMap( fd, RFIFOL( fd, 2 ), RFIFOL( fd, 6 ), RFIFOL( fd, 10 ), RFIFOB( fd, 14 ), RFIFOW( fd, 15 ), RFIFOCP( fd, 17 ) ); break; case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break; case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOCP(fd,12), RFIFOW(fd,2)-12); break; case 0x3029: mapif_parse_PartyLeaderChange(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break; diff --git a/src/char/inter.cpp b/src/char/inter.cpp index d321d36a2b..d980e22b56 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -58,7 +58,7 @@ unsigned int party_share_level = 10; int inter_recv_packet_length[] = { -1,-1, 7,-1, -1,13,36, (2+4+4+4+1+NAME_LENGTH), 0,-1, 0, 0, 0, 0, 0, 0, // 3000- 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- - -1,10,-1,14, 15+NAME_LENGTH,19, 6,-1, 14,14, 6, 0, 0, 0, 0, 0, // 3020- Party + -1,10,-1,14, 15+NAME_LENGTH,17+MAP_NAME_LENGTH_EXT, 6,-1, 14,14, 6, 0, 0, 0, 0, 0, // 3020- Party -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- -1, 9,10, 0, 0, 0, 0, 0, 8, 6,11,10, 10,-1,6+NAME_LENGTH, 0, // 3040- -1,-1,10,10, 0,-1,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus] diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp index 71de58e0d8..5262f4d6d0 100644 --- a/src/common/mmo.hpp +++ b/src/common/mmo.hpp @@ -363,6 +363,11 @@ struct point { uint16 x,y; }; +struct s_point_str{ + char map[MAP_NAME_LENGTH_EXT]; + uint16 x,y; +}; + struct startitem { t_itemid nameid; unsigned short amount; @@ -589,7 +594,9 @@ struct mmo_charstatus { uint32 mapip; uint16 mapport; - struct point last_point,save_point,memo_point[MAX_MEMOPOINTS]; + struct s_point_str last_point; + struct s_point_str save_point; + struct s_point_str memo_point[MAX_MEMOPOINTS]; struct s_skill skill[MAX_SKILL]; struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex] @@ -684,7 +691,7 @@ struct party_member { uint32 char_id; char name[NAME_LENGTH]; unsigned short class_; - unsigned short map; + char map[MAP_NAME_LENGTH_EXT]; unsigned short lv; unsigned leader : 1, online : 1; diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 9a3eeeebc8..1cd07c5f58 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -962,13 +962,13 @@ ACMD_FUNC(save) /*========================================== * *------------------------------------------*/ -ACMD_FUNC(load) -{ - int16 m; - +ACMD_FUNC(load){ nullpo_retr(-1, sd); - m = map_mapindex2mapid(sd->status.save_point.map); + uint16 mapindex = mapindex_name2id( sd->status.save_point.map ); + + int16 m = map_mapindex2mapid( mapindex ); + if (m >= 0 && map_getmapflag(m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,249)); // You are not authorized to warp to your save map. return -1; @@ -978,7 +978,7 @@ ACMD_FUNC(load) return -1; } - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT); + pc_setpos( sd, mapindex, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT ); clif_displaymessage(fd, msg_txt(sd,7)); // Warping to save point.. return 0; @@ -2580,8 +2580,8 @@ ACMD_FUNC(memo) clif_displaymessage(sd->fd, msg_txt(sd,668)); // Your actual memo positions are: for( i = 0; i < MAX_MEMOPOINTS; i++ ) { - if( sd->status.memo_point[i].map ) - sprintf(atcmd_output, "%d - %s (%d,%d)", i, mapindex_id2name(sd->status.memo_point[i].map), sd->status.memo_point[i].x, sd->status.memo_point[i].y); + if( strcmp( "", sd->status.memo_point[i].map ) != 0 ) + sprintf( atcmd_output, "%d - %s (%d,%d)", i, sd->status.memo_point[i].map, sd->status.memo_point[i].x, sd->status.memo_point[i].y ); else sprintf(atcmd_output, msg_txt(sd,171), i); // %d - void clif_displaymessage(sd->fd, atcmd_output); diff --git a/src/map/battleground.cpp b/src/map/battleground.cpp index 18dedf4488..5607b00de6 100644 --- a/src/map/battleground.cpp +++ b/src/map/battleground.cpp @@ -261,6 +261,11 @@ uint64 BattlegroundDatabase::parseBodyNode(const ryml::NodeRef& node) { this->invalidWarning(location["Map"], "Invalid battleground map name %s, skipping.\n", map_name.c_str()); return 0; } + + if( map_mapindex2mapid( map_entry.mapindex ) < 0 ){ + // Ignore silently, the map is on another mapserver + return 0; + } } if (this->nodeExists(location, "StartEvent")) { @@ -579,7 +584,7 @@ int bg_team_leave(map_session_data *sd, bool quit, bool deserter) if (member->entry_point.map != 0 && !map_getmapflag(map_mapindex2mapid(member->entry_point.map), MF_NOSAVE)) pc_setpos(sd, member->entry_point.map, member->entry_point.x, member->entry_point.y, CLR_TELEPORT); else - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); // Warp to save point if the entry map has no save flag. + pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); // Warp to save point if the entry map has no save flag. bgteam->members.erase(member); break; diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index a60643a6a5..7304c750f3 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -41,7 +41,7 @@ static bool char_init_done = false; //server already initialized? Used for Inter static const int packet_len_table[0x3d] = { // U - used, F - free 60, 3,-1,-1,10,-1, 6,-1, // 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff - 6,-1,18, 7,-1,39,30, 10, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07 + 6,-1,18, 7,-1, -1, 28 + MAP_NAME_LENGTH_EXT, 10, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07 6,30, 10, -1,86, 7,44,34, // 2b08-2b0f: U->2b08, U->2b09, U->2b0a, U->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f 11,10,10, 0,11, -1, 0,10, // 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, U->2b15, F->2b16, U->2b17 2,10, 2,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f @@ -53,7 +53,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free //2af8: Outgoing, chrif_connect -> 'connect to charserver / auth @ charserver' //2af9: Incoming, chrif_connectack -> 'answer of the 2af8 login(ok / fail)' //2afa: Outgoing, chrif_sendmap -> 'sending our maps' -//2afb: Incoming, chrif_sendmapack -> 'Maps received successfully / or not .. also received server name & default map' +//2afb: Incoming, chrif_sendmapack -> 'Maps received successfully / or not .. also received server name' //2afc: Outgoing, chrif_scdata_request -> request sc_data for pc_authok'ed char. <- new command reuses previous one. //2afd: Incoming, chrif_authok -> 'client authentication ok' //2afe: Outgoing, send_usercount_tochar -> 'sends player count of this map server to charserver' @@ -322,20 +322,8 @@ int chrif_save(map_session_data *sd, int flag) { WFIFOL(char_fd,8) = sd->status.char_id; WFIFOB(char_fd,12) = (flag&CSAVE_QUIT) ? 1 : 0; //Flag to tell char-server this character is quitting. - // If the user is on a instance map, we have to fake his current position - if( map_getmapdata(sd->bl.m)->instance_id ){ - struct mmo_charstatus status; - - // Copy the whole status - memcpy( &status, &sd->status, sizeof( struct mmo_charstatus ) ); - // Change his current position to his savepoint - memcpy( &status.last_point, &status.save_point, sizeof( struct point ) ); - // Copy the copied status into the packet - memcpy( WFIFOP( char_fd, 13 ), &status, sizeof( struct mmo_charstatus ) ); - } else { - // Copy the whole status into the packet - memcpy( WFIFOP( char_fd, 13 ), &sd->status, sizeof( struct mmo_charstatus ) ); - } + // Copy the whole status into the packet + memcpy( WFIFOP( char_fd, 13 ), &sd->status, sizeof( struct mmo_charstatus ) ); WFIFOSET(char_fd, WFIFOW(char_fd,2)); @@ -380,11 +368,11 @@ int chrif_sendmap(int fd) { ShowStatus("Sending maps to char server...\n"); // Sending normal maps, not instances - WFIFOHEAD(fd, 4 + instance_start * 4); + WFIFOHEAD( fd, 4 + instance_start * MAP_NAME_LENGTH_EXT ); WFIFOW(fd,0) = 0x2afa; for (int i = 0; i < instance_start; i++) - WFIFOW(fd, 4 + i * 4) = map[i].index; - WFIFOW(fd, 2) = 4 + instance_start * 4; + safestrncpy( WFIFOCP( fd, 4 + i * MAP_NAME_LENGTH_EXT ), map[i].name, MAP_NAME_LENGTH_EXT ); + WFIFOW( fd, 2 ) = 4 + instance_start * MAP_NAME_LENGTH_EXT; WFIFOSET(fd, WFIFOW(fd, 2)); return 0; @@ -396,8 +384,8 @@ int chrif_recvmap(int fd) { uint32 ip = ntohl(RFIFOL(fd,4)); uint16 port = ntohs(RFIFOW(fd,8)); - for(i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) { - map_setipport(RFIFOW(fd,i), ip, port); + for( i = 10, j = 0; i < RFIFOW( fd, 2 ); i += MAP_NAME_LENGTH_EXT, j++ ){ + map_setipport( mapindex_name2id( RFIFOCP( fd, i ) ), ip, port ); } if (battle_config.etc_log) @@ -414,8 +402,9 @@ int chrif_removemap(int fd) { uint32 ip = RFIFOL(fd,4); uint16 port = RFIFOW(fd,8); - for(i = 10, j = 0; i < RFIFOW(fd, 2); i += 4, j++) - map_eraseipport(RFIFOW(fd, i), ip, port); + for( i = 10, j = 0; i < RFIFOW( fd, 2 ); i += MAP_NAME_LENGTH_EXT, j++ ){ + map_eraseipport( mapindex_name2id( RFIFOCP( fd, i ) ), ip, port ); + } other_mapserver_count--; @@ -441,28 +430,29 @@ int chrif_changemapserver(map_session_data* sd, uint32 ip, uint16 port) { chrif_check(-1); - WFIFOHEAD(char_fd,39); + WFIFOHEAD( char_fd, 37 + MAP_NAME_LENGTH_EXT ); WFIFOW(char_fd, 0) = 0x2b05; WFIFOL(char_fd, 2) = sd->bl.id; WFIFOL(char_fd, 6) = sd->login_id1; WFIFOL(char_fd,10) = sd->login_id2; WFIFOL(char_fd,14) = sd->status.char_id; - WFIFOW(char_fd,18) = sd->mapindex; - WFIFOW(char_fd,20) = sd->bl.x; - WFIFOW(char_fd,22) = sd->bl.y; - WFIFOL(char_fd,24) = htonl(ip); - WFIFOW(char_fd,28) = htons(port); - WFIFOB(char_fd,30) = sd->status.sex; - WFIFOL(char_fd,31) = htonl(session[sd->fd]->client_addr); - WFIFOL(char_fd,35) = sd->group_id; - WFIFOSET(char_fd,39); + safestrncpy( WFIFOCP( char_fd, 18 ), mapindex_id2name( sd->mapindex ), MAP_NAME_LENGTH_EXT ); + int offset = 18 + MAP_NAME_LENGTH_EXT; + WFIFOW( char_fd, offset + 0 ) = sd->bl.x; + WFIFOW( char_fd, offset + 2 ) = sd->bl.y; + WFIFOL( char_fd, offset + 4 ) = htonl( ip ); + WFIFOW( char_fd, offset + 8 ) = htons( port ); + WFIFOB( char_fd, offset + 10 ) = sd->status.sex; + WFIFOL( char_fd, offset + 11 ) = htonl( session[sd->fd]->client_addr ); + WFIFOL( char_fd, offset + 15 ) = sd->group_id; + WFIFOSET( char_fd, 37 + MAP_NAME_LENGTH_EXT ); return 0; } /// map-server change (mapserv) request acknowledgement (positive or negative) -/// R 2b06 .L .L .L .L .W .W .W .L .W -int chrif_changemapserverack(uint32 account_id, int login_id1, int login_id2, uint32 char_id, short map_index, short x, short y, uint32 ip, uint16 port) { +/// R 2b06 .L .L .L .L .16B .W .W .L .W +int chrif_changemapserverack(uint32 account_id, int login_id1, int login_id2, uint32 char_id, const char* map, short x, short y, uint32 ip, uint16 port) { struct auth_node *node; if ( !( node = chrif_auth_check(account_id, char_id, ST_MAPCHANGE) ) ) @@ -473,7 +463,7 @@ int chrif_changemapserverack(uint32 account_id, int login_id1, int login_id2, ui clif_authfail_fd(node->fd, 0); chrif_char_offline(node->sd); } else - clif_changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port)); + clif_changemapserver(node->sd, map, x, y, ntohl(ip), ntohs(port)); //Player has been saved already, remove him from memory. [Skotlex] chrif_auth_delete(account_id, char_id, ST_MAPCHANGE); @@ -578,7 +568,6 @@ void chrif_on_ready(void) { /** * Maps are sent, then received misc info from char-server * - Server name - * - Default map * HZ 0x2afb **/ int chrif_sendmapack(int fd) { @@ -592,19 +581,11 @@ int chrif_sendmapack(int fd) { // Whisper name safestrncpy( wisp_server_name, RFIFOCP( fd, offs ), NAME_LENGTH ); - // Default map - safestrncpy( map_default.mapname, RFIFOCP( fd, ( offs += NAME_LENGTH ) ), MAP_NAME_LENGTH ); - map_default.x = RFIFOW(fd, (offs+=MAP_NAME_LENGTH)); - map_default.y = RFIFOW(fd, (offs+=2)); - // Server name - safestrncpy( charserver_name, RFIFOCP( fd, ( offs += 2 ) ), NAME_LENGTH ); + safestrncpy( charserver_name, RFIFOCP( fd, offs + NAME_LENGTH ), NAME_LENGTH ); ShowStatus( "Map-server connected to char-server '" CL_WHITE "%s" CL_RESET "' (whispername: %s).\n", charserver_name, wisp_server_name ); - if (battle_config.etc_log) - ShowInfo("Received default map from char-server '" CL_WHITE "%s %d,%d" CL_RESET "'.\n", map_default.mapname, map_default.x, map_default.y); - chrif_on_ready(); return 0; @@ -1784,7 +1765,7 @@ int chrif_parse(int fd) { case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break; case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break; case 0x2b04: chrif_recvmap(fd); break; - case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break; + case 0x2b06: chrif_changemapserverack( RFIFOL( fd, 2 ), RFIFOL( fd, 6 ), RFIFOL( fd, 10 ), RFIFOL( fd, 14 ), RFIFOCP( fd, 18 ), RFIFOW( fd, 18 + MAP_NAME_LENGTH_EXT ), RFIFOW( fd, 18 + MAP_NAME_LENGTH_EXT + 2 ), RFIFOL( fd, 18 + MAP_NAME_LENGTH_EXT + 4 ), RFIFOW( fd, 18 + MAP_NAME_LENGTH_EXT + 8 ) ); break; case 0x2b09: map_addnickdb(RFIFOL(fd,2), RFIFOCP(fd,6)); break; case 0x2b0b: chrif_skillcooldown_load(fd); break; case 0x2b0d: chrif_changedsex(fd); break; diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 19f3f67dba..dc0038e1bb 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -2115,7 +2115,7 @@ void clif_changemap(map_session_data *sd, short m, int x, int y) /// Notifies the client of a position change to coordinates on given map, which is on another map-server. /// 0092 .16B .W .W .L .W (ZC_NPCACK_SERVERMOVE) /// 0ac7 .16B .W .W .L .W .128B (ZC_NPCACK_SERVERMOVE2) -void clif_changemapserver(map_session_data* sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port) +void clif_changemapserver(map_session_data* sd, const char* map, int x, int y, uint32 ip, uint16 port) { int fd; #if PACKETVER >= 20170315 @@ -2128,7 +2128,7 @@ void clif_changemapserver(map_session_data* sd, unsigned short map_index, int x, WFIFOHEAD(fd,packet_len(cmd)); WFIFOW(fd,0) = cmd; - mapindex_getmapname_ext(mapindex_id2name(map_index), WFIFOCP(fd,2)); + mapindex_getmapname_ext( map, WFIFOCP( fd, 2 ) ); WFIFOW(fd,18) = x; WFIFOW(fd,20) = y; WFIFOL(fd,22) = htonl(ip); @@ -6245,8 +6245,7 @@ void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,i /// Presents a list of available warp destinations (ZC_WARPLIST). /// 011c .W { .16B }*4 -void clif_skill_warppoint(map_session_data* sd, uint16 skill_id, uint16 skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4) -{ +void clif_skill_warppoint( map_session_data* sd, uint16 skill_id, uint16 skill_lv, const char* map1, const char* map2, const char* map3, const char* map4 ){ int fd; nullpo_retv(sd); fd = sd->fd; @@ -6255,12 +6254,18 @@ void clif_skill_warppoint(map_session_data* sd, uint16 skill_id, uint16 skill_lv WFIFOW(fd,0) = 0x11c; WFIFOW(fd,2) = skill_id; memset(WFIFOP(fd,4), 0x00, 4*MAP_NAME_LENGTH_EXT); - if (map1 == (unsigned short)-1) strcpy(WFIFOCP(fd,4), "Random"); - else // normal map name - if (map1 > 0) mapindex_getmapname_ext(mapindex_id2name(map1), WFIFOCP(fd,4)); - if (map2 > 0) mapindex_getmapname_ext(mapindex_id2name(map2), WFIFOCP(fd,20)); - if (map3 > 0) mapindex_getmapname_ext(mapindex_id2name(map3), WFIFOCP(fd,36)); - if (map4 > 0) mapindex_getmapname_ext(mapindex_id2name(map4), WFIFOCP(fd,52)); + if( strcmp( "", map1 ) != 0 ){ + mapindex_getmapname_ext( map1, WFIFOCP( fd, 4 ) ); + } + if( strcmp( "", map2 ) != 0 ){ + mapindex_getmapname_ext( map2, WFIFOCP( fd, 20 ) ); + } + if( strcmp( "", map3 ) != 0 ){ + mapindex_getmapname_ext( map3, WFIFOCP( fd, 36 ) ); + } + if( strcmp( "", map4 ) != 0 ){ + mapindex_getmapname_ext( map4, WFIFOCP( fd, 52 ) ); + } WFIFOSET(fd,packet_len(0x11c)); sd->menuskill_id = skill_id; @@ -7979,7 +7984,7 @@ void clif_party_info( struct party_data& party, map_session_data* sd ){ member.GID = m.char_id; #endif safestrncpy( member.playerName, m.name, sizeof( member.playerName ) ); - mapindex_getmapname_ext( mapindex_id2name( m.map ), member.mapName ); + mapindex_getmapname_ext( m.map, member.mapName ); member.leader = ( m.leader ) ? 0 : 1; member.offline = ( m.online ) ? 0 : 1; #if PACKETVER_MAIN_NUM >= 20170524 || PACKETVER_RE_NUM >= 20170502 || defined(PACKETVER_ZERO) diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 3ce6dd9698..95de965402 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -639,7 +639,7 @@ int clif_spawn(struct block_list *bl, bool walking = false); //area void clif_walkok(map_session_data *sd); // self void clif_move(struct unit_data *ud); //area void clif_changemap(map_session_data *sd, short m, int x, int y); //self -void clif_changemapserver(map_session_data* sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port); //self +void clif_changemapserver( map_session_data* sd, const char* map, int x, int y, uint32 ip, uint16 port ); void clif_blown(struct block_list *bl); // area void clif_slide(struct block_list *bl, int x, int y); // area void clif_fixpos(struct block_list *bl); // area @@ -746,7 +746,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,t_tick tick, bool clif_skill_nodamage(struct block_list *src,struct block_list *dst,uint16 skill_id,int heal,t_tick tick); void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,int y,t_tick tick); void clif_skill_estimation(map_session_data *sd,struct block_list *dst); -void clif_skill_warppoint(map_session_data* sd, uint16 skill_id, uint16 skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4); +void clif_skill_warppoint( map_session_data* sd, uint16 skill_id, uint16 skill_lv, const char* map1, const char* map2 = "", const char* map3 = "", const char* map4 = "" ); void clif_skill_memomessage(map_session_data* sd, int type); void clif_skill_teleportmessage(map_session_data *sd, int type); void clif_skill_produce_mix_list(map_session_data *sd, int skill_id, int trigger); diff --git a/src/map/guild.cpp b/src/map/guild.cpp index dd8be1668e..0c7ef9a535 100644 --- a/src/map/guild.cpp +++ b/src/map/guild.cpp @@ -299,7 +299,7 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) { uint16 mapindex = mapindex_name2idx(map_name.c_str(), nullptr); - if (map_mapindex2mapid(mapindex) < 0) { + if( mapindex == 0 ){ this->invalidWarning(node["Map"], "Map %s doesn't exist, skipping.\n", map_name.c_str()); return 0; } @@ -394,7 +394,8 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) { map_data* md = map_getmapdata( map_mapindex2mapid( gc->mapindex ) ); - if( warp_x >= md->xs ){ + // If the map is on another map-server, we cannot verify the bounds + if( md != nullptr && warp_x >= md->xs ){ this->invalidWarning( node["WarpX"], "WarpX has to be smaller than %hu.\n", md->xs ); return 0; } @@ -420,7 +421,8 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) { map_data* md = map_getmapdata( map_mapindex2mapid( gc->mapindex ) ); - if( warp_y >= md->ys ){ + // If the map is on another map-server, we cannot verify the bounds + if( md != nullptr && warp_y >= md->ys ){ this->invalidWarning( node["WarpY"], "WarpY has to be smaller than %hu.\n", md->ys ); return 0; } @@ -1218,11 +1220,9 @@ int guild_member_withdraw(int guild_id, uint32 account_id, uint32 char_id, int f if (g->instance_id) { struct map_data *mapdata = map_getmapdata(sd->bl.m); - if (mapdata->instance_id) { // User was on the instance map - if (mapdata->save.map) - pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, CLR_TELEPORT); - else - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); + // User was on the instance map of the guild + if( g->instance_id == mapdata->instance_id ){ + pc_setpos_savepoint( *sd ); } } diff --git a/src/map/instance.cpp b/src/map/instance.cpp index c5f1af60eb..151f5a7771 100644 --- a/src/map/instance.cpp +++ b/src/map/instance.cpp @@ -167,14 +167,21 @@ uint64 InstanceDatabase::parseBodyNode(const ryml::NodeRef& node) { if (!this->asString(enterNode, "Map", map)) return 0; - int16 m = map_mapname2mapid(map.c_str()); + uint16 mapindex = mapindex_name2idx( map.c_str(), nullptr ); - if (m == -1) { + if( mapindex == 0 ){ this->invalidWarning(enterNode["Map"], "Map %s is not a valid map, skipping.\n", map.c_str()); return 0; } - instance->enter.map = m; + int16 mapid = map_mapindex2mapid( mapindex ); + + if( mapid < 0 ){ + // Ignore silently, the map is on another mapserver + return 0; + } + + instance->enter.map = mapid; } if (this->nodeExists(enterNode, "X")) { diff --git a/src/map/intif.cpp b/src/map/intif.cpp index 9218db61c3..e51feb7dda 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -37,7 +37,7 @@ static const int packet_len_table[] = { -1,-1,27,-1, -1, 0,37,-1, 10+NAME_LENGTH,-1, 0, 0, 0, 0, 0, 0, //0x3800-0x380f 0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 - 39,-1,15,15, 15+NAME_LENGTH,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 + 39,-1,15,15, 15+NAME_LENGTH,17+MAP_NAME_LENGTH_EXT, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 -1,10, 0,18, 0, 0, 0, 0, -1,75,-1,11, 11,-1, 38, 0, //0x3840 -1,-1, 7, 7, 7,11, 8,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari] @@ -709,15 +709,15 @@ int intif_party_changemap(map_session_data *sd,int online) } else mapindex = sd->mapindex; - WFIFOHEAD(inter_fd,19); + WFIFOHEAD( inter_fd, 17 + MAP_NAME_LENGTH_EXT ); WFIFOW(inter_fd,0)=0x3025; WFIFOL(inter_fd,2)=sd->status.party_id; WFIFOL(inter_fd,6)=sd->status.account_id; WFIFOL(inter_fd,10)=sd->status.char_id; - WFIFOW(inter_fd,14)=mapindex; - WFIFOB(inter_fd,16)=online; - WFIFOW(inter_fd,17)=sd->status.base_level; - WFIFOSET(inter_fd,19); + WFIFOB(inter_fd,14)=online; + WFIFOW(inter_fd,15)=sd->status.base_level; + safestrncpy( WFIFOCP( inter_fd, 17 ), mapindex_id2name( mapindex ), MAP_NAME_LENGTH_EXT ); + WFIFOSET( inter_fd, 17 + MAP_NAME_LENGTH_EXT ); return 1; } @@ -1628,7 +1628,7 @@ int intif_parse_PartyBroken(int fd) */ int intif_parse_PartyMove(int fd) { - party_recv_movemap(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOW(fd,14),RFIFOB(fd,16),RFIFOW(fd,17)); + party_recv_movemap( RFIFOL( fd, 2 ), RFIFOL( fd, 6 ), RFIFOL( fd, 10 ), RFIFOB( fd, 14 ), RFIFOW( fd, 15 ), RFIFOCP( fd, 17 ) ); return 1; } diff --git a/src/map/map.cpp b/src/map/map.cpp index 04be885f7f..1e4465b2e9 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -182,8 +182,6 @@ const char *MSG_CONF_NAME_THA; char wisp_server_name[NAME_LENGTH] = "Server"; // can be modified in char-server configuration file -struct s_map_default map_default; - int console = 0; int enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex] int enable_grf = 0; //To enable/disable reading maps from GRF files, bypassing mapcache [blackhole89] @@ -2146,23 +2144,6 @@ int map_quit(map_session_data *sd) { unit_remove_map_pc(sd,CLR_RESPAWN); - if( mapdata->instance_id > 0 ) { // Avoid map conflicts and warnings on next login - int16 m; - struct point *pt; - if( mapdata->save.map ) - pt = &mapdata->save; - else - pt = &sd->status.save_point; - - if( (m=map_mapindex2mapid(pt->map)) >= 0 ) - { - sd->bl.m = m; - sd->bl.x = pt->x; - sd->bl.y = pt->y; - sd->mapindex = pt->map; - } - } - if (sd->state.vending) idb_remove(vending_getdb(), sd->status.char_id); @@ -2751,7 +2732,7 @@ static int map_instancemap_leave(struct block_list *bl, va_list ap) nullpo_retr(0, bl); nullpo_retr(0, sd = (map_session_data *)bl); - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); + pc_setpos_savepoint( *sd ); return 1; } @@ -5153,11 +5134,6 @@ bool MapServer::initialize( int argc, char *argv[] ){ MSG_CONF_NAME_THA = "conf/msg_conf/map_msg_tha.conf"; // Thai /* Multilanguage */ - // Default map - safestrncpy(map_default.mapname, "prontera", MAP_NAME_LENGTH); - map_default.x = 156; - map_default.y = 191; - // default inter_config inter_config.start_status_points = 48; inter_config.emblem_woe_change = true; diff --git a/src/map/map.hpp b/src/map/map.hpp index 6c471659a6..5408807293 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -1051,13 +1051,6 @@ extern char channel_conf[]; extern char wisp_server_name[]; -struct s_map_default { - char mapname[MAP_NAME_LENGTH]; - unsigned short x; - unsigned short y; -}; -extern struct s_map_default map_default; - /// Type of 'save_settings' enum save_settings_type { CHARSAVE_NONE = 0x000, /// Never diff --git a/src/map/party.cpp b/src/map/party.cpp index 96c5bed141..d9149899bd 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -46,7 +46,7 @@ static void party_fill_member(struct party_member* member, map_session_data* sd, member->char_id = sd->status.char_id; safestrncpy(member->name, sd->status.name, NAME_LENGTH); member->class_ = sd->status.class_; - member->map = sd->mapindex; + safestrncpy( member->map, mapindex_id2name( sd->mapindex ), sizeof( member->map ) ); member->lv = sd->status.base_level; member->online = 1; member->leader = leader; @@ -780,14 +780,12 @@ int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id, char clif_name_area(&sd->bl); //Update name display [Skotlex] //TODO: hp bars should be cleared too - if( p->instance_id ) { + if( p != nullptr && p->instance_id ){ struct map_data *mapdata = map_getmapdata(sd->bl.m); - if( mapdata->instance_id ) { // User was on the instance map - if( mapdata->save.map ) - pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, CLR_TELEPORT); - else - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); + // User was on the instance map of the party + if( mapdata != nullptr && p->instance_id == mapdata->instance_id ){ + pc_setpos_savepoint( *sd ); } } } @@ -918,7 +916,7 @@ int party_changeleader(map_session_data *sd, map_session_data *tsd, struct party if (tmi == MAX_PARTY) return 0; // Shouldn't happen - if (battle_config.change_party_leader_samemap && p->party.member[mi].map != p->party.member[tmi].map) { + if( battle_config.change_party_leader_samemap && strncmp( p->party.member[mi].map, p->party.member[tmi].map, sizeof( p->party.member[mi].map ) ) != 0 ){ clif_msg(sd, PARTY_MASTER_CHANGE_SAME_MAP); return 0; } @@ -953,8 +951,7 @@ int party_changeleader(map_session_data *sd, map_session_data *tsd, struct party /// - changes maps /// - logs in or out /// - gains a level (disabled) -int party_recv_movemap(int party_id,uint32 account_id,uint32 char_id, unsigned short map_idx,int online,int lv) -{ +int party_recv_movemap( int party_id, uint32 account_id, uint32 char_id, int online, int lv, const char* map ){ struct party_member* m; struct party_data* p; int i; @@ -971,7 +968,7 @@ int party_recv_movemap(int party_id,uint32 account_id,uint32 char_id, unsigned s } m = &p->party.member[i]; - m->map = map_idx; + safestrncpy( m->map, map, sizeof( m->map ) ); m->online = online; m->lv = lv; //Check if they still exist on this map server diff --git a/src/map/party.hpp b/src/map/party.hpp index 082645029a..930672b334 100644 --- a/src/map/party.hpp +++ b/src/map/party.hpp @@ -79,7 +79,7 @@ int party_reply_invite(map_session_data *sd,int party_id,int flag); #define party_add_member(party_id,sd) party_reply_invite(sd,party_id,1) int party_recv_noinfo(int party_id, uint32 char_id); int party_recv_info(struct party* sp, uint32 char_id); -int party_recv_movemap(int party_id,uint32 account_id,uint32 char_id, unsigned short map,int online,int lv); +int party_recv_movemap( int party_id, uint32 account_id, uint32 char_id, int online, int lv, const char* map ); int party_broken(int party_id); int party_optionchanged(int party_id,uint32 account_id,int exp,int item,int flag); int party_changeoption(map_session_data *sd,int exp,int item); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index a8fab1798c..7f08340594 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -1315,31 +1315,51 @@ void pc_makesavestatus(map_session_data *sd) { sd->status.sp = sd->battle_status.sp; sd->status.ap = sd->battle_status.ap; } - sd->status.last_point.map = sd->mapindex; + mapindex_getmapname( mapindex_id2name( sd->mapindex ), sd->status.last_point.map ); sd->status.last_point.x = sd->bl.x; sd->status.last_point.y = sd->bl.y; return; } - if(pc_isdead(sd)) { - pc_setrestartvalue(sd, 0); - memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point)); - } else { + if( pc_isdead( sd ) ){ + pc_setrestartvalue( sd, 0 ); + + // Return to save point + safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) ); + sd->status.last_point.x = sd->status.save_point.x; + sd->status.last_point.y = sd->status.save_point.y; + }else{ sd->status.hp = sd->battle_status.hp; sd->status.sp = sd->battle_status.sp; sd->status.ap = sd->battle_status.ap; - sd->status.last_point.map = sd->mapindex; - sd->status.last_point.x = sd->bl.x; - sd->status.last_point.y = sd->bl.y; - } - if(map_getmapflag(sd->bl.m, MF_NOSAVE)) { - struct map_data *mapdata = map_getmapdata(sd->bl.m); + struct map_data* mapdata = map_getmapdata( sd->bl.m ); - if(mapdata->save.map) - memcpy(&sd->status.last_point,&mapdata->save,sizeof(sd->status.last_point)); - else - memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point)); + // If saving is not allowed on the map, we return the player to the designated point + if( mapdata->flag[MF_NOSAVE] ){ + // The map has a specific return point + if( mapdata->save.map ){ + safestrncpy( sd->status.last_point.map, mapindex_id2name( mapdata->save.map ), sizeof( sd->status.last_point.map ) ); + sd->status.last_point.x = mapdata->save.x; + sd->status.last_point.y = mapdata->save.y; + // Return the user to his save point + }else{ + safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) ); + sd->status.last_point.x = sd->status.save_point.x; + sd->status.last_point.y = sd->status.save_point.y; + } + // If the user is on a instance map, we return him to his save point + }else if( mapdata->instance_id ){ + // Return the user to his save point + safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) ); + sd->status.last_point.x = sd->status.save_point.x; + sd->status.last_point.y = sd->status.save_point.y; + }else{ + // Save normally + mapindex_getmapname( mapindex_id2name( sd->mapindex ), sd->status.last_point.map ); + sd->status.last_point.x = sd->bl.x; + sd->status.last_point.y = sd->bl.y; + } } } @@ -2011,9 +2031,9 @@ bool pc_authok(map_session_data *sd, uint32 login_id2, time_t expiration_time, i sd->vars_received = 0x0; //warp player - enum e_setpos setpos_result = pc_setpos( sd, sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT ); + enum e_setpos setpos_result = pc_setpos( sd, mapindex_name2id( sd->status.last_point.map ), sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT ); if( setpos_result != SETPOS_OK ){ - ShowError( "Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, setpos_result ); + ShowError( "Last_point_map %s not found (error code %d)\n", sd->status.last_point.map, setpos_result ); // try warping to a default map instead (church graveyard) if (pc_setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != SETPOS_OK) { @@ -6892,6 +6912,16 @@ enum e_setpos pc_setpos(map_session_data* sd, unsigned short mapindex, int x, in return SETPOS_OK; } +enum e_setpos pc_setpos_savepoint( map_session_data& sd, clr_type clrtype ){ + struct map_data *mapdata = map_getmapdata( sd.bl.m ); + + if( mapdata != nullptr && mapdata->flag[MF_NOSAVE] && mapdata->save.map ){ + return pc_setpos( &sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, clrtype ); + }else{ + return pc_setpos( &sd, mapindex_name2id( sd.status.save_point.map ), sd.status.save_point.x, sd.status.save_point.y, clrtype ); + } +} + /*========================================== * Warp player sd to random location on current map. * May fail if no walkable cell found (1000 attempts). @@ -6955,9 +6985,11 @@ bool pc_memo(map_session_data* sd, int pos) if( pos == -1 ) { uint8 i; + const char* mapname = map_mapid2mapname( sd->bl.m ); + // prevent memo-ing the same map multiple times - ARR_FIND( 0, MAX_MEMOPOINTS, i, sd->status.memo_point[i].map == map_id2index(sd->bl.m) ); - memmove(&sd->status.memo_point[1], &sd->status.memo_point[0], (u8min(i,MAX_MEMOPOINTS-1))*sizeof(struct point)); + ARR_FIND( 0, MAX_MEMOPOINTS, i, strncmp( sd->status.memo_point[i].map, mapname, sizeof( sd->status.memo_point[i].map ) ) == 0 ); + memmove( &sd->status.memo_point[1], &sd->status.memo_point[0], ( u8min( i, MAX_MEMOPOINTS - 1 ) ) * sizeof( struct s_point_str ) ); pos = 0; } @@ -6966,7 +6998,7 @@ bool pc_memo(map_session_data* sd, int pos) return false; } - sd->status.memo_point[pos].map = map_id2index(sd->bl.m); + safestrncpy( sd->status.memo_point[pos].map, map_mapid2mapname( sd->bl.m ), sizeof( sd->status.memo_point[pos].map ) ); sd->status.memo_point[pos].x = sd->bl.x; sd->status.memo_point[pos].y = sd->bl.y; @@ -9340,8 +9372,9 @@ void pc_respawn(map_session_data* sd, clr_type clrtype) pc_setstand(sd, true); pc_setrestartvalue(sd,3); - if( pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype) != SETPOS_OK ) + if( pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, clrtype ) != SETPOS_OK ){ clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet. + } } static TIMER_FUNC(pc_respawn_timer){ @@ -12645,7 +12678,7 @@ void pc_setsavepoint(map_session_data *sd, short mapindex,int x,int y) { nullpo_retv(sd); - sd->status.save_point.map = mapindex; + safestrncpy( sd->status.save_point.map, mapindex_id2name( mapindex ), sizeof( sd->status.save_point.map ) ); sd->status.save_point.x = x; sd->status.save_point.y = y; } diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 91fe236930..addb6d3553 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -1408,6 +1408,7 @@ enum e_setpos{ }; enum e_setpos pc_setpos(map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype); +enum e_setpos pc_setpos_savepoint( map_session_data& sd, clr_type clrtype = CLR_TELEPORT ); void pc_setsavepoint(map_session_data *sd, short mapindex,int x,int y); char pc_randomwarp(map_session_data *sd,clr_type type,bool ignore_mapflag = false); bool pc_memo(map_session_data* sd, int pos); diff --git a/src/map/script.cpp b/src/map/script.cpp index 9a0ca776f7..bc522a7807 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -5612,7 +5612,7 @@ BUILDIN_FUNC(warp) if(strcmp(str,"Random")==0) ret = pc_randomwarp(sd,CLR_TELEPORT,true); else if(strcmp(str,"SavePoint")==0 || strcmp(str,"Save")==0) - ret = pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); + ret = pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); else ret = pc_setpos(sd,mapindex_name2id(str),x,y,CLR_OUTSIGHT); @@ -5851,11 +5851,11 @@ BUILDIN_FUNC(warpparty) break; case WARPPARTY_SAVEPOINTALL: if (!mapdata->flag[MF_NORETURN]) - ret = pc_setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT); + ret = pc_setpos( pl_sd, mapindex_name2id( pl_sd->status.save_point.map ), pl_sd->status.save_point.x, pl_sd->status.save_point.y, CLR_TELEPORT ); break; case WARPPARTY_SAVEPOINT: if (!mapdata->flag[MF_NORETURN]) - ret = pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); + ret = pc_setpos( pl_sd, mapindex_name2id( sd->status.save_point.map ),sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); break; case WARPPARTY_LEADER: if (p->party.member[i].leader) @@ -5957,11 +5957,11 @@ BUILDIN_FUNC(warpguild) break; case 1: // SavePointAll if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN)) - pc_setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT); + pc_setpos( pl_sd, mapindex_name2id( pl_sd->status.save_point.map ), pl_sd->status.save_point.x, pl_sd->status.save_point.y, CLR_TELEPORT ); break; case 2: // SavePoint if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN)) - pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); + pc_setpos( pl_sd, mapindex_name2id( sd->status.save_point.map ),sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); break; case 3: // m,x,y if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN) && !map_getmapflag(pl_sd->bl.m, MF_NOWARP) && pc_job_can_entermap((enum e_job)pl_sd->status.class_, m, pc_get_group_level(pl_sd))) @@ -8986,7 +8986,7 @@ BUILDIN_FUNC(getpartyleader) case 1: script_pushint(st,p->party.member[i].account_id); break; case 2: script_pushint(st,p->party.member[i].char_id); break; case 3: script_pushint(st,p->party.member[i].class_); break; - case 4: script_pushstrcopy(st,mapindex_id2name(p->party.member[i].map)); break; + case 4: script_pushstrcopy( st, p->party.member[i].map ); break; case 5: script_pushint(st,p->party.member[i].lv); break; default: script_pushstrcopy(st,p->party.member[i].name); break; } @@ -13126,7 +13126,7 @@ BUILDIN_FUNC(warpwaitingpc) if( strcmp(map_name,"Random") == 0 ) pc_randomwarp(sd,CLR_TELEPORT,true); else if( strcmp(map_name,"SavePoint") == 0 ) - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); + pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); else pc_setpos(sd, mapindex_name2id(map_name), x, y, CLR_OUTSIGHT); } @@ -13620,7 +13620,7 @@ static int buildin_maprespawnguildid_sub_pc(map_session_data* sd, va_list ap) (sd->status.guild_id != g_id && flag&2) || //Warp out outsiders (sd->status.guild_id == 0 && flag&2) // Warp out players not in guild ) - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); + pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); return 1; } @@ -15506,7 +15506,7 @@ int atcommand_sub(struct script_state* st,int type) { memcpy(&dummy_sd.bl, bl, sizeof(struct block_list)); if (bl->type == BL_NPC) safestrncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH); - sd->mapindex = (bl->m > 0) ? map_id2index(bl->m) : mapindex_name2id(map_default.mapname); + sd->mapindex = (bl->m > 0) ? map_id2index(bl->m) : 0; } // Init Group ID, Level, & permissions @@ -16090,7 +16090,7 @@ BUILDIN_FUNC(getsavepoint) type = script_getnum(st,2); switch(type) { - case 0: script_pushstrcopy(st,mapindex_id2name(sd->status.save_point.map)); break; + case 0: script_pushstrcopy( st, sd->status.save_point.map ); break; case 1: script_pushint(st,sd->status.save_point.x); break; case 2: script_pushint(st,sd->status.save_point.y); break; default: diff --git a/src/map/skill.cpp b/src/map/skill.cpp index e24aa56036..867bff2564 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -9057,15 +9057,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( skill_lv == 1 ) pc_randomwarp(sd,CLR_TELEPORT); else - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); + pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); break; } clif_skill_nodamage(src,bl,skill_id,skill_lv,1); if( skill_lv == 1 && skill_id != ALL_ODINS_RECALL ) - clif_skill_warppoint(sd,skill_id,skill_lv, (unsigned short)-1,0,0,0); + clif_skill_warppoint( sd, skill_id, skill_lv, "Random" ); else - clif_skill_warppoint(sd,skill_id,skill_lv, (unsigned short)-1,sd->status.save_point.map,0,0); + clif_skill_warppoint( sd, skill_id, skill_lv, "Random", sd->status.save_point.map ); } else unit_warp(bl,-1,-1,-1,CLR_TELEPORT); break; @@ -13604,9 +13604,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui if(sd) { clif_skill_warppoint(sd, skill_id, skill_lv, sd->status.save_point.map, - (skill_lv >= 2) ? sd->status.memo_point[0].map : 0, - (skill_lv >= 3) ? sd->status.memo_point[1].map : 0, - (skill_lv >= 4) ? sd->status.memo_point[2].map : 0 + (skill_lv >= 2) ? sd->status.memo_point[0].map : "", + (skill_lv >= 3) ? sd->status.memo_point[1].map : "", + (skill_lv >= 4) ? sd->status.memo_point[2].map : "" ); } if( sc && sc->getSCE(SC_CURSEDCIRCLE_ATKER) ) //Should only remove after the skill has been casted. @@ -14243,14 +14243,14 @@ int skill_castend_map (map_session_data *sd, uint16 skill_id, const char *mapnam if(strcmp(mapname,"Random") == 0) pc_randomwarp(sd,CLR_TELEPORT); else if (sd->menuskill_val > 1 || skill_id == ALL_ODINS_RECALL) //Need lv2 to be able to warp here. - pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); + pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ),sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); clif_refresh_storagewindow(sd); break; case AL_WARP: { - const struct point *p[4]; + const struct s_point_str *p[4]; std::shared_ptr group; int i, lv, wx, wy; int maxcount=0; @@ -14286,7 +14286,7 @@ int skill_castend_map (map_session_data *sd, uint16 skill_id, const char *mapnam if( lv > 4 ) lv = 4; // crash prevention // check if the chosen map exists in the memo list - ARR_FIND( 0, lv, i, mapindex == p[i]->map ); + ARR_FIND( 0, lv, i, strncmp( p[i]->map, mapname, sizeof( p[i]->map ) ) == 0 ); if( i < lv ) { x=p[i]->x; y=p[i]->y; diff --git a/src/map/status.cpp b/src/map/status.cpp index 40d1cf9e76..8b0a7daa87 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -11305,7 +11305,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val3 = map_idx; val4 = pos; } else if (!val3 || val3 == sd->mapindex) { // Use save point. - val3 = sd->status.save_point.map; + val3 = mapindex_name2id( sd->status.save_point.map ); val4 = (sd->status.save_point.x&0xFFFF) |(sd->status.save_point.y<<16); }