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!
This commit is contained in:
Lemongrass3110 2023-01-11 16:54:53 +01:00 committed by GitHub
parent cbe2acb786
commit 14cb61d598
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 311 additions and 337 deletions

View File

@ -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->base_exp != cp->base_exp) || (p->base_level != cp->base_level) ||
(p->job_level != cp->job_level) || (p->job_exp != cp->job_exp) || (p->job_level != cp->job_level) || (p->job_exp != cp->job_exp) ||
(p->zeny != cp->zeny) || (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) || (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_hp != cp->max_hp) || (p->hp != cp->hp) ||
(p->max_sp != cp->max_sp) || (p->sp != cp->sp) || (p->max_sp != cp->max_sp) || (p->sp != cp->sp) ||
(p->status_point != cp->status_point) || (p->skill_point != cp->skill_point) || (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->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->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, 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, 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->save_point.map, p->save_point.x, p->save_point.y, p->rename,
(unsigned long)p->delete_date, // FIXME: platform-dependent size (unsigned long)p->delete_date, // FIXME: platform-dependent size
p->robe, p->character_moves, p->font, p->uniqueitem_counter, 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, 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); 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 ) 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 ) if( count )
StringBuf_AppendStr(&buf, ","); 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); StringBuf_Printf(&buf, "('%d', '%s', '%d', '%d')", char_id, esc_mapname, p->memo_point[i].x, p->memo_point[i].y);
++count; ++count;
} }
@ -910,7 +911,6 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
SqlStmt* stmt; SqlStmt* stmt;
struct mmo_charstatus p; struct mmo_charstatus p;
int j = 0, i; int j = 0, i;
char last_map[MAP_NAME_LENGTH_EXT];
char sex[2]; char sex[2];
stmt = SqlStmt_Malloc(sql_handle); 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, 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, 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, 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, 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, 35, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p.robe, 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++ ) 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->found_char[p.slot] = p.char_id;
sd->unban_time[p.slot] = p.unban_time; sd->unban_time[p.slot] = p.unban_time;
p.sex = char_mmo_gender(sd, &p, sex[0]); 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 char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything) {
int i; int i;
SqlStmt* stmt; SqlStmt* stmt;
char last_map[MAP_NAME_LENGTH_EXT]; struct s_point_str tmp_point;
char save_map[MAP_NAME_LENGTH_EXT];
char point_map[MAP_NAME_LENGTH_EXT];
struct point tmp_point;
struct s_skill tmp_skill; struct s_skill tmp_skill;
uint16 skill_count = 0; uint16 skill_count = 0;
struct s_friend tmp_friend; 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, 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, 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, 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, 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, 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, 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, 44, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_UINT32, &p->partner_id, 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; return 0;
} }
p->sex = char_mmo_gender(NULL, p, sex[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_Init(&msg_buf);
StringBuf_AppendStr(&msg_buf, " status"); 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) 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_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
|| SQL_ERROR == SqlStmt_Execute(stmt) || 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, 1, SQLDT_SHORT, &tmp_point.x, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_point.y, 0, NULL, NULL) ) || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_point.y, 0, NULL, NULL) )
SqlStmt_ShowDebug(stmt); SqlStmt_ShowDebug(stmt);
for( i = 0; i < MAX_MEMOPOINTS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) 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)); memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
} }
StringBuf_AppendStr(&msg_buf, " memo"); 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 ){ 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 name[NAME_LENGTH];
char esc_name[NAME_LENGTH*2+1]; 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]; struct startitem tmp_start_items[MAX_STARTITEM];
uint32 char_id; uint32 char_id;
int flag, k, start_point_idx = rnd() % charserv_config.start_point_count; 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); normalize_name(name,TRIM_CHARS);
Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); 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)); 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)); memcpy(tmp_start_items, charserv_config.start_items, MAX_STARTITEM * sizeof(struct startitem));
flag = char_check_char_name(name,esc_name); 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. // Check for Doram based information.
if (start_job == JOB_SUMMONER) { // Check for just this job for now. 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)); 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)); memcpy(tmp_start_items, charserv_config.start_items_doram, MAX_STARTITEM * sizeof(struct startitem));
start_point_idx = rnd() % charserv_config.start_point_count_doram; 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')", "'%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, 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, (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); Sql_ShowDebug(sql_handle);
return -2; //No, stop the procedure! 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->hairColor = (uint8)u16min( p->hair_color, UINT8_MAX );
info->bIsChangedCharName = ( p->rename > 0 ) ? 0 : 1; info->bIsChangedCharName = ( p->rename > 0 ) ? 0 : 1;
#if (PACKETVER >= 20100720 && PACKETVER <= 20100727) || PACKETVER >= 20100803 #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 #endif
#if PACKETVER >= 20100803 #if PACKETVER >= 20100803
#if PACKETVER_CHAR_DELETEDATE #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). // 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). // 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++) for(int i = 0; i < ARRAYLENGTH(map_server); i++)
{ {
if (session_isValid(map_server[i].fd) if (session_isValid(map_server[i].fd)
&& (ip == (uint32)-1 || map_server[i].ip == ip) && (ip == (uint32)-1 || map_server[i].ip == ip)
&& (port == (uint16)-1 || map_server[i].port == port)) && (port == (uint16)-1 || map_server[i].port == port))
{ {
for (int j = 0; map_server[i].map[j]; j++) for( std::string& m : map_server[i].maps ){
if (map_server[i].map[j] == map) if( m == map ){
return i; return i;
}
}
} }
} }
@ -2774,13 +2757,13 @@ void char_set_defaults(){
charserv_config.char_check_db =1; charserv_config.char_check_db =1;
// See const.hpp to change the default values // 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].x = MAP_DEFAULT_X;
charserv_config.start_point[0].y = MAP_DEFAULT_Y; charserv_config.start_point[0].y = MAP_DEFAULT_Y;
charserv_config.start_point_count = 1; charserv_config.start_point_count = 1;
#if PACKETVER >= 20151001 #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].x = MAP_DEFAULT_X;
charserv_config.start_point_doram[0].y = MAP_DEFAULT_Y; charserv_config.start_point_doram[0].y = MAP_DEFAULT_Y;
charserv_config.start_point_count_doram = 1; charserv_config.start_point_count_doram = 1;
@ -2811,10 +2794,6 @@ void char_set_defaults(){
charserv_config.start_zeny = 0; charserv_config.start_zeny = 0;
charserv_config.guild_exp_rate = 100; 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.clan_remove_inactive_days = 14;
charserv_config.mail_return_days = 14; charserv_config.mail_return_days = 14;
charserv_config.mail_delete_days = 14; charserv_config.mail_delete_days = 14;
@ -2836,8 +2815,7 @@ void char_set_defaults(){
* @param start: Start point reference * @param start: Start point reference
* @param count: Start point count 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; char *lineitem, **fields;
int i = 0, fields_length = 3 + 1; 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; continue;
} }
start_point[i].map = mapindex_name2id(fields[1]); safestrncpy( start_point[i].map, fields[1], sizeof( start_point[i].map ) );
if (!start_point[i].map) { start_point[i].x = max( 0, atoi( fields[2] ) );
ShowError("Start point %s not found in map-index cache. Setting to default location.\n", fields[1]); start_point[i].y = max( 0, atoi( fields[3] ) );
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]));
}
(*count)++; (*count)++;
lineitem = strtok(NULL, ":"); //next lineitem 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); charserv_config.charmove_config.char_moves_unlimited = config_switch(w2);
} else if (strcmpi(w1, "char_checkdb") == 0) { } else if (strcmpi(w1, "char_checkdb") == 0) {
charserv_config.char_check_db = config_switch(w2); 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) { } else if (strcmpi(w1, "clan_remove_inactive_days") == 0) {
charserv_config.clan_remove_inactive_days = atoi(w2); charserv_config.clan_remove_inactive_days = atoi(w2);
} else if (strcmpi(w1, "mail_return_days") == 0) { } else if (strcmpi(w1, "mail_return_days") == 0) {
@ -3176,7 +3141,6 @@ void CharacterServer::finalize(){
} }
Sql_Free(sql_handle); Sql_Free(sql_handle);
mapindex_final();
ShowStatus("Finished.\n"); ShowStatus("Finished.\n");
} }
@ -3191,9 +3155,6 @@ void CharacterServer::handle_shutdown(){
} }
bool CharacterServer::initialize( int argc, char *argv[] ){ bool CharacterServer::initialize( int argc, char *argv[] ){
//Read map indexes
mapindex_init();
// Init default value // Init default value
CHAR_CONF_NAME = "conf/char_athena.conf"; CHAR_CONF_NAME = "conf/char_athena.conf";
LAN_CONF_NAME = "conf/subnet_athena.conf"; LAN_CONF_NAME = "conf/subnet_athena.conf";
@ -3295,8 +3256,6 @@ bool CharacterServer::initialize( int argc, char *argv[] ){
} }
do_init_chcnslif(); 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); ShowStatus("The char-server is " CL_GREEN "ready" CL_RESET " (Server is listening on the port %d).\n\n", charserv_config.char_port);

