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