/*========================================== * 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); if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out. 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); } if(!chrif_isconnected()) return -1; //Character is saved on reconnect. //For data sync if (sd->state.storage_flag == 1) storage_storage_save(sd->status.account_id, flag); else 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); return 0; }
/*========================================== * timerFunction * Chk the connection to char server, (if it down) *------------------------------------------*/ static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data) { static int displayed = 0; if ( char_fd <= 0 || session[char_fd] == NULL ) { if ( !displayed ) { ShowStatus("Attempting to connect to Char Server. Please wait.\n"); displayed = 1; } chrif_state = 0; char_fd = make_connection(char_ip, char_port,false); if (char_fd == -1)//Attempt to connect later. [Skotlex] return 0; session[char_fd]->func_parse = chrif_parse; session[char_fd]->flag.server = 1; realloc_fifo(char_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); chrif_connect(char_fd); chrif_connected = (chrif_state == 2); srvinfo = 0; } else { if (srvinfo == 0) { chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common); srvinfo = 1; } } if ( chrif_isconnected() ) displayed = 0; return 0; }
static int harmony_group_register_timer(int tid, unsigned int tick, int id, intptr data) { if (chrif_isconnected()) { harmony_register_groups(); // We will re-send group associations every thirty seconds, otherwise the login server would never be able to recover from a restart _athena_delete_timer(tid, harmony_group_register_timer); tid_group_register = _athena_add_timer_interval(_athena_gettick()+30*1000, harmony_group_register_timer, 0, 0, 30*1000); } return 0; }
/*========================================== * Request auth confirmation *------------------------------------------*/ void chrif_authreq(struct map_session_data *sd) { struct auth_node *node= chrif_search(sd->bl.id); if( node != NULL || !chrif_isconnected() ) { set_eof(sd->fd); return; } if( !chrif_isconnected() ) return; WFIFOHEAD(char_fd,19); WFIFOW(char_fd,0) = 0x2b26; WFIFOL(char_fd,2) = sd->status.account_id; WFIFOL(char_fd,6) = sd->status.char_id; WFIFOL(char_fd,10) = sd->login_id1; WFIFOB(char_fd,14) = sd->status.sex; WFIFOL(char_fd,15) = htonl(session[sd->fd]->client_addr); WFIFOSET(char_fd,19); chrif_sd_to_auth(sd, ST_LOGIN); }
/*========================================== * 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); if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out. pc_makesavestatus(sd); if(!chrif_isconnected()) { if (flag) sd->state.finalsave = 1; //Will save character on reconnect. return -1; } if (sd->state.finalsave) return -1; //Refuse to save a char already tagged for final saving. [Skotlex] //For data sync if (sd->state.storage_flag == 1) storage_storage_save(sd->status.account_id, flag); else 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->hd && merc_is_hom_active(sd->hd)) merc_save(sd->hd); if (flag) sd->state.finalsave = 1; //Mark the last save as done. return 0; }
/*========================================== * timer�� * char�I�Ƃ̐ڑ����m�F���A������Ă�����ēx�ڑ����� *------------------------------------------*/ static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data) { static int displayed = 0; if (char_fd <= 0 || session[char_fd] == NULL) { if (!displayed) { ShowStatus("Estabelecendo conexao com o servidor de personagens. Por favor aguarde.\n"); displayed = 1; } chrif_state = 0; char_fd = make_connection(char_ip, char_port); if (char_fd == -1) { //Attempt to connect later. [Skotlex] return 0; } session[char_fd]->func_parse = chrif_parse; session[char_fd]->flag.server = 1; realloc_fifo(char_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); chrif_connect(char_fd); chrif_connected = (chrif_state == 2); #ifndef TXT_ONLY srvinfo = 0; #endif /* not TXT_ONLY */ } else { #ifndef TXT_ONLY if (srvinfo == 0) { chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common); srvinfo = 1; } #endif /* not TXT_ONLY */ } if (chrif_isconnected()) displayed = 0; return 0; }
int auth_db_cleanup(int tid, unsigned int tick, int id, int data) { if(!chrif_isconnected()) return 0; auth_db->foreach(auth_db, auth_db_cleanup_sub); return 0; }
void harmony_action_request_global(int task, int id, intptr data) { switch (task) { case HARMTASK_LOGIN_ACTION: chrif_harmony_request((uint8*)data, id); break; case HARMTASK_GET_FD: { TBL_PC *sd = BL_CAST(BL_PC, map_id2bl(id)); *(int32*)data = (sd ? sd->fd : 0); } break; case HARMTASK_SET_LOG_METHOD: log_method = id; break; case HARMTASK_INIT_GROUPS: if (chrif_isconnected()) harmony_register_groups(); else { // Register groups as soon as the char server is available again if (tid_group_register != INVALID_TIMER) _athena_delete_timer(tid_group_register, harmony_group_register_timer); tid_group_register = _athena_add_timer_interval(_athena_gettick()+1000, harmony_group_register_timer, 0, 0, 500); } break; case HARMTASK_RESOLVE_GROUP: #if HARMSW == HARMSW_RATHENA_GROUP *(int32*)data = pc_group_id2level(id); #else *(int32*)data = id; #endif break; case HARMTASK_PACKET: clif_send((const uint8*)data, id, NULL, ALL_CLIENT); break; case HARMTASK_GET_ADMINS: { #if HARMSW == HARMSW_RATHENA_GROUP // Iterate groups and register each group individually current_groupscan_minlevel = id; pc_group_iterate(harmony_iterate_groups_adminlevel); #else // int account_id; int level = id; if (SQL_SUCCESS != SqlStmt_BindParam(admin_stmt, 0, SQLDT_INT, (void*)&level, sizeof(level)) || SQL_SUCCESS != SqlStmt_Execute(admin_stmt)) { ShowError("Fetching GM accounts failed.\n"); Sql_ShowDebug(mmysql_handle); break; } SqlStmt_BindColumn(admin_stmt, 0, SQLDT_INT, &account_id, 0, NULL, NULL); while (SQL_SUCCESS == SqlStmt_NextRow(admin_stmt)) { harm_funcs->zone_register_admin(account_id, false); } #endif break; } case HARMTASK_IS_CHAR_CONNECTED: *(int*)data = chrif_isconnected(); break; default: ShowError("Harmony requested unknown action! (Global; ID=%d)\n", task); ShowError("This indicates that you are running an incompatible version.\n"); break; } }
/*========================================== * 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; }