View File

@ -186,7 +186,7 @@ struct CharServ_Config {
int log_inter; // loggin inter or not [devil] int log_inter; // loggin inter or not [devil]
int char_check_db; ///cheking sql-table at begining ? 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 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 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; uint32 start_status_points;
@ -197,10 +197,6 @@ struct CharServ_Config {
int start_zeny; int start_zeny;
int guild_exp_rate; 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 clan_remove_inactive_days;
int mail_return_days; int mail_return_days;
int mail_delete_days; int mail_delete_days;
@ -218,7 +214,7 @@ struct mmo_map_server {
uint32 ip; uint32 ip;
uint16 port; uint16 port;
int users; int users;
std::vector<uint16> map; std::vector<std::string> maps;
}; };
extern struct mmo_map_server map_server[MAX_MAP_SERVERS]; 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 DEFAULT_AUTOSAVE_INTERVAL 300*1000
#define MAX_CHAR_BUF sizeof( struct CHARACTER_INFO ) //Max size (for WFIFOHEAD calls) #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_lan_subnetcheck(uint32 ip);
int char_count_users(void); int char_count_users(void);

View File

@ -5,6 +5,7 @@
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -29,6 +30,15 @@
using namespace rathena; using namespace rathena;
std::vector<struct s_point_str> 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 #if PACKETVER_SUPPORTS_PINCODE
bool pincode_allowed( char* pincode ); bool pincode_allowed( char* pincode );
#endif #endif
@ -693,7 +703,7 @@ int chclif_parse_maplogin(int fd){
map_server[i].ip = ntohl(RFIFOL(fd,54)); map_server[i].ip = ntohl(RFIFOL(fd,54));
map_server[i].port = ntohs(RFIFOW(fd,58)); map_server[i].port = ntohs(RFIFOW(fd,58));
map_server[i].users = 0; map_server[i].users = 0;
map_server[i].map = {}; map_server[i].maps = {};
session[fd]->func_parse = chmapif_parse; session[fd]->func_parse = chmapif_parse;
session[fd]->flag.server = 1; session[fd]->flag.server = 1;
realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
@ -796,7 +806,7 @@ void chclif_send_map_data( int fd, std::shared_ptr<struct mmo_charstatus> cd, ui
WFIFOHEAD(fd,size); WFIFOHEAD(fd,size);
WFIFOW(fd,0) = cmd; WFIFOW(fd,0) = cmd;
WFIFOL(fd,2) = cd->char_id; 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] 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); 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 [!] 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); int slot = RFIFOB(fd,2);
RFIFOSKIP(fd,3); 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) // Map-server not available, tell the client to wait (client wont close, char select will respawn)
if (server_id == ARRAYLENGTH(map_server)) { if (server_id == ARRAYLENGTH(map_server)) {
WFIFOHEAD(fd, 24); 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); ShowInfo("Selected char: (Account %d: %d - %s)\n", sd->account_id, slot, char_dat.name);
// searching map server // 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 map is not found, we check major cities
if (i < 0 || !cd->last_point.map) { if( i < 0 ){
unsigned short j; unsigned short j;
//First check that there's actually a map server online. //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)) { if (j == ARRAYLENGTH(map_server)) {
ShowInfo("Connection Closed. No map servers available.\n"); ShowInfo("Connection Closed. No map servers available.\n");
chclif_send_auth_result(fd,1); // 01 = Server closed chclif_send_auth_result(fd,1); // 01 = Server closed
return 1; return 1;
} }
if ((i = char_search_mapserver((j=mapindex_name2id(MAP_PRONTERA)),-1,-1)) >= 0) {
cd->last_point.x = 273; for( struct s_point_str& accessible_map : accessible_maps ){
cd->last_point.y = 354; i = char_search_mapserver( accessible_map.map, -1, -1 );
} else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_GEFFEN)),-1,-1)) >= 0) {
cd->last_point.x = 120; // Found a map-server for a map
cd->last_point.y = 100; if( i >= 0 ){
} else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_MORROC)),-1,-1)) >= 0) { ShowWarning( "Unable to find map-server for '%s', sending to major city '%s'.\n", cd->last_point.map, accessible_map.map );
cd->last_point.x = 160; memcpy( &cd->last_point, &accessible_map, sizeof( cd->last_point ) );
cd->last_point.y = 94; break;
} 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) { if( i < 0 ){
cd->last_point.x = 87; 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 );
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));
chclif_send_auth_result(fd,1); // 01 = Server closed chclif_send_auth_result(fd,1); // 01 = Server closed
return 1; 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] //Send NEW auth packet [Kevin]

View File

@ -823,7 +823,7 @@ void chlogif_on_ready(void)
chlogif_send_acc_tologin(INVALID_TIMER, gettick(), 0, 0); chlogif_send_acc_tologin(INVALID_TIMER, gettick(), 0, 0);
// if no map-server already connected, display a message... // 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) ) if( i == ARRAYLENGTH(map_server) )
ShowStatus("Awaiting maps from map-server.\n"); ShowStatus("Awaiting maps from map-server.\n");
} }

