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->job_level != cp->job_level) || (p->job_exp != cp->job_exp) ||
(p->zeny != cp->zeny) ||
(p->last_point.map != cp->last_point.map) ||
( strncmp( p->last_point.map, cp->last_point.map, sizeof( p->last_point.map ) ) != 0 ) ||
(p->last_point.x != cp->last_point.x) || (p->last_point.y != cp->last_point.y) ||
( strncmp( p->save_point.map, cp->save_point.map, sizeof( p->save_point.map ) ) != 0 ) ||
( p->save_point.x != cp->save_point.x ) || ( p->save_point.y != cp->save_point.y ) ||
(p->max_hp != cp->max_hp) || (p->hp != cp->hp) ||
(p->max_sp != cp->max_sp) || (p->sp != cp->sp) ||
(p->status_point != cp->status_point) || (p->skill_point != cp->skill_point) ||
@ -316,8 +318,8 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
p->str, p->agi, p->vit, p->int_, p->dex, p->luk,
p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id, p->ele_id,
p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom,
mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
p->last_point.map, p->last_point.x, p->last_point.y,
p->save_point.map, p->save_point.x, p->save_point.y, p->rename,
(unsigned long)p->delete_date, // FIXME: platform-dependent size
p->robe, p->character_moves, p->font, p->uniqueitem_counter,
p->hotkey_rowshift, p->clan_id, p->title_id, p->show_equip, p->hotkey_rowshift2,
@ -390,11 +392,10 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
StringBuf_Printf(&buf, "INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ", schema_config.memo_db);
for( i = 0, count = 0; i < MAX_MEMOPOINTS; ++i )
{
if( p->memo_point[i].map )
{
if( strcmp( "", p->memo_point[i].map ) != 0 ){
if( count )
StringBuf_AppendStr(&buf, ",");
Sql_EscapeString(sql_handle, esc_mapname, mapindex_id2name(p->memo_point[i].map));
Sql_EscapeString( sql_handle, esc_mapname, p->memo_point[i].map );
StringBuf_Printf(&buf, "('%d', '%s', '%d', '%d')", char_id, esc_mapname, p->memo_point[i].x, p->memo_point[i].y);
++count;
}
@ -910,7 +911,6 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
SqlStmt* stmt;
struct mmo_charstatus p;
int j = 0, i;
char last_map[MAP_NAME_LENGTH_EXT];
char sex[2];
stmt = SqlStmt_Malloc(sql_handle);
@ -970,7 +970,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p.head_top, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_STRING, &p.last_point.map, sizeof(p.last_point.map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p.rename, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p.robe, 0, NULL, NULL)
@ -1004,7 +1004,6 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SqlStmt_NextRow(stmt); i++ )
{
p.last_point.map = mapindex_name2id(last_map);
sd->found_char[p.slot] = p.char_id;
sd->unban_time[p.slot] = p.unban_time;
p.sex = char_mmo_gender(sd, &p, sex[0]);
@ -1029,10 +1028,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything) {
int i;
SqlStmt* stmt;
char last_map[MAP_NAME_LENGTH_EXT];
char save_map[MAP_NAME_LENGTH_EXT];
char point_map[MAP_NAME_LENGTH_EXT];
struct point tmp_point;
struct s_point_str tmp_point;
struct s_skill tmp_skill;
uint16 skill_count = 0;
struct s_friend tmp_friend;
@ -1106,10 +1102,10 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_STRING, &p->last_point.map, sizeof(p->last_point.map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_STRING, &p->save_point.map, sizeof(p->save_point.map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_UINT32, &p->partner_id, 0, NULL, NULL)
@ -1155,20 +1151,6 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
return 0;
}
p->sex = char_mmo_gender(NULL, p, sex[0]);
p->last_point.map = mapindex_name2id(last_map);
p->save_point.map = mapindex_name2id(save_map);
if( p->last_point.map == 0 ) {
p->last_point.map = mapindex_name2id(charserv_config.default_map);
p->last_point.x = charserv_config.default_map_x;
p->last_point.y = charserv_config.default_map_y;
}
if( p->save_point.map == 0 ) {
p->save_point.map = mapindex_name2id(charserv_config.default_map);
p->save_point.x = charserv_config.default_map_x;
p->save_point.y = charserv_config.default_map_y;
}
StringBuf_Init(&msg_buf);
StringBuf_AppendStr(&msg_buf, " status");
@ -1185,14 +1167,13 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`=? ORDER by `memo_id` LIMIT %d", schema_config.memo_db, MAX_MEMOPOINTS)
|| SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
|| SQL_ERROR == SqlStmt_Execute(stmt)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &point_map, sizeof(point_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &tmp_point.map, sizeof(tmp_point.map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_point.x, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_point.y, 0, NULL, NULL) )
SqlStmt_ShowDebug(stmt);
for( i = 0; i < MAX_MEMOPOINTS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
{
tmp_point.map = mapindex_name2id(point_map);
memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
}
StringBuf_AppendStr(&msg_buf, " memo");
@ -1426,7 +1407,7 @@ int char_check_char_name(char * name, char * esc_name)
int char_make_new_char( struct char_session_data* sd, char* name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short start_job, int sex ){
char name[NAME_LENGTH];
char esc_name[NAME_LENGTH*2+1];
struct point tmp_start_point[MAX_STARTPOINT];
struct s_point_str tmp_start_point[MAX_STARTPOINT];
struct startitem tmp_start_items[MAX_STARTITEM];
uint32 char_id;
int flag, k, start_point_idx = rnd() % charserv_config.start_point_count;
@ -1436,9 +1417,9 @@ int char_make_new_char( struct char_session_data* sd, char* name_, int str, int
normalize_name(name,TRIM_CHARS);
Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
memset(tmp_start_point, 0, MAX_STARTPOINT * sizeof(struct point));
memset( tmp_start_point, 0, sizeof( tmp_start_point ) );
memset(tmp_start_items, 0, MAX_STARTITEM * sizeof(struct startitem));
memcpy(tmp_start_point, charserv_config.start_point, MAX_STARTPOINT * sizeof(struct point));
memcpy( tmp_start_point, charserv_config.start_point, sizeof( tmp_start_point ) );
memcpy(tmp_start_items, charserv_config.start_items, MAX_STARTITEM * sizeof(struct startitem));
flag = char_check_char_name(name,esc_name);
@ -1524,9 +1505,9 @@ int char_make_new_char( struct char_session_data* sd, char* name_, int str, int
// Check for Doram based information.
if (start_job == JOB_SUMMONER) { // Check for just this job for now.
memset(tmp_start_point, 0, MAX_STARTPOINT * sizeof(struct point));
memset( tmp_start_point, 0, sizeof( tmp_start_point ) );
memset(tmp_start_items, 0, MAX_STARTITEM * sizeof(struct startitem));
memcpy(tmp_start_point, charserv_config.start_point_doram, MAX_STARTPOINT * sizeof(struct point));
memcpy( tmp_start_point, charserv_config.start_point_doram, sizeof( tmp_start_point ) );
memcpy(tmp_start_items, charserv_config.start_items_doram, MAX_STARTITEM * sizeof(struct startitem));
start_point_idx = rnd() % charserv_config.start_point_count_doram;
}
@ -1538,7 +1519,7 @@ int char_make_new_char( struct char_session_data* sd, char* name_, int str, int
"'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%u', '%u', '%u', '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%c')",
schema_config.char_db, sd->account_id , slot, esc_name, start_job, charserv_config.start_zeny, status_points, str, agi, vit, int_, dex, luk,
(40 * (100 + vit)/100) , (40 * (100 + vit)/100 ), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
mapindex_id2name(tmp_start_point[start_point_idx].map), tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, mapindex_id2name(tmp_start_point[start_point_idx].map), tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, sex) )
tmp_start_point[start_point_idx].map, tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, tmp_start_point[start_point_idx].map, tmp_start_point[start_point_idx].x, tmp_start_point[start_point_idx].y, sex ) )
{
Sql_ShowDebug(sql_handle);
return -2; //No, stop the procedure!
@ -1863,7 +1844,7 @@ int char_mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p){
info->hairColor = (uint8)u16min( p->hair_color, UINT8_MAX );
info->bIsChangedCharName = ( p->rename > 0 ) ? 0 : 1;
#if (PACKETVER >= 20100720 && PACKETVER <= 20100727) || PACKETVER >= 20100803
mapindex_getmapname_ext( mapindex_id2name( p->last_point.map ), info->mapName );
mapindex_getmapname_ext( p->last_point.map, info->mapName );
#endif
#if PACKETVER >= 20100803
#if PACKETVER_CHAR_DELETEDATE
@ -2114,18 +2095,20 @@ int char_loadName(uint32 char_id, char* name){
// Searches for the mapserver that has a given map (and optionally ip/port, if not -1).
// If found, returns the server's index in the 'server' array (otherwise returns -1).
int char_search_mapserver(unsigned short map, uint32 ip, uint16 port){
int char_search_mapserver( const std::string& map, uint32 ip, uint16 port ){
for(int i = 0; i < ARRAYLENGTH(map_server); i++)
{
if (session_isValid(map_server[i].fd)
&& (ip == (uint32)-1 || map_server[i].ip == ip)
&& (port == (uint16)-1 || map_server[i].port == port))
{
for (int j = 0; map_server[i].map[j]; j++)
if (map_server[i].map[j] == map)
for( std::string& m : map_server[i].maps ){
if( m == map ){
return i;
}
}
}
}
return -1;
}
@ -2774,13 +2757,13 @@ void char_set_defaults(){
charserv_config.char_check_db =1;
// See const.hpp to change the default values
charserv_config.start_point[0].map = mapindex_name2id(MAP_DEFAULT_NAME);
safestrncpy( charserv_config.start_point[0].map, MAP_DEFAULT_NAME, sizeof( charserv_config.start_point[0].map ) );
charserv_config.start_point[0].x = MAP_DEFAULT_X;
charserv_config.start_point[0].y = MAP_DEFAULT_Y;
charserv_config.start_point_count = 1;
#if PACKETVER >= 20151001
charserv_config.start_point_doram[0].map = mapindex_name2id(MAP_DEFAULT_NAME);
safestrncpy( charserv_config.start_point_doram[0].map, MAP_DEFAULT_NAME, sizeof( charserv_config.start_point_doram[0].map ) );
charserv_config.start_point_doram[0].x = MAP_DEFAULT_X;
charserv_config.start_point_doram[0].y = MAP_DEFAULT_Y;
charserv_config.start_point_count_doram = 1;
@ -2811,10 +2794,6 @@ void char_set_defaults(){
charserv_config.start_zeny = 0;
charserv_config.guild_exp_rate = 100;
safestrncpy(charserv_config.default_map, "prontera", MAP_NAME_LENGTH);
charserv_config.default_map_x = 156;
charserv_config.default_map_y = 191;
charserv_config.clan_remove_inactive_days = 14;
charserv_config.mail_return_days = 14;
charserv_config.mail_delete_days = 14;
@ -2836,8 +2815,7 @@ void char_set_defaults(){
* @param start: Start point reference
* @param count: Start point count reference
*/
void char_config_split_startpoint(char *w1_value, char *w2_value, struct point start_point[MAX_STARTPOINT], short *count)
{
void char_config_split_startpoint( char* w1_value, char* w2_value, struct s_point_str start_point[MAX_STARTPOINT], short* count ){
char *lineitem, **fields;
int i = 0, fields_length = 3 + 1;
@ -2857,16 +2835,9 @@ void char_config_split_startpoint(char *w1_value, char *w2_value, struct point s
continue;
}
start_point[i].map = mapindex_name2id(fields[1]);
if (!start_point[i].map) {
ShowError("Start point %s not found in map-index cache. Setting to default location.\n", fields[1]);
start_point[i].map = mapindex_name2id(MAP_DEFAULT_NAME);
start_point[i].x = MAP_DEFAULT_X;
start_point[i].y = MAP_DEFAULT_Y;
} else {
start_point[i].x = max(0, atoi(fields[2]));
start_point[i].y = max(0, atoi(fields[3]));
}
safestrncpy( start_point[i].map, fields[1], sizeof( start_point[i].map ) );
start_point[i].x = max( 0, atoi( fields[2] ) );
start_point[i].y = max( 0, atoi( fields[3] ) );
(*count)++;
lineitem = strtok(NULL, ":"); //next lineitem
@ -3098,12 +3069,6 @@ bool char_config_read(const char* cfgName, bool normal){
charserv_config.charmove_config.char_moves_unlimited = config_switch(w2);
} else if (strcmpi(w1, "char_checkdb") == 0) {
charserv_config.char_check_db = config_switch(w2);
} else if (strcmpi(w1, "default_map") == 0) {
safestrncpy(charserv_config.default_map, w2, MAP_NAME_LENGTH);
} else if (strcmpi(w1, "default_map_x") == 0) {
charserv_config.default_map_x = atoi(w2);
} else if (strcmpi(w1, "default_map_y") == 0) {
charserv_config.default_map_y = atoi(w2);
} else if (strcmpi(w1, "clan_remove_inactive_days") == 0) {
charserv_config.clan_remove_inactive_days = atoi(w2);
} else if (strcmpi(w1, "mail_return_days") == 0) {
@ -3176,7 +3141,6 @@ void CharacterServer::finalize(){
}
Sql_Free(sql_handle);
mapindex_final();
ShowStatus("Finished.\n");
}
@ -3191,9 +3155,6 @@ void CharacterServer::handle_shutdown(){
}
bool CharacterServer::initialize( int argc, char *argv[] ){
//Read map indexes
mapindex_init();
// Init default value
CHAR_CONF_NAME = "conf/char_athena.conf";
LAN_CONF_NAME = "conf/subnet_athena.conf";
@ -3295,8 +3256,6 @@ bool CharacterServer::initialize( int argc, char *argv[] ){
}
do_init_chcnslif();
mapindex_check_mapdefault(charserv_config.default_map);
ShowInfo("Default map: '" CL_WHITE "%s %d,%d" CL_RESET "'\n", charserv_config.default_map, charserv_config.default_map_x, charserv_config.default_map_y);
ShowStatus("The char-server is " CL_GREEN "ready" CL_RESET " (Server is listening on the port %d).\n\n", charserv_config.char_port);

View File

@ -186,7 +186,7 @@ struct CharServ_Config {
int log_inter; // loggin inter or not [devil]
int char_check_db; ///cheking sql-table at begining ?
struct point start_point[MAX_STARTPOINT], start_point_doram[MAX_STARTPOINT]; // Initial position the player will spawn on the server
struct s_point_str start_point[MAX_STARTPOINT], start_point_doram[MAX_STARTPOINT]; // Initial position the player will spawn on the server
short start_point_count, start_point_count_doram; // Number of positions read
struct startitem start_items[MAX_STARTITEM], start_items_doram[MAX_STARTITEM]; // Initial items the player with spawn with on the server
uint32 start_status_points;
@ -197,10 +197,6 @@ struct CharServ_Config {
int start_zeny;
int guild_exp_rate;
char default_map[MAP_NAME_LENGTH];
unsigned short default_map_x;
unsigned short default_map_y;
int clan_remove_inactive_days;
int mail_return_days;
int mail_delete_days;
@ -218,7 +214,7 @@ struct mmo_map_server {
uint32 ip;
uint16 port;
int users;
std::vector<uint16> map;
std::vector<std::string> maps;
};
extern struct mmo_map_server map_server[MAX_MAP_SERVERS];
@ -292,7 +288,7 @@ extern struct fame_list taekwon_fame_list[MAX_FAME_LIST];
#define DEFAULT_AUTOSAVE_INTERVAL 300*1000
#define MAX_CHAR_BUF sizeof( struct CHARACTER_INFO ) //Max size (for WFIFOHEAD calls)
int char_search_mapserver(unsigned short map, uint32 ip, uint16 port);
int char_search_mapserver( const std::string& map, uint32 ip, uint16 port );
int char_lan_subnetcheck(uint32 ip);
int char_count_users(void);

View File

@ -5,6 +5,7 @@
#include <memory>
#include <unordered_map>
#include <vector>
#include <stdlib.h>
#include <string.h>
@ -29,6 +30,15 @@
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
bool pincode_allowed( char* pincode );
#endif
@ -693,7 +703,7 @@ int chclif_parse_maplogin(int fd){
map_server[i].ip = ntohl(RFIFOL(fd,54));
map_server[i].port = ntohs(RFIFOW(fd,58));
map_server[i].users = 0;
map_server[i].map = {};
map_server[i].maps = {};
session[fd]->func_parse = chmapif_parse;
session[fd]->flag.server = 1;
realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
@ -796,7 +806,7 @@ void chclif_send_map_data( int fd, std::shared_ptr<struct mmo_charstatus> cd, ui
WFIFOHEAD(fd,size);
WFIFOW(fd,0) = cmd;
WFIFOL(fd,2) = cd->char_id;
mapindex_getmapname_ext(mapindex_id2name(cd->last_point.map), WFIFOCP(fd,6));
mapindex_getmapname_ext( cd->last_point.map, WFIFOCP( fd, 6 ) );
uint32 subnet_map_ip = char_lan_subnetcheck(ipl); // Advanced subnet check [LuzZza]
WFIFOL(fd,22) = htonl((subnet_map_ip) ? subnet_map_ip : map_server[map_server_index].ip);
WFIFOW(fd,26) = ntows(htons(map_server[map_server_index].port)); // [!] LE byte order here [!]
@ -817,7 +827,7 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){
int slot = RFIFOB(fd,2);
RFIFOSKIP(fd,3);
ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, session_isValid(map_server[server_id].fd) && !map_server[server_id].map.empty() );
ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, session_isValid(map_server[server_id].fd) && !map_server[server_id].maps.empty() );
// Map-server not available, tell the client to wait (client wont close, char select will respawn)
if (server_id == ARRAYLENGTH(map_server)) {
WFIFOHEAD(fd, 24);
@ -877,43 +887,35 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){
ShowInfo("Selected char: (Account %d: %d - %s)\n", sd->account_id, slot, char_dat.name);
// searching map server
i = char_search_mapserver(cd->last_point.map, -1, -1);
i = char_search_mapserver( cd->last_point.map, -1, -1 );
// if map is not found, we check major cities
if (i < 0 || !cd->last_point.map) {
if( i < 0 ){
unsigned short j;
//First check that there's actually a map server online.
ARR_FIND( 0, ARRAYLENGTH(map_server), j, session_isValid(map_server[j].fd) && !map_server[j].map.empty() );
ARR_FIND( 0, ARRAYLENGTH(map_server), j, session_isValid(map_server[j].fd) && !map_server[j].maps.empty() );
if (j == ARRAYLENGTH(map_server)) {
ShowInfo("Connection Closed. No map servers available.\n");
chclif_send_auth_result(fd,1); // 01 = Server closed
return 1;
}
if ((i = char_search_mapserver((j=mapindex_name2id(MAP_PRONTERA)),-1,-1)) >= 0) {
cd->last_point.x = 273;
cd->last_point.y = 354;
} else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_GEFFEN)),-1,-1)) >= 0) {
cd->last_point.x = 120;
cd->last_point.y = 100;
} else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_MORROC)),-1,-1)) >= 0) {
cd->last_point.x = 160;
cd->last_point.y = 94;
} else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_ALBERTA)),-1,-1)) >= 0) {
cd->last_point.x = 116;
cd->last_point.y = 57;
} else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_PAYON)),-1,-1)) >= 0) {
cd->last_point.x = 87;
cd->last_point.y = 117;
} else if ((i = char_search_mapserver((j=mapindex_name2id(MAP_IZLUDE)),-1,-1)) >= 0) {
cd->last_point.x = 94;
cd->last_point.y = 103;
} else {
ShowInfo("Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", mapindex_id2name(cd->last_point.map));
for( struct s_point_str& accessible_map : accessible_maps ){
i = char_search_mapserver( accessible_map.map, -1, -1 );
// Found a map-server for a map
if( i >= 0 ){
ShowWarning( "Unable to find map-server for '%s', sending to major city '%s'.\n", cd->last_point.map, accessible_map.map );
memcpy( &cd->last_point, &accessible_map, sizeof( cd->last_point ) );
break;
}
}
if( i < 0 ){
ShowInfo( "Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", cd->last_point.map );
chclif_send_auth_result(fd,1); // 01 = Server closed
return 1;
}
ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(cd->last_point.map), mapindex_id2name(j));
cd->last_point.map = j;
}
//Send NEW auth packet [Kevin]

View File

@ -823,7 +823,7 @@ void chlogif_on_ready(void)
chlogif_send_acc_tologin(INVALID_TIMER, gettick(), 0, 0);
// if no map-server already connected, display a message...
ARR_FIND( 0, ARRAYLENGTH(map_server), i, session_isValid(map_server[i].fd) && !map_server[i].map.empty() );
ARR_FIND( 0, ARRAYLENGTH(map_server), i, session_isValid(map_server[i].fd) && !map_server[i].maps.empty() );
if( i == ARRAYLENGTH(map_server) )
ShowStatus("Awaiting maps from map-server.\n");
}

View File

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

View File

@ -11,7 +11,6 @@
#include "../common/cbasetypes.hpp"
#include "../common/malloc.hpp"
#include "../common/mapindex.hpp"
#include "../common/mmo.hpp"
#include "../common/showmsg.hpp"
#include "../common/socket.hpp"
@ -244,7 +243,7 @@ std::shared_ptr<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, 2, &data, &len); memcpy(m->name, data, zmin(len, NAME_LENGTH));
Sql_GetData(sql_handle, 3, &data, NULL); m->lv = atoi(data);
Sql_GetData(sql_handle, 4, &data, NULL); m->map = mapindex_name2id(data);
Sql_GetData(sql_handle, 4, &data, &len); memcpy(m->map, data, zmin(len, sizeof(m->map)));
Sql_GetData(sql_handle, 5, &data, NULL); m->online = (atoi(data) ? 1 : 0);
Sql_GetData(sql_handle, 6, &data, NULL); m->class_ = atoi(data);
m->leader = (m->account_id == leader_id && m->char_id == leader_char ? 1 : 0);
@ -301,7 +300,7 @@ std::shared_ptr<struct party_data> search_partyname( char* str ){
int party_check_family_share( std::shared_ptr<struct party_data> p ){
int i;
unsigned short map = 0;
const char* map = nullptr;
if (!p->family)
return 0;
for (i = 0; i < MAX_PARTY; i++) {
@ -311,6 +310,10 @@ int party_check_family_share( std::shared_ptr<struct party_data> p ){
}
}
if( map == nullptr ){
return 0;
}
for (i = 0; i < MAX_PARTY; i++) {
struct party_member * mem = &(p->party.member[i]);
if (mem->lv == 0)
@ -322,7 +325,7 @@ int party_check_family_share( std::shared_ptr<struct party_data> p ){
//everyone should be online to share
return 0;
}
if (mem->map != map) {
if( strncmp( mem->map, map, sizeof( mem->map ) ) != 0 ){
//everyone should be on the same map
return 0;
}
@ -455,16 +458,18 @@ int mapif_party_withdraw(int party_id, uint32 account_id, uint32 char_id, char *
//Party map update notification
int mapif_party_membermoved(struct party *p,int idx)
{
unsigned char buf[20];
unsigned char buf[17+MAP_NAME_LENGTH_EXT];
WBUFW(buf,0) = 0x3825;
WBUFL(buf,2) = p->party_id;
WBUFL(buf,6) = p->member[idx].account_id;
WBUFL(buf,10) = p->member[idx].char_id;
WBUFW(buf,14) = p->member[idx].map;
WBUFB(buf,16) = p->member[idx].online;
WBUFW(buf,17) = p->member[idx].lv;
chmapif_sendall(buf, 19);
WBUFB(buf,14) = p->member[idx].online;
WBUFW(buf,15) = p->member[idx].lv;
safestrncpy( WBUFCP( buf, 17 ), p->member[idx].map, sizeof( p->member[idx].map ) );
chmapif_sendall( buf, sizeof( buf ) );
return 0;
}
@ -679,8 +684,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_
return 0;
}
// When member goes to other map or levels up.
int mapif_parse_PartyChangeMap(int fd, int party_id, uint32 account_id, uint32 char_id, unsigned short map, int online, unsigned int lv)
{
int mapif_parse_PartyChangeMap( int fd, int party_id, uint32 account_id, uint32 char_id, int online, unsigned int lv, const char* map ){
int i;
std::shared_ptr<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.
}
if (p->party.member[i].map != map) {
p->party.member[i].map = map;
if( strncmp( p->party.member[i].map, map, sizeof( p->party.member[i].map ) ) != 0 ){
safestrncpy( p->party.member[i].map, map, sizeof( p->party.member[i].map ) );
mapif_party_membermoved(&p->party, i);
int_party_check_lv(p);
}
@ -814,7 +818,7 @@ int inter_party_parse_frommap(int fd)
case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break;
case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break;
case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOCP(fd,14), (enum e_party_member_withdraw)RFIFOB(fd,14+NAME_LENGTH)); break;
case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOW(fd,14), RFIFOB(fd,16), RFIFOW(fd,17)); break;
case 0x3025: mapif_parse_PartyChangeMap( fd, RFIFOL( fd, 2 ), RFIFOL( fd, 6 ), RFIFOL( fd, 10 ), RFIFOB( fd, 14 ), RFIFOW( fd, 15 ), RFIFOCP( fd, 17 ) ); break;
case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break;
case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOCP(fd,12), RFIFOW(fd,2)-12); break;
case 0x3029: mapif_parse_PartyLeaderChange(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;

View File

@ -58,7 +58,7 @@ unsigned int party_share_level = 10;
int inter_recv_packet_length[] = {
-1,-1, 7,-1, -1,13,36, (2+4+4+4+1+NAME_LENGTH), 0,-1, 0, 0, 0, 0, 0, 0, // 3000-
6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010-
-1,10,-1,14, 15+NAME_LENGTH,19, 6,-1, 14,14, 6, 0, 0, 0, 0, 0, // 3020- Party
-1,10,-1,14, 15+NAME_LENGTH,17+MAP_NAME_LENGTH_EXT, 6,-1, 14,14, 6, 0, 0, 0, 0, 0, // 3020- Party
-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030-
-1, 9,10, 0, 0, 0, 0, 0, 8, 6,11,10, 10,-1,6+NAME_LENGTH, 0, // 3040-
-1,-1,10,10, 0,-1,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]

View File

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

View File

@ -962,13 +962,13 @@ ACMD_FUNC(save)
/*==========================================
*
*------------------------------------------*/
ACMD_FUNC(load)
{
int16 m;
ACMD_FUNC(load){
nullpo_retr(-1, sd);
m = map_mapindex2mapid(sd->status.save_point.map);
uint16 mapindex = mapindex_name2id( sd->status.save_point.map );
int16 m = map_mapindex2mapid( mapindex );
if (m >= 0 && map_getmapflag(m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
clif_displaymessage(fd, msg_txt(sd,249)); // You are not authorized to warp to your save map.
return -1;
@ -978,7 +978,7 @@ ACMD_FUNC(load)
return -1;
}
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
pc_setpos( sd, mapindex, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT );
clif_displaymessage(fd, msg_txt(sd,7)); // Warping to save point..
return 0;
@ -2580,8 +2580,8 @@ ACMD_FUNC(memo)
clif_displaymessage(sd->fd, msg_txt(sd,668)); // Your actual memo positions are:
for( i = 0; i < MAX_MEMOPOINTS; i++ )
{
if( sd->status.memo_point[i].map )
sprintf(atcmd_output, "%d - %s (%d,%d)", i, mapindex_id2name(sd->status.memo_point[i].map), sd->status.memo_point[i].x, sd->status.memo_point[i].y);
if( strcmp( "", sd->status.memo_point[i].map ) != 0 )
sprintf( atcmd_output, "%d - %s (%d,%d)", i, sd->status.memo_point[i].map, sd->status.memo_point[i].x, sd->status.memo_point[i].y );
else
sprintf(atcmd_output, msg_txt(sd,171), i); // %d - void
clif_displaymessage(sd->fd, atcmd_output);

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());
return 0;
}
if( map_mapindex2mapid( map_entry.mapindex ) < 0 ){
// Ignore silently, the map is on another mapserver
return 0;
}
}
if (this->nodeExists(location, "StartEvent")) {
@ -579,7 +584,7 @@ int bg_team_leave(map_session_data *sd, bool quit, bool deserter)
if (member->entry_point.map != 0 && !map_getmapflag(map_mapindex2mapid(member->entry_point.map), MF_NOSAVE))
pc_setpos(sd, member->entry_point.map, member->entry_point.x, member->entry_point.y, CLR_TELEPORT);
else
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); // Warp to save point if the entry map has no save flag.
pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT ); // Warp to save point if the entry map has no save flag.
bgteam->members.erase(member);
break;

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
60, 3,-1,-1,10,-1, 6,-1, // 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff
6,-1,18, 7,-1,39,30, 10, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07
6,-1,18, 7,-1, -1, 28 + MAP_NAME_LENGTH_EXT, 10, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07
6,30, 10, -1,86, 7,44,34, // 2b08-2b0f: U->2b08, U->2b09, U->2b0a, U->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
11,10,10, 0,11, -1, 0,10, // 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, U->2b15, F->2b16, U->2b17
2,10, 2,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
@ -53,7 +53,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2af8: Outgoing, chrif_connect -> 'connect to charserver / auth @ charserver'
//2af9: Incoming, chrif_connectack -> 'answer of the 2af8 login(ok / fail)'
//2afa: Outgoing, chrif_sendmap -> 'sending our maps'
//2afb: Incoming, chrif_sendmapack -> 'Maps received successfully / or not .. also received server name & default map'
//2afb: Incoming, chrif_sendmapack -> 'Maps received successfully / or not .. also received server name'
//2afc: Outgoing, chrif_scdata_request -> request sc_data for pc_authok'ed char. <- new command reuses previous one.
//2afd: Incoming, chrif_authok -> 'client authentication ok'
//2afe: Outgoing, send_usercount_tochar -> 'sends player count of this map server to charserver'
@ -322,20 +322,8 @@ int chrif_save(map_session_data *sd, int flag) {
WFIFOL(char_fd,8) = sd->status.char_id;
WFIFOB(char_fd,12) = (flag&CSAVE_QUIT) ? 1 : 0; //Flag to tell char-server this character is quitting.
// If the user is on a instance map, we have to fake his current position
if( map_getmapdata(sd->bl.m)->instance_id ){
struct mmo_charstatus status;
// Copy the whole status
memcpy( &status, &sd->status, sizeof( struct mmo_charstatus ) );
// Change his current position to his savepoint
memcpy( &status.last_point, &status.save_point, sizeof( struct point ) );
// Copy the copied status into the packet
memcpy( WFIFOP( char_fd, 13 ), &status, sizeof( struct mmo_charstatus ) );
} else {
// Copy the whole status into the packet
memcpy( WFIFOP( char_fd, 13 ), &sd->status, sizeof( struct mmo_charstatus ) );
}
WFIFOSET(char_fd, WFIFOW(char_fd,2));
@ -380,11 +368,11 @@ int chrif_sendmap(int fd) {
ShowStatus("Sending maps to char server...\n");
// Sending normal maps, not instances
WFIFOHEAD(fd, 4 + instance_start * 4);
WFIFOHEAD( fd, 4 + instance_start * MAP_NAME_LENGTH_EXT );
WFIFOW(fd,0) = 0x2afa;
for (int i = 0; i < instance_start; i++)
WFIFOW(fd, 4 + i * 4) = map[i].index;
WFIFOW(fd, 2) = 4 + instance_start * 4;
safestrncpy( WFIFOCP( fd, 4 + i * MAP_NAME_LENGTH_EXT ), map[i].name, MAP_NAME_LENGTH_EXT );
WFIFOW( fd, 2 ) = 4 + instance_start * MAP_NAME_LENGTH_EXT;
WFIFOSET(fd, WFIFOW(fd, 2));
return 0;
@ -396,8 +384,8 @@ int chrif_recvmap(int fd) {
uint32 ip = ntohl(RFIFOL(fd,4));
uint16 port = ntohs(RFIFOW(fd,8));
for(i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) {
map_setipport(RFIFOW(fd,i), ip, port);
for( i = 10, j = 0; i < RFIFOW( fd, 2 ); i += MAP_NAME_LENGTH_EXT, j++ ){
map_setipport( mapindex_name2id( RFIFOCP( fd, i ) ), ip, port );
}
if (battle_config.etc_log)
@ -414,8 +402,9 @@ int chrif_removemap(int fd) {
uint32 ip = RFIFOL(fd,4);
uint16 port = RFIFOW(fd,8);
for(i = 10, j = 0; i < RFIFOW(fd, 2); i += 4, j++)
map_eraseipport(RFIFOW(fd, i), ip, port);
for( i = 10, j = 0; i < RFIFOW( fd, 2 ); i += MAP_NAME_LENGTH_EXT, j++ ){
map_eraseipport( mapindex_name2id( RFIFOCP( fd, i ) ), ip, port );
}
other_mapserver_count--;
@ -441,28 +430,29 @@ int chrif_changemapserver(map_session_data* sd, uint32 ip, uint16 port) {
chrif_check(-1);
WFIFOHEAD(char_fd,39);
WFIFOHEAD( char_fd, 37 + MAP_NAME_LENGTH_EXT );
WFIFOW(char_fd, 0) = 0x2b05;
WFIFOL(char_fd, 2) = sd->bl.id;
WFIFOL(char_fd, 6) = sd->login_id1;
WFIFOL(char_fd,10) = sd->login_id2;
WFIFOL(char_fd,14) = sd->status.char_id;
WFIFOW(char_fd,18) = sd->mapindex;
WFIFOW(char_fd,20) = sd->bl.x;
WFIFOW(char_fd,22) = sd->bl.y;
WFIFOL(char_fd,24) = htonl(ip);
WFIFOW(char_fd,28) = htons(port);
WFIFOB(char_fd,30) = sd->status.sex;
WFIFOL(char_fd,31) = htonl(session[sd->fd]->client_addr);
WFIFOL(char_fd,35) = sd->group_id;
WFIFOSET(char_fd,39);
safestrncpy( WFIFOCP( char_fd, 18 ), mapindex_id2name( sd->mapindex ), MAP_NAME_LENGTH_EXT );
int offset = 18 + MAP_NAME_LENGTH_EXT;
WFIFOW( char_fd, offset + 0 ) = sd->bl.x;
WFIFOW( char_fd, offset + 2 ) = sd->bl.y;
WFIFOL( char_fd, offset + 4 ) = htonl( ip );
WFIFOW( char_fd, offset + 8 ) = htons( port );
WFIFOB( char_fd, offset + 10 ) = sd->status.sex;
WFIFOL( char_fd, offset + 11 ) = htonl( session[sd->fd]->client_addr );
WFIFOL( char_fd, offset + 15 ) = sd->group_id;
WFIFOSET( char_fd, 37 + MAP_NAME_LENGTH_EXT );
return 0;
}
/// map-server change (mapserv) request acknowledgement (positive or negative)
/// R 2b06 <account_id>.L <login_id1>.L <login_id2>.L <char_id>.L <map_index>.W <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) {
/// 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, const char* map, short x, short y, uint32 ip, uint16 port) {
struct auth_node *node;
if ( !( node = chrif_auth_check(account_id, char_id, ST_MAPCHANGE) ) )
@ -473,7 +463,7 @@ int chrif_changemapserverack(uint32 account_id, int login_id1, int login_id2, ui
clif_authfail_fd(node->fd, 0);
chrif_char_offline(node->sd);
} else
clif_changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port));
clif_changemapserver(node->sd, map, x, y, ntohl(ip), ntohs(port));
//Player has been saved already, remove him from memory. [Skotlex]
chrif_auth_delete(account_id, char_id, ST_MAPCHANGE);
@ -578,7 +568,6 @@ void chrif_on_ready(void) {
/**
* Maps are sent, then received misc info from char-server
* - Server name
* - Default map
* HZ 0x2afb
**/
int chrif_sendmapack(int fd) {
@ -592,19 +581,11 @@ int chrif_sendmapack(int fd) {
// Whisper name
safestrncpy( wisp_server_name, RFIFOCP( fd, offs ), NAME_LENGTH );
// Default map
safestrncpy( map_default.mapname, RFIFOCP( fd, ( offs += NAME_LENGTH ) ), MAP_NAME_LENGTH );
map_default.x = RFIFOW(fd, (offs+=MAP_NAME_LENGTH));
map_default.y = RFIFOW(fd, (offs+=2));
// Server name
safestrncpy( charserver_name, RFIFOCP( fd, ( offs += 2 ) ), NAME_LENGTH );
safestrncpy( charserver_name, RFIFOCP( fd, offs + NAME_LENGTH ), NAME_LENGTH );
ShowStatus( "Map-server connected to char-server '" CL_WHITE "%s" CL_RESET "' (whispername: %s).\n", charserver_name, wisp_server_name );
if (battle_config.etc_log)
ShowInfo("Received default map from char-server '" CL_WHITE "%s %d,%d" CL_RESET "'.\n", map_default.mapname, map_default.x, map_default.y);
chrif_on_ready();
return 0;
@ -1784,7 +1765,7 @@ int chrif_parse(int fd) {
case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break;
case 0x2b04: chrif_recvmap(fd); break;
case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
case 0x2b06: chrif_changemapserverack( RFIFOL( fd, 2 ), RFIFOL( fd, 6 ), RFIFOL( fd, 10 ), RFIFOL( fd, 14 ), RFIFOCP( fd, 18 ), RFIFOW( fd, 18 + MAP_NAME_LENGTH_EXT ), RFIFOW( fd, 18 + MAP_NAME_LENGTH_EXT + 2 ), RFIFOL( fd, 18 + MAP_NAME_LENGTH_EXT + 4 ), RFIFOW( fd, 18 + MAP_NAME_LENGTH_EXT + 8 ) ); break;
case 0x2b09: map_addnickdb(RFIFOL(fd,2), RFIFOCP(fd,6)); break;
case 0x2b0b: chrif_skillcooldown_load(fd); break;
case 0x2b0d: chrif_changedsex(fd); break;

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.
/// 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)
void clif_changemapserver(map_session_data* sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port)
void clif_changemapserver(map_session_data* sd, const char* map, int x, int y, uint32 ip, uint16 port)
{
int fd;
#if PACKETVER >= 20170315
@ -2128,7 +2128,7 @@ void clif_changemapserver(map_session_data* sd, unsigned short map_index, int x,
WFIFOHEAD(fd,packet_len(cmd));
WFIFOW(fd,0) = cmd;
mapindex_getmapname_ext(mapindex_id2name(map_index), WFIFOCP(fd,2));
mapindex_getmapname_ext( map, WFIFOCP( fd, 2 ) );
WFIFOW(fd,18) = x;
WFIFOW(fd,20) = y;
WFIFOL(fd,22) = htonl(ip);
@ -6245,8 +6245,7 @@ void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,i
/// Presents a list of available warp destinations (ZC_WARPLIST).
/// 011c <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;
nullpo_retv(sd);
fd = sd->fd;
@ -6255,12 +6254,18 @@ void clif_skill_warppoint(map_session_data* sd, uint16 skill_id, uint16 skill_lv
WFIFOW(fd,0) = 0x11c;
WFIFOW(fd,2) = skill_id;
memset(WFIFOP(fd,4), 0x00, 4*MAP_NAME_LENGTH_EXT);
if (map1 == (unsigned short)-1) strcpy(WFIFOCP(fd,4), "Random");
else // normal map name
if (map1 > 0) mapindex_getmapname_ext(mapindex_id2name(map1), WFIFOCP(fd,4));
if (map2 > 0) mapindex_getmapname_ext(mapindex_id2name(map2), WFIFOCP(fd,20));
if (map3 > 0) mapindex_getmapname_ext(mapindex_id2name(map3), WFIFOCP(fd,36));
if (map4 > 0) mapindex_getmapname_ext(mapindex_id2name(map4), WFIFOCP(fd,52));
if( strcmp( "", map1 ) != 0 ){
mapindex_getmapname_ext( map1, WFIFOCP( fd, 4 ) );
}
if( strcmp( "", map2 ) != 0 ){
mapindex_getmapname_ext( map2, WFIFOCP( fd, 20 ) );
}
if( strcmp( "", map3 ) != 0 ){
mapindex_getmapname_ext( map3, WFIFOCP( fd, 36 ) );
}
if( strcmp( "", map4 ) != 0 ){
mapindex_getmapname_ext( map4, WFIFOCP( fd, 52 ) );
}
WFIFOSET(fd,packet_len(0x11c));
sd->menuskill_id = skill_id;
@ -7979,7 +7984,7 @@ void clif_party_info( struct party_data& party, map_session_data* sd ){
member.GID = m.char_id;
#endif
safestrncpy( member.playerName, m.name, sizeof( member.playerName ) );
mapindex_getmapname_ext( mapindex_id2name( m.map ), member.mapName );
mapindex_getmapname_ext( m.map, member.mapName );
member.leader = ( m.leader ) ? 0 : 1;
member.offline = ( m.online ) ? 0 : 1;
#if PACKETVER_MAIN_NUM >= 20170524 || PACKETVER_RE_NUM >= 20170502 || defined(PACKETVER_ZERO)

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_move(struct unit_data *ud); //area
void clif_changemap(map_session_data *sd, short m, int x, int y); //self
void clif_changemapserver(map_session_data* sd, unsigned short map_index, int x, int y, uint32 ip, uint16 port); //self
void clif_changemapserver( map_session_data* sd, const char* map, int x, int y, uint32 ip, uint16 port );
void clif_blown(struct block_list *bl); // area
void clif_slide(struct block_list *bl, int x, int y); // area
void clif_fixpos(struct block_list *bl); // area
@ -746,7 +746,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,t_tick tick,
bool clif_skill_nodamage(struct block_list *src,struct block_list *dst,uint16 skill_id,int heal,t_tick tick);
void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,int y,t_tick tick);
void clif_skill_estimation(map_session_data *sd,struct block_list *dst);
void clif_skill_warppoint(map_session_data* sd, uint16 skill_id, uint16 skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4);
void clif_skill_warppoint( map_session_data* sd, uint16 skill_id, uint16 skill_lv, const char* map1, const char* map2 = "", const char* map3 = "", const char* map4 = "" );
void clif_skill_memomessage(map_session_data* sd, int type);
void clif_skill_teleportmessage(map_session_data *sd, int type);
void clif_skill_produce_mix_list(map_session_data *sd, int skill_id, int trigger);

View File

@ -299,7 +299,7 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) {
uint16 mapindex = mapindex_name2idx(map_name.c_str(), nullptr);
if (map_mapindex2mapid(mapindex) < 0) {
if( mapindex == 0 ){
this->invalidWarning(node["Map"], "Map %s doesn't exist, skipping.\n", map_name.c_str());
return 0;
}
@ -394,7 +394,8 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) {
map_data* md = map_getmapdata( map_mapindex2mapid( gc->mapindex ) );
if( warp_x >= md->xs ){
// If the map is on another map-server, we cannot verify the bounds
if( md != nullptr && warp_x >= md->xs ){
this->invalidWarning( node["WarpX"], "WarpX has to be smaller than %hu.\n", md->xs );
return 0;
}
@ -420,7 +421,8 @@ uint64 CastleDatabase::parseBodyNode(const ryml::NodeRef& node) {
map_data* md = map_getmapdata( map_mapindex2mapid( gc->mapindex ) );
if( warp_y >= md->ys ){
// If the map is on another map-server, we cannot verify the bounds
if( md != nullptr && warp_y >= md->ys ){
this->invalidWarning( node["WarpY"], "WarpY has to be smaller than %hu.\n", md->ys );
return 0;
}
@ -1218,11 +1220,9 @@ int guild_member_withdraw(int guild_id, uint32 account_id, uint32 char_id, int f
if (g->instance_id) {
struct map_data *mapdata = map_getmapdata(sd->bl.m);
if (mapdata->instance_id) { // User was on the instance map
if (mapdata->save.map)
pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, CLR_TELEPORT);
else
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
// User was on the instance map of the guild
if( g->instance_id == mapdata->instance_id ){
pc_setpos_savepoint( *sd );
}
}

View File

@ -167,14 +167,21 @@ uint64 InstanceDatabase::parseBodyNode(const ryml::NodeRef& node) {
if (!this->asString(enterNode, "Map", map))
return 0;
int16 m = map_mapname2mapid(map.c_str());
uint16 mapindex = mapindex_name2idx( map.c_str(), nullptr );
if (m == -1) {
if( mapindex == 0 ){
this->invalidWarning(enterNode["Map"], "Map %s is not a valid map, skipping.\n", map.c_str());
return 0;
}
instance->enter.map = m;
int16 mapid = map_mapindex2mapid( mapindex );
if( mapid < 0 ){
// Ignore silently, the map is on another mapserver
return 0;
}
instance->enter.map = mapid;
}
if (this->nodeExists(enterNode, "X")) {

View File

@ -37,7 +37,7 @@
static const int packet_len_table[] = {
-1,-1,27,-1, -1, 0,37,-1, 10+NAME_LENGTH,-1, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
39,-1,15,15, 15+NAME_LENGTH,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
39,-1,15,15, 15+NAME_LENGTH,17+MAP_NAME_LENGTH_EXT, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
-1,10, 0,18, 0, 0, 0, 0, -1,75,-1,11, 11,-1, 38, 0, //0x3840
-1,-1, 7, 7, 7,11, 8,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari]
@ -709,15 +709,15 @@ int intif_party_changemap(map_session_data *sd,int online)
} else
mapindex = sd->mapindex;
WFIFOHEAD(inter_fd,19);
WFIFOHEAD( inter_fd, 17 + MAP_NAME_LENGTH_EXT );
WFIFOW(inter_fd,0)=0x3025;
WFIFOL(inter_fd,2)=sd->status.party_id;
WFIFOL(inter_fd,6)=sd->status.account_id;
WFIFOL(inter_fd,10)=sd->status.char_id;
WFIFOW(inter_fd,14)=mapindex;
WFIFOB(inter_fd,16)=online;
WFIFOW(inter_fd,17)=sd->status.base_level;
WFIFOSET(inter_fd,19);
WFIFOB(inter_fd,14)=online;
WFIFOW(inter_fd,15)=sd->status.base_level;
safestrncpy( WFIFOCP( inter_fd, 17 ), mapindex_id2name( mapindex ), MAP_NAME_LENGTH_EXT );
WFIFOSET( inter_fd, 17 + MAP_NAME_LENGTH_EXT );
return 1;
}
@ -1628,7 +1628,7 @@ int intif_parse_PartyBroken(int fd)
*/
int intif_parse_PartyMove(int fd)
{
party_recv_movemap(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOW(fd,14),RFIFOB(fd,16),RFIFOW(fd,17));
party_recv_movemap( RFIFOL( fd, 2 ), RFIFOL( fd, 6 ), RFIFOL( fd, 10 ), RFIFOB( fd, 14 ), RFIFOW( fd, 15 ), RFIFOCP( fd, 17 ) );
return 1;
}

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
struct s_map_default map_default;
int console = 0;
int enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex]
int enable_grf = 0; //To enable/disable reading maps from GRF files, bypassing mapcache [blackhole89]
@ -2146,23 +2144,6 @@ int map_quit(map_session_data *sd) {
unit_remove_map_pc(sd,CLR_RESPAWN);
if( mapdata->instance_id > 0 ) { // Avoid map conflicts and warnings on next login
int16 m;
struct point *pt;
if( mapdata->save.map )
pt = &mapdata->save;
else
pt = &sd->status.save_point;
if( (m=map_mapindex2mapid(pt->map)) >= 0 )
{
sd->bl.m = m;
sd->bl.x = pt->x;
sd->bl.y = pt->y;
sd->mapindex = pt->map;
}
}
if (sd->state.vending)
idb_remove(vending_getdb(), sd->status.char_id);
@ -2751,7 +2732,7 @@ static int map_instancemap_leave(struct block_list *bl, va_list ap)
nullpo_retr(0, bl);
nullpo_retr(0, sd = (map_session_data *)bl);
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
pc_setpos_savepoint( *sd );
return 1;
}
@ -5153,11 +5134,6 @@ bool MapServer::initialize( int argc, char *argv[] ){
MSG_CONF_NAME_THA = "conf/msg_conf/map_msg_tha.conf"; // Thai
/* Multilanguage */
// Default map
safestrncpy(map_default.mapname, "prontera", MAP_NAME_LENGTH);
map_default.x = 156;
map_default.y = 191;
// default inter_config
inter_config.start_status_points = 48;
inter_config.emblem_woe_change = true;

View File

@ -1051,13 +1051,6 @@ extern char channel_conf[];
extern char wisp_server_name[];
struct s_map_default {
char mapname[MAP_NAME_LENGTH];
unsigned short x;
unsigned short y;
};
extern struct s_map_default map_default;
/// Type of 'save_settings'
enum save_settings_type {
CHARSAVE_NONE = 0x000, /// Never

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

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)
int party_recv_noinfo(int party_id, uint32 char_id);
int party_recv_info(struct party* sp, uint32 char_id);
int party_recv_movemap(int party_id,uint32 account_id,uint32 char_id, unsigned short map,int online,int lv);
int party_recv_movemap( int party_id, uint32 account_id, uint32 char_id, int online, int lv, const char* map );
int party_broken(int party_id);
int party_optionchanged(int party_id,uint32 account_id,int exp,int item,int flag);
int party_changeoption(map_session_data *sd,int exp,int item);

View File

@ -1315,31 +1315,51 @@ void pc_makesavestatus(map_session_data *sd) {
sd->status.sp = sd->battle_status.sp;
sd->status.ap = sd->battle_status.ap;
}
sd->status.last_point.map = sd->mapindex;
mapindex_getmapname( mapindex_id2name( sd->mapindex ), sd->status.last_point.map );
sd->status.last_point.x = sd->bl.x;
sd->status.last_point.y = sd->bl.y;
return;
}
if(pc_isdead(sd)) {
pc_setrestartvalue(sd, 0);
memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
} else {
if( pc_isdead( sd ) ){
pc_setrestartvalue( sd, 0 );
// Return to save point
safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) );
sd->status.last_point.x = sd->status.save_point.x;
sd->status.last_point.y = sd->status.save_point.y;
}else{
sd->status.hp = sd->battle_status.hp;
sd->status.sp = sd->battle_status.sp;
sd->status.ap = sd->battle_status.ap;
sd->status.last_point.map = sd->mapindex;
struct map_data* mapdata = map_getmapdata( sd->bl.m );
// If saving is not allowed on the map, we return the player to the designated point
if( mapdata->flag[MF_NOSAVE] ){
// The map has a specific return point
if( mapdata->save.map ){
safestrncpy( sd->status.last_point.map, mapindex_id2name( mapdata->save.map ), sizeof( sd->status.last_point.map ) );
sd->status.last_point.x = mapdata->save.x;
sd->status.last_point.y = mapdata->save.y;
// Return the user to his save point
}else{
safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) );
sd->status.last_point.x = sd->status.save_point.x;
sd->status.last_point.y = sd->status.save_point.y;
}
// If the user is on a instance map, we return him to his save point
}else if( mapdata->instance_id ){
// Return the user to his save point
safestrncpy( sd->status.last_point.map, sd->status.save_point.map, sizeof( sd->status.last_point.map ) );
sd->status.last_point.x = sd->status.save_point.x;
sd->status.last_point.y = sd->status.save_point.y;
}else{
// Save normally
mapindex_getmapname( mapindex_id2name( sd->mapindex ), sd->status.last_point.map );
sd->status.last_point.x = sd->bl.x;
sd->status.last_point.y = sd->bl.y;
}
if(map_getmapflag(sd->bl.m, MF_NOSAVE)) {
struct map_data *mapdata = map_getmapdata(sd->bl.m);
if(mapdata->save.map)
memcpy(&sd->status.last_point,&mapdata->save,sizeof(sd->status.last_point));
else
memcpy(&sd->status.last_point,&sd->status.save_point,sizeof(sd->status.last_point));
}
}
@ -2011,9 +2031,9 @@ bool pc_authok(map_session_data *sd, uint32 login_id2, time_t expiration_time, i
sd->vars_received = 0x0;
//warp player
enum e_setpos setpos_result = pc_setpos( sd, sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT );
enum e_setpos setpos_result = pc_setpos( sd, mapindex_name2id( sd->status.last_point.map ), sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT );
if( setpos_result != SETPOS_OK ){
ShowError( "Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, setpos_result );
ShowError( "Last_point_map %s not found (error code %d)\n", sd->status.last_point.map, setpos_result );
// try warping to a default map instead (church graveyard)
if (pc_setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != SETPOS_OK) {
@ -6892,6 +6912,16 @@ enum e_setpos pc_setpos(map_session_data* sd, unsigned short mapindex, int x, in
return SETPOS_OK;
}
enum e_setpos pc_setpos_savepoint( map_session_data& sd, clr_type clrtype ){
struct map_data *mapdata = map_getmapdata( sd.bl.m );
if( mapdata != nullptr && mapdata->flag[MF_NOSAVE] && mapdata->save.map ){
return pc_setpos( &sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, clrtype );
}else{
return pc_setpos( &sd, mapindex_name2id( sd.status.save_point.map ), sd.status.save_point.x, sd.status.save_point.y, clrtype );
}
}
/*==========================================
* Warp player sd to random location on current map.
* May fail if no walkable cell found (1000 attempts).
@ -6955,9 +6985,11 @@ bool pc_memo(map_session_data* sd, int pos)
if( pos == -1 )
{
uint8 i;
const char* mapname = map_mapid2mapname( sd->bl.m );
// prevent memo-ing the same map multiple times
ARR_FIND( 0, MAX_MEMOPOINTS, i, sd->status.memo_point[i].map == map_id2index(sd->bl.m) );
memmove(&sd->status.memo_point[1], &sd->status.memo_point[0], (u8min(i,MAX_MEMOPOINTS-1))*sizeof(struct point));
ARR_FIND( 0, MAX_MEMOPOINTS, i, strncmp( sd->status.memo_point[i].map, mapname, sizeof( sd->status.memo_point[i].map ) ) == 0 );
memmove( &sd->status.memo_point[1], &sd->status.memo_point[0], ( u8min( i, MAX_MEMOPOINTS - 1 ) ) * sizeof( struct s_point_str ) );
pos = 0;
}
@ -6966,7 +6998,7 @@ bool pc_memo(map_session_data* sd, int pos)
return false;
}
sd->status.memo_point[pos].map = map_id2index(sd->bl.m);
safestrncpy( sd->status.memo_point[pos].map, map_mapid2mapname( sd->bl.m ), sizeof( sd->status.memo_point[pos].map ) );
sd->status.memo_point[pos].x = sd->bl.x;
sd->status.memo_point[pos].y = sd->bl.y;
@ -9340,8 +9372,9 @@ void pc_respawn(map_session_data* sd, clr_type clrtype)
pc_setstand(sd, true);
pc_setrestartvalue(sd,3);
if( pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype) != SETPOS_OK )
if( pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, clrtype ) != SETPOS_OK ){
clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
}
}
static TIMER_FUNC(pc_respawn_timer){
@ -12645,7 +12678,7 @@ void pc_setsavepoint(map_session_data *sd, short mapindex,int x,int y)
{
nullpo_retv(sd);
sd->status.save_point.map = mapindex;
safestrncpy( sd->status.save_point.map, mapindex_id2name( mapindex ), sizeof( sd->status.save_point.map ) );
sd->status.save_point.x = x;
sd->status.save_point.y = y;
}

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_savepoint( map_session_data& sd, clr_type clrtype = CLR_TELEPORT );
void pc_setsavepoint(map_session_data *sd, short mapindex,int x,int y);
char pc_randomwarp(map_session_data *sd,clr_type type,bool ignore_mapflag = false);
bool pc_memo(map_session_data* sd, int pos);

View File

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

View File

@ -9057,15 +9057,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( skill_lv == 1 )
pc_randomwarp(sd,CLR_TELEPORT);
else
pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ), sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT );
break;
}
clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
if( skill_lv == 1 && skill_id != ALL_ODINS_RECALL )
clif_skill_warppoint(sd,skill_id,skill_lv, (unsigned short)-1,0,0,0);
clif_skill_warppoint( sd, skill_id, skill_lv, "Random" );
else
clif_skill_warppoint(sd,skill_id,skill_lv, (unsigned short)-1,sd->status.save_point.map,0,0);
clif_skill_warppoint( sd, skill_id, skill_lv, "Random", sd->status.save_point.map );
} else
unit_warp(bl,-1,-1,-1,CLR_TELEPORT);
break;
@ -13604,9 +13604,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
if(sd)
{
clif_skill_warppoint(sd, skill_id, skill_lv, sd->status.save_point.map,
(skill_lv >= 2) ? sd->status.memo_point[0].map : 0,
(skill_lv >= 3) ? sd->status.memo_point[1].map : 0,
(skill_lv >= 4) ? sd->status.memo_point[2].map : 0
(skill_lv >= 2) ? sd->status.memo_point[0].map : "",
(skill_lv >= 3) ? sd->status.memo_point[1].map : "",
(skill_lv >= 4) ? sd->status.memo_point[2].map : ""
);
}
if( sc && sc->getSCE(SC_CURSEDCIRCLE_ATKER) ) //Should only remove after the skill has been casted.
@ -14243,14 +14243,14 @@ int skill_castend_map (map_session_data *sd, uint16 skill_id, const char *mapnam
if(strcmp(mapname,"Random") == 0)
pc_randomwarp(sd,CLR_TELEPORT);
else if (sd->menuskill_val > 1 || skill_id == ALL_ODINS_RECALL) //Need lv2 to be able to warp here.
pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
pc_setpos( sd, mapindex_name2id( sd->status.save_point.map ),sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT );
clif_refresh_storagewindow(sd);
break;
case AL_WARP:
{
const struct point *p[4];
const struct s_point_str *p[4];
std::shared_ptr<s_skill_unit_group> group;
int i, lv, wx, wy;
int maxcount=0;
@ -14286,7 +14286,7 @@ int skill_castend_map (map_session_data *sd, uint16 skill_id, const char *mapnam
if( lv > 4 ) lv = 4; // crash prevention
// check if the chosen map exists in the memo list
ARR_FIND( 0, lv, i, mapindex == p[i]->map );
ARR_FIND( 0, lv, i, strncmp( p[i]->map, mapname, sizeof( p[i]->map ) ) == 0 );
if( i < lv ) {
x=p[i]->x;
y=p[i]->y;

View File

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