/*========================================== * Saves character data. * Flag = 1: Character is quitting * Flag = 2: Character is changing map-servers *------------------------------------------*/ int chrif_save(struct map_session_data *sd, int flag) { nullpo_retr(-1, sd); pc_makesavestatus(sd); if (flag && sd->state.active) //Store player data which is quitting. { //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex] if (chrif_isconnected()) chrif_save_scdata(sd); if (!chrif_auth_logout(sd, flag==1?ST_LOGOUT:ST_MAPCHANGE)) ShowError("chrif_save: Falha em configurar personagem %d:%d para sair adequadamente!\n", sd->status.account_id, sd->status.char_id); } if(!chrif_isconnected()) return -1; //Character is saved on reconnect. //For data sync if (sd->state.storage_flag == 2) storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag); if (flag) sd->state.storage_flag = 0; //Force close it. //Saving of registry values. if (sd->state.reg_dirty&4) intif_saveregistry(sd, 3); //Save char regs if (sd->state.reg_dirty&2) intif_saveregistry(sd, 2); //Save account regs if (sd->state.reg_dirty&1) intif_saveregistry(sd, 1); //Save account2 regs WFIFOHEAD(char_fd, sizeof(sd->status) + 13); WFIFOW(char_fd,0) = 0x2b01; WFIFOW(char_fd,2) = sizeof(sd->status) + 13; WFIFOL(char_fd,4) = sd->status.account_id; WFIFOL(char_fd,8) = sd->status.char_id; WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting. memcpy(WFIFOP(char_fd,13), &sd->status, sizeof(sd->status)); WFIFOSET(char_fd, WFIFOW(char_fd,2)); if( sd->status.pet_id > 0 && sd->pd ) intif_save_petdata(sd->status.account_id,&sd->pd->pet); if( sd->hd && merc_is_hom_active(sd->hd) ) merc_save(sd->hd); if( sd->md && mercenary_get_lifetime(sd->md) > 0 ) mercenary_save(sd->md); #ifndef TXT_ONLY if( sd->save_quest ) intif_quest_save(sd); #endif return 0; }
/*========================================== * Saves character data. * Flag = 1: Character is quitting * Flag = 2: Character is changing map-servers *------------------------------------------*/ int chrif_save(struct map_session_data *sd, int flag) { nullpo_retr(-1, sd); pc_makesavestatus(sd); if (flag && sd->state.active) { //Store player data which is quitting //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex] if ( chrif_isconnected() ) chrif_save_scdata(sd); if ( !chrif_auth_logout(sd,flag == 1 ? ST_LOGOUT : ST_MAPCHANGE) ) ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id); } chrif_check(-1); //Character is saved on reconnect. //For data sync if (sd->state.storage_flag == 2) storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag); if (flag) sd->state.storage_flag = 0; //Force close it. //Saving of registry values. if (sd->state.reg_dirty&4) intif_saveregistry(sd, 3); //Save char regs if (sd->state.reg_dirty&2) intif_saveregistry(sd, 2); //Save account regs if (sd->state.reg_dirty&1) intif_saveregistry(sd, 1); //Save account2 regs WFIFOHEAD(char_fd, sizeof(sd->status) + 13); WFIFOW(char_fd,0) = 0x2b01; WFIFOW(char_fd,2) = sizeof(sd->status) + 13; WFIFOL(char_fd,4) = sd->status.account_id; WFIFOL(char_fd,8) = sd->status.char_id; WFIFOB(char_fd,12) = (flag==1)?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[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)); if( sd->status.pet_id > 0 && sd->pd ) intif_save_petdata(sd->status.account_id,&sd->pd->pet); if( sd->hd && merc_is_hom_active(sd->hd) ) merc_save(sd->hd); if( sd->md && mercenary_get_lifetime(sd->md) > 0 ) mercenary_save(sd->md); if( sd->ed && elemental_get_lifetime(sd->ed) > 0 ) elemental_save(sd->ed); if( sd->save_quest ) intif_quest_save(sd); return 0; }