View File

@ -167,25 +167,21 @@ void chmapif_sendall_playercount(int users){
* Send some misc info to new map-server. * Send some misc info to new map-server.
* - Server name for whisper name * - Server name for whisper name
* - Default map * - Default map
* HZ 0x2afb <size>.W <status>.B <whisper name>.24B <mapname>.11B <map_x>.W <map_y>.W <server name>.24B * HZ 0x2afb <size>.W <status>.B <whisper name>.24B <server name>.24B
* @param fd * @param fd
**/ **/
void chmapif_send_misc(int fd) { void chmapif_send_misc(int fd) {
uint16 offs = 5; uint16 offs = 5;
unsigned char buf[45+NAME_LENGTH]; unsigned char buf[5+NAME_LENGTH+NAME_LENGTH];
memset(buf, '\0', sizeof(buf)); memset(buf, '\0', sizeof(buf));
WBUFW(buf, 0) = 0x2afb; WBUFW(buf, 0) = 0x2afb;
// 0 succes, 1:failure // 0 succes, 1:failure
WBUFB(buf, 4) = 0; WBUFB(buf, 4) = 0;
// Send name for wisp to player // Send name for wisp to player
safestrncpy( WBUFCP( buf, 5 ), charserv_config.wisp_server_name, NAME_LENGTH ); safestrncpy( WBUFCP( buf, offs ), charserv_config.wisp_server_name, NAME_LENGTH );
// Default map offs += NAME_LENGTH;
safestrncpy( WBUFCP( buf, ( offs += NAME_LENGTH ) ), charserv_config.default_map, MAP_NAME_LENGTH ); // 29 safestrncpy( WBUFCP( buf, offs ), charserv_config.server_name, sizeof( charserv_config.server_name ) );
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
offs += NAME_LENGTH; offs += NAME_LENGTH;
// 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); ShowWarning("Map-server %d has NO maps.\n", map_id);
} }
else { else {
unsigned char buf[16384]; unsigned char buf[INT16_MAX];
// Transmitting maps information to the other map-servers // Transmitting maps information to the other map-servers
WBUFW(buf,0) = 0x2b04; 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); WBUFL(buf,4) = htonl(map_server[map_id].ip);
WBUFW(buf,8) = htons(map_server[map_id].port); 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)); chmapif_sendallwos(fd, buf, WBUFW(buf,2));
} }
// Transmitting the maps of the other map-servers to the new map-server // Transmitting the maps of the other map-servers to the new map-server
for (x = 0; x < ARRAYLENGTH(map_server); x++) { for (x = 0; x < ARRAYLENGTH(map_server); x++) {
if (session_isValid(map_server[x].fd) && x != map_id) { 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; WFIFOW(fd,0) = 0x2b04;
WFIFOL(fd,4) = htonl(map_server[x].ip); WFIFOL(fd,4) = htonl(map_server[x].ip);
WFIFOW(fd,8) = htons(map_server[x].port); WFIFOW(fd,8) = htons(map_server[x].port);
uint16 j = 0; uint16 j = 0;
for(size_t i = 0; i < map_server[x].map.size(); i++) for( std::string& map : map_server[x].maps ){
if (map_server[x].map[i]) safestrncpy( WFIFOCP( fd, 10 + j * MAP_NAME_LENGTH_EXT ), map.c_str(), MAP_NAME_LENGTH_EXT );
WFIFOW(fd,10+(j++)*4) = map_server[x].map[i]; j++;
}
if (j > 0) { if (j > 0) {
WFIFOW(fd,2) = j * 4 + 10; WFIFOW( fd, 2 ) = j * MAP_NAME_LENGTH_EXT + 10;
WFIFOSET(fd,WFIFOW(fd,2)); WFIFOSET(fd,WFIFOW(fd,2));
} }
} }
@ -252,20 +250,26 @@ int chmapif_parse_getmapname(int fd, int id){
return 0; return 0;
//Retain what map-index that map-serv contains //Retain what map-index that map-serv contains
map_server[id].map = {}; map_server[id].maps.clear();
for(i = 4; i < RFIFOW(fd,2); i += 4)
map_server[id].map.push_back(RFIFOW(fd, i)); 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); mapbuf = RFIFOP(fd,4);
RFIFOSKIP(fd,RFIFOW(fd,2)); RFIFOSKIP(fd,RFIFOW(fd,2));
ShowStatus("Map-Server %d connected: %" PRIuPTR " maps, from IP %d.%d.%d.%d port %d.\n", 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); ShowStatus("Map-server %d loading complete.\n", id);
chmapif_send_misc(fd); chmapif_send_misc(fd);
chmapif_send_fame_list(fd); //Send fame list. 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; return 1;
} }
@ -589,12 +593,13 @@ int chmapif_parse_req_skillcooldown(int fd){
* @param nok : 0=accepted or no=1 * @param nok : 0=accepted or no=1
*/ */
void chmapif_changemapserv_ack(int fd, bool nok){ 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; 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) if(nok)
WFIFOL(fd,6) = 0; //Set login1 to 0.(not ok) 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 * @return : 0 not enough data received, 1 success
*/ */
int chmapif_parse_reqchangemapserv(int fd){ int chmapif_parse_reqchangemapserv(int fd){
if (RFIFOREST(fd) < 39) if( RFIFOREST( fd ) < ( 37 + MAP_NAME_LENGTH_EXT ) ){
return 0; return 0;
}
else { else {
int map_id, map_fd = -1; int map_id, map_fd = -1;
struct mmo_charstatus char_dat; 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) if (map_id >= 0)
map_fd = map_server[map_id].fd; map_fd = map_server[map_id].fd;
@ -631,10 +638,10 @@ int chmapif_parse_reqchangemapserv(int fd){
uint32 aid = RFIFOL( fd, 2 ); uint32 aid = RFIFOL( fd, 2 );
//Update the "last map" as this is where the player must be spawned on the new map server. //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); safestrncpy( char_data->last_point.map, RFIFOCP( fd, 18 ), MAP_NAME_LENGTH_EXT );
char_data->last_point.x = RFIFOW(fd,20); char_data->last_point.x = RFIFOW( fd, offset + 0 );
char_data->last_point.y = RFIFOW(fd,22); char_data->last_point.y = RFIFOW( fd, offset + 2 );
char_data->sex = RFIFOB(fd,30); char_data->sex = RFIFOB( fd, offset + 10 );
// create temporary auth entry // create temporary auth entry
std::shared_ptr<struct auth_node> node = std::make_shared<struct auth_node>(); std::shared_ptr<struct auth_node> node = std::make_shared<struct auth_node>();
@ -643,10 +650,10 @@ int chmapif_parse_reqchangemapserv(int fd){
node->char_id = char_id; node->char_id = char_id;
node->login_id1 = RFIFOL(fd,6); node->login_id1 = RFIFOL(fd,6);
node->login_id2 = RFIFOL(fd,10); 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->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->ip = ntohl( RFIFOL( fd, offset + 11 ) );
node->group_id = RFIFOL(fd,35); node->group_id = RFIFOL( fd, offset + 15 );
node->changing_mapservers = 1; node->changing_mapservers = 1;
char_get_authdb()[node->account_id] = node; char_get_authdb()[node->account_id] = node;
@ -665,7 +672,7 @@ int chmapif_parse_reqchangemapserv(int fd){
} else { //Reply with nak } else { //Reply with nak
chmapif_changemapserv_ack(fd,1); chmapif_changemapserv_ack(fd,1);
} }
RFIFOSKIP(fd,39); RFIFOSKIP( fd, 37 + MAP_NAME_LENGTH_EXT );
} }
return 1; return 1;
} }
@ -1503,18 +1510,19 @@ void do_init_chmapif(void){
*/ */
void chmapif_server_reset(int id){ void chmapif_server_reset(int id){
int j = 0; int j = 0;
unsigned char buf[16384]; unsigned char buf[INT16_MAX];
int fd = map_server[id].fd; int fd = map_server[id].fd;
//Notify other map servers that this one is gone. [Skotlex] //Notify other map servers that this one is gone. [Skotlex]
WBUFW(buf,0) = 0x2b20; WBUFW(buf,0) = 0x2b20;
WBUFL(buf,4) = htonl(map_server[id].ip); WBUFL(buf,4) = htonl(map_server[id].ip);
WBUFW(buf,8) = htons(map_server[id].port); WBUFW(buf,8) = htons(map_server[id].port);
for(size_t i = 0; i < map_server[id].map.size(); i++) for( std::string& map : map_server[id].maps ){
if (map_server[id].map[i]) safestrncpy( WBUFCP( buf, 10 + j * MAP_NAME_LENGTH_EXT ), map.c_str(), MAP_NAME_LENGTH_EXT );
WBUFW(buf,10+(j++)*4) = map_server[id].map[i]; j++;
}
if (j > 0) { 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)); chmapif_sendallwos(fd, buf, WBUFW(buf,2));
} }

View File

@ -11,7 +11,6 @@
#include "../common/cbasetypes.hpp" #include "../common/cbasetypes.hpp"
#include "../common/malloc.hpp" #include "../common/malloc.hpp"
#include "../common/mapindex.hpp"
#include "../common/mmo.hpp" #include "../common/mmo.hpp"
#include "../common/showmsg.hpp" #include "../common/showmsg.hpp"
#include "../common/socket.hpp" #include "../common/socket.hpp"
@ -244,7 +243,7 @@ std::shared_ptr<struct party_data> inter_party_fromsql( int party_id ){
Sql_GetData(sql_handle, 1, &data, NULL); m->char_id = atoi(data); 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, 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, 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, 5, &data, NULL); m->online = (atoi(data) ? 1 : 0);
Sql_GetData(sql_handle, 6, &data, NULL); m->class_ = atoi(data); 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); m->leader = (m->account_id == leader_id && m->char_id == leader_char ? 1 : 0);
@ -301,7 +300,7 @@ std::shared_ptr<struct party_data> search_partyname( char* str ){
int party_check_family_share( std::shared_ptr<struct party_data> p ){ int party_check_family_share( std::shared_ptr<struct party_data> p ){
int i; int i;
unsigned short map = 0; const char* map = nullptr;
if (!p->family) if (!p->family)
return 0; return 0;
for (i = 0; i < MAX_PARTY; i++) { for (i = 0; i < MAX_PARTY; i++) {
@ -311,6 +310,10 @@ int party_check_family_share( std::shared_ptr<struct party_data> p ){
} }
} }
if( map == nullptr ){
return 0;
}
for (i = 0; i < MAX_PARTY; i++) { for (i = 0; i < MAX_PARTY; i++) {
struct party_member * mem = &(p->party.member[i]); struct party_member * mem = &(p->party.member[i]);
if (mem->lv == 0) if (mem->lv == 0)
@ -322,7 +325,7 @@ int party_check_family_share( std::shared_ptr<struct party_data> p ){
//everyone should be online to share //everyone should be online to share
return 0; return 0;
} }
if (mem->map != map) { if( strncmp( mem->map, map, sizeof( mem->map ) ) != 0 ){
//everyone should be on the same map //everyone should be on the same map
return 0; return 0;
} }
@ -455,16 +458,18 @@ int mapif_party_withdraw(int party_id, uint32 account_id, uint32 char_id, char *
//Party map update notification //Party map update notification
int mapif_party_membermoved(struct party *p,int idx) 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; WBUFW(buf,0) = 0x3825;
WBUFL(buf,2) = p->party_id; WBUFL(buf,2) = p->party_id;
WBUFL(buf,6) = p->member[idx].account_id; WBUFL(buf,6) = p->member[idx].account_id;
WBUFL(buf,10) = p->member[idx].char_id; WBUFL(buf,10) = p->member[idx].char_id;
WBUFW(buf,14) = p->member[idx].map; WBUFB(buf,14) = p->member[idx].online;
WBUFB(buf,16) = p->member[idx].online; WBUFW(buf,15) = p->member[idx].lv;
WBUFW(buf,17) = p->member[idx].lv; safestrncpy( WBUFCP( buf, 17 ), p->member[idx].map, sizeof( p->member[idx].map ) );
chmapif_sendall(buf, 19);
chmapif_sendall( buf, sizeof( buf ) );
return 0; return 0;
} }
@ -679,8 +684,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_
return 0; return 0;
} }
// When member goes to other map or levels up. // 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; int i;
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id ); std::shared_ptr<struct party_data> 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. //since they do nothing with it.
} }
if (p->party.member[i].map != map) { if( strncmp( p->party.member[i].map, map, sizeof( p->party.member[i].map ) ) != 0 ){
p->party.member[i].map = map; safestrncpy( p->party.member[i].map, map, sizeof( p->party.member[i].map ) );
mapif_party_membermoved(&p->party, i); mapif_party_membermoved(&p->party, i);
int_party_check_lv(p); 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 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 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 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 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 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; case 0x3029: mapif_parse_PartyLeaderChange(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;

View File

@ -58,7 +58,7 @@ unsigned int party_share_level = 10;
int inter_recv_packet_length[] = { 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- -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- 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, 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, 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] -1,-1,10,10, 0,-1,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]

View File

@ -363,6 +363,11 @@ struct point {
uint16 x,y; uint16 x,y;
}; };
struct s_point_str{
char map[MAP_NAME_LENGTH_EXT];
uint16 x,y;
};
struct startitem { struct startitem {
t_itemid nameid; t_itemid nameid;
unsigned short amount; unsigned short amount;
@ -589,7 +594,9 @@ struct mmo_charstatus {
uint32 mapip; uint32 mapip;
uint16 mapport; 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_skill skill[MAX_SKILL];
struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex] struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
@ -684,7 +691,7 @@ struct party_member {
uint32 char_id; uint32 char_id;
char name[NAME_LENGTH]; char name[NAME_LENGTH];
unsigned short class_; unsigned short class_;
unsigned short map; char map[MAP_NAME_LENGTH_EXT];
unsigned short lv; unsigned short lv;
unsigned leader : 1, unsigned leader : 1,
online : 1; online : 1;

View File

@ -962,13 +962,13 @@ ACMD_FUNC(save)
/*========================================== /*==========================================
* *
*------------------------------------------*/ *------------------------------------------*/
ACMD_FUNC(load) ACMD_FUNC(load){
{
int16 m;
nullpo_retr(-1, sd); 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)) { 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. clif_displaymessage(fd, msg_txt(sd,249)); // You are not authorized to warp to your save map.
return -1; return -1;
@ -978,7 +978,7 @@ ACMD_FUNC(load)
return -1; 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.. clif_displaymessage(fd, msg_txt(sd,7)); // Warping to save point..
return 0; return 0;
@ -2580,8 +2580,8 @@ ACMD_FUNC(memo)
clif_displaymessage(sd->fd, msg_txt(sd,668)); // Your actual memo positions are: clif_displaymessage(sd->fd, msg_txt(sd,668)); // Your actual memo positions are:
for( i = 0; i < MAX_MEMOPOINTS; i++ ) for( i = 0; i < MAX_MEMOPOINTS; i++ )
{ {
if( sd->status.memo_point[i].map ) if( strcmp( "", sd->status.memo_point[i].map ) != 0 )
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); 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 else
sprintf(atcmd_output, msg_txt(sd,171), i); // %d - void sprintf(atcmd_output, msg_txt(sd,171), i); // %d - void
clif_displaymessage(sd->fd, atcmd_output); clif_displaymessage(sd->fd, atcmd_output);

View File

@ -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()); this->invalidWarning(location["Map"], "Invalid battleground map name %s, skipping.\n", map_name.c_str());
return 0; return 0;
} }
if( map_mapindex2mapid( map_entry.mapindex ) < 0 ){
// Ignore silently, the map is on another mapserver
return 0;
}
} }
if (this->nodeExists(location, "StartEvent")) { 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)) 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); pc_setpos(sd, member->entry_point.map, member->entry_point.x, member->entry_point.y, CLR_TELEPORT);
else 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); bgteam->members.erase(member);
break; break;

View File

@ -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 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 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 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 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 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' //2af8: Outgoing, chrif_connect -> 'connect to charserver / auth @ charserver'
//2af9: Incoming, chrif_connectack -> 'answer of the 2af8 login(ok / fail)' //2af9: Incoming, chrif_connectack -> 'answer of the 2af8 login(ok / fail)'
//2afa: Outgoing, chrif_sendmap -> 'sending our maps' //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. //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' //2afd: Incoming, chrif_authok -> 'client authentication ok'
//2afe: Outgoing, send_usercount_tochar -> 'sends player count of this map server to charserver' //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; 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. 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 // Copy the whole status into the packet
if( map_getmapdata(sd->bl.m)->instance_id ){ memcpy( WFIFOP( char_fd, 13 ), &sd->status, sizeof( struct mmo_charstatus ) );
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 ) );
}
WFIFOSET(char_fd, WFIFOW(char_fd,2)); WFIFOSET(char_fd, WFIFOW(char_fd,2));
@ -380,11 +368,11 @@ int chrif_sendmap(int fd) {
ShowStatus("Sending maps to char server...\n"); ShowStatus("Sending maps to char server...\n");
// Sending normal maps, not instances // Sending normal maps, not instances
WFIFOHEAD(fd, 4 + instance_start * 4); WFIFOHEAD( fd, 4 + instance_start * MAP_NAME_LENGTH_EXT );
WFIFOW(fd,0) = 0x2afa; WFIFOW(fd,0) = 0x2afa;
for (int i = 0; i < instance_start; i++) for (int i = 0; i < instance_start; i++)
WFIFOW(fd, 4 + i * 4) = map[i].index; safestrncpy( WFIFOCP( fd, 4 + i * MAP_NAME_LENGTH_EXT ), map[i].name, MAP_NAME_LENGTH_EXT );
WFIFOW(fd, 2) = 4 + instance_start * 4; WFIFOW( fd, 2 ) = 4 + instance_start * MAP_NAME_LENGTH_EXT;
WFIFOSET(fd, WFIFOW(fd, 2)); WFIFOSET(fd, WFIFOW(fd, 2));
return 0; return 0;
@ -396,8 +384,8 @@ int chrif_recvmap(int fd) {
uint32 ip = ntohl(RFIFOL(fd,4)); uint32 ip = ntohl(RFIFOL(fd,4));
uint16 port = ntohs(RFIFOW(fd,8)); uint16 port = ntohs(RFIFOW(fd,8));
for(i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) { for( i = 10, j = 0; i < RFIFOW( fd, 2 ); i += MAP_NAME_LENGTH_EXT, j++ ){
map_setipport(RFIFOW(fd,i), ip, port); map_setipport( mapindex_name2id( RFIFOCP( fd, i ) ), ip, port );
} }
if (battle_config.etc_log) if (battle_config.etc_log)
@ -414,8 +402,9 @@ int chrif_removemap(int fd) {
uint32 ip = RFIFOL(fd,4); uint32 ip = RFIFOL(fd,4);
uint16 port = RFIFOW(fd,8); uint16 port = RFIFOW(fd,8);
for(i = 10, j = 0; i < RFIFOW(fd, 2); i += 4, j++) for( i = 10, j = 0; i < RFIFOW( fd, 2 ); i += MAP_NAME_LENGTH_EXT, j++ ){
map_eraseipport(RFIFOW(fd, i), ip, port); map_eraseipport( mapindex_name2id( RFIFOCP( fd, i ) ), ip, port );
}
other_mapserver_count--; other_mapserver_count--;
@ -441,28 +430,29 @@ int chrif_changemapserver(map_session_data* sd, uint32 ip, uint16 port) {
chrif_check(-1); chrif_check(-1);
WFIFOHEAD(char_fd,39); WFIFOHEAD( char_fd, 37 + MAP_NAME_LENGTH_EXT );
WFIFOW(char_fd, 0) = 0x2b05; WFIFOW(char_fd, 0) = 0x2b05;
WFIFOL(char_fd, 2) = sd->bl.id; WFIFOL(char_fd, 2) = sd->bl.id;
WFIFOL(char_fd, 6) = sd->login_id1; WFIFOL(char_fd, 6) = sd->login_id1;
WFIFOL(char_fd,10) = sd->login_id2; WFIFOL(char_fd,10) = sd->login_id2;
WFIFOL(char_fd,14) = sd->status.char_id; WFIFOL(char_fd,14) = sd->status.char_id;
WFIFOW(char_fd,18) = sd->mapindex; safestrncpy( WFIFOCP( char_fd, 18 ), mapindex_id2name( sd->mapindex ), MAP_NAME_LENGTH_EXT );
WFIFOW(char_fd,20) = sd->bl.x; int offset = 18 + MAP_NAME_LENGTH_EXT;
WFIFOW(char_fd,22) = sd->bl.y; WFIFOW( char_fd, offset + 0 ) = sd->bl.x;
WFIFOL(char_fd,24) = htonl(ip); WFIFOW( char_fd, offset + 2 ) = sd->bl.y;
WFIFOW(char_fd,28) = htons(port); WFIFOL( char_fd, offset + 4 ) = htonl( ip );
WFIFOB(char_fd,30) = sd->status.sex; WFIFOW( char_fd, offset + 8 ) = htons( port );
WFIFOL(char_fd,31) = htonl(session[sd->fd]->client_addr); WFIFOB( char_fd, offset + 10 ) = sd->status.sex;
WFIFOL(char_fd,35) = sd->group_id; WFIFOL( char_fd, offset + 11 ) = htonl( session[sd->fd]->client_addr );
WFIFOSET(char_fd,39); WFIFOL( char_fd, offset + 15 ) = sd->group_id;
WFIFOSET( char_fd, 37 + MAP_NAME_LENGTH_EXT );
return 0; return 0;
} }
/// map-server change (mapserv) request acknowledgement (positive or negative) /// map-server change (mapserv) request acknowledgement (positive or negative)
/// R 2b06 <account_id>.L <login_id1>.L <login_id2>.L <char_id>.L <map_index>.W <x>.W <y>.W <ip>.L <port>.W /// R 2b06 <account_id>.L <login_id1>.L <login_id2>.L <char_id>.L <map>.16B <x>.W <y>.W <ip>.L <port>.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) { 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; struct auth_node *node;
if ( !( node = chrif_auth_check(account_id, char_id, ST_MAPCHANGE) ) ) 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); clif_authfail_fd(node->fd, 0);
chrif_char_offline(node->sd); chrif_char_offline(node->sd);
} else } 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] //Player has been saved already, remove him from memory. [Skotlex]
chrif_auth_delete(account_id, char_id, ST_MAPCHANGE); 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 * Maps are sent, then received misc info from char-server
* - Server name * - Server name
* - Default map
* HZ 0x2afb * HZ 0x2afb
**/ **/
int chrif_sendmapack(int fd) { int chrif_sendmapack(int fd) {
@ -592,19 +581,11 @@ int chrif_sendmapack(int fd) {
// Whisper name // Whisper name
safestrncpy( wisp_server_name, RFIFOCP( fd, offs ), NAME_LENGTH ); 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 // 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 ); 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(); chrif_on_ready();
return 0; return 0;
@ -1784,7 +1765,7 @@ int chrif_parse(int fd) {
case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break; case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break; case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break;
case 0x2b04: chrif_recvmap(fd); 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 0x2b09: map_addnickdb(RFIFOL(fd,2), RFIFOCP(fd,6)); break;
case 0x2b0b: chrif_skillcooldown_load(fd); break; case 0x2b0b: chrif_skillcooldown_load(fd); break;
case 0x2b0d: chrif_changedsex(fd); break; case 0x2b0d: chrif_changedsex(fd); break;

View File

@ -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. /// Notifies the client of a position change to coordinates on given map, which is on another map-server.
/// 0092 <map name>.16B <x>.W <y>.W <ip>.L <port>.W (ZC_NPCACK_SERVERMOVE) /// 0092 <map name>.16B <x>.W <y>.W <ip>.L <port>.W (ZC_NPCACK_SERVERMOVE)
/// 0ac7 <map name>.16B <x>.W <y>.W <ip>.L <port>.W <unknown>.128B (ZC_NPCACK_SERVERMOVE2) /// 0ac7 <map name>.16B <x>.W <y>.W <ip>.L <port>.W <unknown>.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; int fd;
#if PACKETVER >= 20170315 #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)); WFIFOHEAD(fd,packet_len(cmd));
WFIFOW(fd,0) = 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,18) = x;
WFIFOW(fd,20) = y; WFIFOW(fd,20) = y;
WFIFOL(fd,22) = htonl(ip); 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). /// Presents a list of available warp destinations (ZC_WARPLIST).
/// 011c <skill id>.W { <map name>.16B }*4 /// 011c <skill id>.W { <map name>.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; int fd;
nullpo_retv(sd); nullpo_retv(sd);
fd = sd->fd; 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,0) = 0x11c;
WFIFOW(fd,2) = skill_id; WFIFOW(fd,2) = skill_id;
memset(WFIFOP(fd,4), 0x00, 4*MAP_NAME_LENGTH_EXT); memset(WFIFOP(fd,4), 0x00, 4*MAP_NAME_LENGTH_EXT);
if (map1 == (unsigned short)-1) strcpy(WFIFOCP(fd,4), "Random"); if( strcmp( "", map1 ) != 0 ){
else // normal map name mapindex_getmapname_ext( map1, WFIFOCP( fd, 4 ) );
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( strcmp( "", map2 ) != 0 ){
if (map3 > 0) mapindex_getmapname_ext(mapindex_id2name(map3), WFIFOCP(fd,36)); mapindex_getmapname_ext( map2, WFIFOCP( fd, 20 ) );
if (map4 > 0) mapindex_getmapname_ext(mapindex_id2name(map4), WFIFOCP(fd,52)); }
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)); WFIFOSET(fd,packet_len(0x11c));
sd->menuskill_id = skill_id; 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; member.GID = m.char_id;
#endif #endif
safestrncpy( member.playerName, m.name, sizeof( member.playerName ) ); 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.leader = ( m.leader ) ? 0 : 1;
member.offline = ( m.online ) ? 0 : 1; member.offline = ( m.online ) ? 0 : 1;
#if PACKETVER_MAIN_NUM >= 20170524 || PACKETVER_RE_NUM >= 20170502 || defined(PACKETVER_ZERO) #if PACKETVER_MAIN_NUM >= 20170524 || PACKETVER_RE_NUM >= 20170502 || defined(PACKETVER_ZERO)

View File

@ -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_walkok(map_session_data *sd); // self
void clif_move(struct unit_data *ud); //area void clif_move(struct unit_data *ud); //area
void clif_changemap(map_session_data *sd, short m, int x, int y); //self 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_blown(struct block_list *bl); // area
void clif_slide(struct block_list *bl, int x, int y); // area void clif_slide(struct block_list *bl, int x, int y); // area
void clif_fixpos(struct block_list *bl); // 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); 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_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_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_memomessage(map_session_data* sd, int type);
void clif_skill_teleportmessage(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); void clif_skill_produce_mix_list(map_session_data *sd, int skill_id, int trigger);

View File

@ -299,7 +299,7 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) {
uint16 mapindex = mapindex_name2idx(map_name.c_str(), nullptr); 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()); this->invalidWarning(node["Map"], "Map %s doesn't exist, skipping.\n", map_name.c_str());
return 0; return 0;
} }
@ -394,7 +394,8 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) {
map_data* md = map_getmapdata( map_mapindex2mapid( gc->mapindex ) ); 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 ); this->invalidWarning( node["WarpX"], "WarpX has to be smaller than %hu.\n", md->xs );
return 0; return 0;
} }
@ -420,7 +421,8 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) {
map_data* md = map_getmapdata( map_mapindex2mapid( gc->mapindex ) ); 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 ); this->invalidWarning( node["WarpY"], "WarpY has to be smaller than %hu.\n", md->ys );
return 0; 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) { if (g->instance_id) {
struct map_data *mapdata = map_getmapdata(sd->bl.m); struct map_data *mapdata = map_getmapdata(sd->bl.m);
if (mapdata->instance_id) { // User was on the instance map // User was on the instance map of the guild
if (mapdata->save.map) if( g->instance_id == mapdata->instance_id ){
pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, CLR_TELEPORT); pc_setpos_savepoint( *sd );
else
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
} }
} }

View File

@ -167,14 +167,21 @@ uint64 InstanceDatabase::parseBodyNode(const ryml::NodeRef& node) {
if (!this->asString(enterNode, "Map", map)) if (!this->asString(enterNode, "Map", map))
return 0; 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()); this->invalidWarning(enterNode["Map"], "Map %s is not a valid map, skipping.\n", map.c_str());
return 0; 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")) { if (this->nodeExists(enterNode, "X")) {

View File

@ -37,7 +37,7 @@
static const int packet_len_table[] = { 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 -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 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 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,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] -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 } else
mapindex = sd->mapindex; mapindex = sd->mapindex;
WFIFOHEAD(inter_fd,19); WFIFOHEAD( inter_fd, 17 + MAP_NAME_LENGTH_EXT );
WFIFOW(inter_fd,0)=0x3025; WFIFOW(inter_fd,0)=0x3025;
WFIFOL(inter_fd,2)=sd->status.party_id; WFIFOL(inter_fd,2)=sd->status.party_id;
WFIFOL(inter_fd,6)=sd->status.account_id; WFIFOL(inter_fd,6)=sd->status.account_id;
WFIFOL(inter_fd,10)=sd->status.char_id; WFIFOL(inter_fd,10)=sd->status.char_id;
WFIFOW(inter_fd,14)=mapindex; WFIFOB(inter_fd,14)=online;
WFIFOB(inter_fd,16)=online; WFIFOW(inter_fd,15)=sd->status.base_level;
WFIFOW(inter_fd,17)=sd->status.base_level; safestrncpy( WFIFOCP( inter_fd, 17 ), mapindex_id2name( mapindex ), MAP_NAME_LENGTH_EXT );
WFIFOSET(inter_fd,19); WFIFOSET( inter_fd, 17 + MAP_NAME_LENGTH_EXT );
return 1; return 1;
} }
@ -1628,7 +1628,7 @@ int intif_parse_PartyBroken(int fd)
*/ */
int intif_parse_PartyMove(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; return 1;
} }

View File

@ -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 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 console = 0;
int enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex] 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] 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); 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) if (sd->state.vending)
idb_remove(vending_getdb(), sd->status.char_id); 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, bl);
nullpo_retr(0, sd = (map_session_data *)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; 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 MSG_CONF_NAME_THA = "conf/msg_conf/map_msg_tha.conf"; // Thai
/* Multilanguage */ /* Multilanguage */
// Default map
safestrncpy(map_default.mapname, "prontera", MAP_NAME_LENGTH);
map_default.x = 156;
map_default.y = 191;
// default inter_config // default inter_config
inter_config.start_status_points = 48; inter_config.start_status_points = 48;
inter_config.emblem_woe_change = true; inter_config.emblem_woe_change = true;

View File

@ -1051,13 +1051,6 @@ extern char channel_conf[];
extern char wisp_server_name[]; 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' /// Type of 'save_settings'
enum save_settings_type { enum save_settings_type {
CHARSAVE_NONE = 0x000, /// Never CHARSAVE_NONE = 0x000, /// Never

View File

@ -46,7 +46,7 @@ static void party_fill_member(struct party_member* member, map_session_data* sd,
member->char_id = sd->status.char_id; member->char_id = sd->status.char_id;
safestrncpy(member->name, sd->status.name, NAME_LENGTH); safestrncpy(member->name, sd->status.name, NAME_LENGTH);
member->class_ = sd->status.class_; 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->lv = sd->status.base_level;
member->online = 1; member->online = 1;
member->leader = leader; 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] clif_name_area(&sd->bl); //Update name display [Skotlex]
//TODO: hp bars should be cleared too //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); struct map_data *mapdata = map_getmapdata(sd->bl.m);
if( mapdata->instance_id ) { // User was on the instance map // User was on the instance map of the party
if( mapdata->save.map ) if( mapdata != nullptr && p->instance_id == mapdata->instance_id ){
pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, CLR_TELEPORT); pc_setpos_savepoint( *sd );
else
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
} }
} }
} }
@ -918,7 +916,7 @@ int party_changeleader(map_session_data *sd, map_session_data *tsd, struct party
if (tmi == MAX_PARTY) if (tmi == MAX_PARTY)
return 0; // Shouldn't happen 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); clif_msg(sd, PARTY_MASTER_CHANGE_SAME_MAP);
return 0; return 0;
} }
@ -953,8 +951,7 @@ int party_changeleader(map_session_data *sd, map_session_data *tsd, struct party
/// - changes maps /// - changes maps
/// - logs in or out /// - logs in or out
/// - gains a level (disabled) /// - 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_member* m;
struct party_data* p; struct party_data* p;
int i; 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 = &p->party.member[i];
m->map = map_idx; safestrncpy( m->map, map, sizeof( m->map ) );
m->online = online; m->online = online;
m->lv = lv; m->lv = lv;
//Check if they still exist on this map server //Check if they still exist on this map server

View File

@ -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) #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_noinfo(int party_id, uint32 char_id);
int party_recv_info(struct party* sp, 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_broken(int party_id);
int party_optionchanged(int party_id,uint32 account_id,int exp,int item,int flag); 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); int party_changeoption(map_session_data *sd,int exp,int item);

View File

@ -1315,31 +1315,51 @@ void pc_makesavestatus(map_session_data *sd) {
sd->status.sp = sd->battle_status.sp; sd->status.sp = sd->battle_status.sp;
sd->status.ap = sd->battle_status.ap; 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.x = sd->bl.x;
sd->status.last_point.y = sd->bl.y; sd->status.last_point.y = sd->bl.y;
return; return;
} }
if(pc_isdead(sd)) { if( pc_isdead( sd ) ){
pc_setrestartvalue(sd, 0); pc_setrestartvalue( sd, 0 );
memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
} else { // 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.hp = sd->battle_status.hp;
sd->status.sp = sd->battle_status.sp; sd->status.sp = sd->battle_status.sp;
sd->status.ap = sd->battle_status.ap; 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) // If saving is not allowed on the map, we return the player to the designated point
memcpy(&sd->status.last_point,&mapdata->save,sizeof(sd->status.last_point)); if( mapdata->flag[MF_NOSAVE] ){
else // The map has a specific return point
memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_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; sd->vars_received = 0x0;
//warp player //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 ){ 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) // try warping to a default map instead (church graveyard)
if (pc_setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != SETPOS_OK) { 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; 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. * Warp player sd to random location on current map.
* May fail if no walkable cell found (1000 attempts). * 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 ) if( pos == -1 )
{ {
uint8 i; uint8 i;
const char* mapname = map_mapid2mapname( sd->bl.m );
// prevent memo-ing the same map multiple times // 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) ); 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 point)); memmove( &sd->status.memo_point[1], &sd->status.memo_point[0], ( u8min( i, MAX_MEMOPOINTS - 1 ) ) * sizeof( struct s_point_str ) );
pos = 0; pos = 0;
} }
@ -6966,7 +6998,7 @@ bool pc_memo(map_session_data* sd, int pos)
return false; 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].x = sd->bl.x;
sd->status.memo_point[pos].y = sd->bl.y; 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_setstand(sd, true);
pc_setrestartvalue(sd,3); 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. clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
}
} }
static TIMER_FUNC(pc_respawn_timer){ 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); 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.x = x;
sd->status.save_point.y = y; sd->status.save_point.y = y;
} }

View File

@ -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(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); 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); char pc_randomwarp(map_session_data *sd,clr_type type,bool ignore_mapflag = false);
bool pc_memo(map_session_data* sd, int pos); bool pc_memo(map_session_data* sd, int pos);

View File

@ -5612,7 +5612,7 @@ BUILDIN_FUNC(warp)
if(strcmp(str,"Random")==0) if(strcmp(str,"Random")==0)
ret = pc_randomwarp(sd,CLR_TELEPORT,true); ret = pc_randomwarp(sd,CLR_TELEPORT,true);
else if(strcmp(str,"SavePoint")==0 || strcmp(str,"Save")==0) 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 else
ret = pc_setpos(sd,mapindex_name2id(str),x,y,CLR_OUTSIGHT); ret = pc_setpos(sd,mapindex_name2id(str),x,y,CLR_OUTSIGHT);
@ -5851,11 +5851,11 @@ BUILDIN_FUNC(warpparty)
break; break;
case WARPPARTY_SAVEPOINTALL: case WARPPARTY_SAVEPOINTALL:
if (!mapdata->flag[MF_NORETURN]) 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; break;
case WARPPARTY_SAVEPOINT: case WARPPARTY_SAVEPOINT:
if (!mapdata->flag[MF_NORETURN]) 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; break;
case WARPPARTY_LEADER: case WARPPARTY_LEADER:
if (p->party.member[i].leader) if (p->party.member[i].leader)
@ -5957,11 +5957,11 @@ BUILDIN_FUNC(warpguild)
break; break;
case 1: // SavePointAll case 1: // SavePointAll
if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN)) 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; break;
case 2: // SavePoint case 2: // SavePoint
if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN)) 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; break;
case 3: // m,x,y 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))) 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 1: script_pushint(st,p->party.member[i].account_id); break;
case 2: script_pushint(st,p->party.member[i].char_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 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; case 5: script_pushint(st,p->party.member[i].lv); break;
default: script_pushstrcopy(st,p->party.member[i].name); break; default: script_pushstrcopy(st,p->party.member[i].name); break;
} }
@ -13126,7 +13126,7 @@ BUILDIN_FUNC(warpwaitingpc)
if( strcmp(map_name,"Random") == 0 ) if( strcmp(map_name,"Random") == 0 )
pc_randomwarp(sd,CLR_TELEPORT,true); pc_randomwarp(sd,CLR_TELEPORT,true);
else if( strcmp(map_name,"SavePoint") == 0 ) 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 else
pc_setpos(sd, mapindex_name2id(map_name), x, y, CLR_OUTSIGHT); 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 != g_id && flag&2) || //Warp out outsiders
(sd->status.guild_id == 0 && flag&2) // Warp out players not in guild (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; return 1;
} }
@ -15506,7 +15506,7 @@ int atcommand_sub(struct script_state* st,int type) {
memcpy(&dummy_sd.bl, bl, sizeof(struct block_list)); memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
if (bl->type == BL_NPC) if (bl->type == BL_NPC)
safestrncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH); 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 // Init Group ID, Level, & permissions
@ -16090,7 +16090,7 @@ BUILDIN_FUNC(getsavepoint)
type = script_getnum(st,2); type = script_getnum(st,2);
switch(type) { 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 1: script_pushint(st,sd->status.save_point.x); break;
case 2: script_pushint(st,sd->status.save_point.y); break; case 2: script_pushint(st,sd->status.save_point.y); break;
default: default:

View File

@ -9057,15 +9057,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( skill_lv == 1 ) if( skill_lv == 1 )
pc_randomwarp(sd,CLR_TELEPORT); pc_randomwarp(sd,CLR_TELEPORT);
else 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; break;
} }
clif_skill_nodamage(src,bl,skill_id,skill_lv,1); clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
if( skill_lv == 1 && skill_id != ALL_ODINS_RECALL ) 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 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 } else
unit_warp(bl,-1,-1,-1,CLR_TELEPORT); unit_warp(bl,-1,-1,-1,CLR_TELEPORT);
break; break;
@ -13604,9 +13604,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
if(sd) if(sd)
{ {
clif_skill_warppoint(sd, skill_id, skill_lv, sd->status.save_point.map, 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 >= 2) ? sd->status.memo_point[0].map : "",
(skill_lv >= 3) ? sd->status.memo_point[1].map : 0, (skill_lv >= 3) ? sd->status.memo_point[1].map : "",
(skill_lv >= 4) ? sd->status.memo_point[2].map : 0 (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. 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) if(strcmp(mapname,"Random") == 0)
pc_randomwarp(sd,CLR_TELEPORT); pc_randomwarp(sd,CLR_TELEPORT);
else if (sd->menuskill_val > 1 || skill_id == ALL_ODINS_RECALL) //Need lv2 to be able to warp here. 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); clif_refresh_storagewindow(sd);
break; break;
case AL_WARP: case AL_WARP:
{ {
const struct point *p[4]; const struct s_point_str *p[4];
std::shared_ptr<s_skill_unit_group> group; std::shared_ptr<s_skill_unit_group> group;
int i, lv, wx, wy; int i, lv, wx, wy;
int maxcount=0; 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 if( lv > 4 ) lv = 4; // crash prevention
// check if the chosen map exists in the memo list // 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 ) { if( i < lv ) {
x=p[i]->x; x=p[i]->x;
y=p[i]->y; y=p[i]->y;

View File

@ -11305,7 +11305,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
val3 = map_idx; val3 = map_idx;
val4 = pos; val4 = pos;
} else if (!val3 || val3 == sd->mapindex) { // Use save point. } 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) val4 = (sd->status.save_point.x&0xFFFF)
|(sd->status.save_point.y<<16); |(sd->status.save_point.y<<16);
} }