/*========================================== * Request sc_data from charserver [Skotlex] *------------------------------------------*/ int chrif_scdata_request(int account_id, int char_id) { #ifdef ENABLE_SC_SAVING chrif_check(-1); WFIFOHEAD(char_fd,10); WFIFOW(char_fd,0) = 0x2afc; WFIFOL(char_fd,2) = account_id; WFIFOL(char_fd,6) = char_id; WFIFOSET(char_fd,10); #endif return 0; }
/*========================================== * Search Char trough id on char serv *------------------------------------------*/ int chrif_searchcharid(int char_id) { if( !char_id ) return -1; chrif_check(-1); WFIFOHEAD(char_fd,6); WFIFOW(char_fd,0) = 0x2b08; WFIFOL(char_fd,2) = char_id; WFIFOSET(char_fd,6); return 0; }
/*========================================== * Change Email *------------------------------------------*/ int chrif_changeemail(int id, const char *actual_email, const char *new_email) { if (battle_config.etc_log) ShowInfo("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", id, actual_email, new_email); chrif_check(-1); WFIFOHEAD(char_fd,86); WFIFOW(char_fd,0) = 0x2b0c; WFIFOL(char_fd,2) = id; memcpy(WFIFOP(char_fd,6), actual_email, 40); memcpy(WFIFOP(char_fd,46), new_email, 40); WFIFOSET(char_fd,86); return 0; }
/*========================================== * GMに変化要求 *------------------------------------------*/ int chrif_changegm(int id, const char *pass, int len) { if (battle_config.etc_log) ShowInfo("chrif_changegm: account: %d, password: '******'.\n", id, pass); chrif_check(-1); WFIFOHEAD(char_fd, len + 8); WFIFOW(char_fd,0) = 0x2b0a; WFIFOW(char_fd,2) = len + 8; WFIFOL(char_fd,4) = id; memcpy(WFIFOP(char_fd,8), pass, len); WFIFOSET(char_fd, len + 8); return 0; }
int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the player and sends it to the char-server for saving. [Skotlex] #ifdef ENABLE_SC_SAVING int i, count=0; unsigned int tick; struct status_change_data data; struct status_change *sc = &sd->sc; const struct TimerData *timer; chrif_check(-1); tick = gettick(); WFIFOHEAD(char_fd, 14 + SC_MAX*sizeof(struct status_change_data)); WFIFOW(char_fd,0) = 0x2b1c; WFIFOL(char_fd,4) = sd->status.account_id; WFIFOL(char_fd,8) = sd->status.char_id; for (i = 0; i < SC_MAX; i++) { if (!sc->data[i]) continue; if (sc->data[i]->timer != INVALID_TIMER) { timer = get_timer(sc->data[i]->timer); if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0) continue; data.tick = DIFF_TICK(timer->tick,tick); //Duration that is left before ending. } else data.tick = -1; //Infinite duration data.type = i; data.val1 = sc->data[i]->val1; data.val2 = sc->data[i]->val2; data.val3 = sc->data[i]->val3; data.val4 = sc->data[i]->val4; memcpy(WFIFOP(char_fd,14 +count*sizeof(struct status_change_data)), &data, sizeof(struct status_change_data)); count++; } if (count == 0) return 0; //Nothing to save. WFIFOW(char_fd,12) = count; WFIFOW(char_fd,2) = 14 +count*sizeof(struct status_change_data); //Total packet size WFIFOSET(char_fd,WFIFOW(char_fd,2)); #endif return 0; }
// unused int send_usercount_tochar(int tid, unsigned int tick, int id, int data) { int count = 0; struct s_mapiterator* iter; chrif_check(-1); iter = mapit_getallusers(); for( mapit_first(iter); mapit_exists(iter); mapit_next(iter) ) count++; mapit_free(iter); WFIFOHEAD(char_fd,4); WFIFOW(char_fd,0) = 0x2afe; WFIFOW(char_fd,2) = count; WFIFOSET(char_fd,4); return 0; }
int chrif_changesex(struct map_session_data *sd) { chrif_check(-1); WFIFOHEAD(char_fd,44); WFIFOW(char_fd,0) = 0x2b0e; WFIFOL(char_fd,2) = sd->status.account_id; safestrncpy((char*)WFIFOP(char_fd,6), sd->status.name, NAME_LENGTH); WFIFOW(char_fd,30) = 5; WFIFOSET(char_fd,44); clif_displaymessage(sd->fd, "Necess�rio desconectar para realizar a mudan�a de sexo..."); if (sd->fd) clif_authfail_fd(sd->fd, 15); else map_quit(sd); return 0; }
/*========================================== * *------------------------------------------*/ int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip) { nullpo_retr(-1, sd); if( !sd || !sd->bl.id || !sd->login_id1 ) return -1; chrif_check(-1); WFIFOHEAD(char_fd,18); WFIFOW(char_fd, 0) = 0x2b02; 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) = htonl(s_ip); WFIFOSET(char_fd,18); return 0; }
int chrif_changesex(struct map_session_data *sd) { chrif_check(-1); WFIFOHEAD(char_fd,44); WFIFOW(char_fd,0) = 0x2b0e; WFIFOL(char_fd,2) = sd->status.account_id; safestrncpy((char*)WFIFOP(char_fd,6), sd->status.name, NAME_LENGTH); WFIFOW(char_fd,30) = 5; WFIFOSET(char_fd,44); clif->message(sd->fd, msg_txt(408)); //"Need disconnection to perform change-sex request..." if (sd->fd) clif->authfail_fd(sd->fd, 15); else map_quit(sd); return 0; }
int send_usercount_tochar(int tid, unsigned int tick, int id, int data) { int count; static int last_count = 0; chrif_check(-1); map_getallusers(&count); if (count == last_count) //No need to waste packets. return 0; last_count = count; WFIFOHEAD(char_fd,4); WFIFOW(char_fd,0) = 0x2afe; WFIFOW(char_fd,2) = count; WFIFOSET(char_fd,4); return 0; }
/*========================================== * S 2b0e <accid>.l <name>.24B <type>.w { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w } * Send an account modification request to the login server (via char server). * type of operation: * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5) *------------------------------------------*/ int chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) { chrif_check(-1); WFIFOHEAD(char_fd,44); WFIFOW(char_fd,0) = 0x2b0e; WFIFOL(char_fd,2) = acc; safestrncpy((char*)WFIFOP(char_fd,6), character_name, NAME_LENGTH); WFIFOW(char_fd,30) = operation_type; if (operation_type == 2) { WFIFOW(char_fd,32) = year; WFIFOW(char_fd,34) = month; WFIFOW(char_fd,36) = day; WFIFOW(char_fd,38) = hour; WFIFOW(char_fd,40) = minute; WFIFOW(char_fd,42) = second; } WFIFOSET(char_fd,44); return 0; }
/*========================================== * timer関数 * 今このmap鯖に繋がっているクライアント人数をchar鯖へ送る *------------------------------------------*/ int send_users_tochar(int tid, unsigned int tick, int id, int data) { int count, users=0, i; struct map_session_data **all_sd; chrif_check(-1); all_sd = map_getallusers(&count); WFIFOHEAD(char_fd, 6+8*users); WFIFOW(char_fd,0) = 0x2aff; for (i = 0; i < count; i++) { WFIFOL(char_fd,6+8*users) = all_sd[i]->status.account_id; WFIFOL(char_fd,6+8*users+4) = all_sd[i]->status.char_id; users++; } WFIFOW(char_fd,2) = 6 + 8 * users; WFIFOW(char_fd,4) = users; WFIFOSET(char_fd,6+8*users); return 0; }
/*========================================== * Request/Receive top 10 Fame character list *------------------------------------------*/ int chrif_updatefamelist(struct map_session_data* sd) { char type; chrif_check(-1); switch(sd->class_ & MAPID_UPPERMASK) { case MAPID_BLACKSMITH: type = 1; break; case MAPID_ALCHEMIST: type = 2; break; case MAPID_TAEKWON: type = 3; break; default: return 0; } WFIFOHEAD(char_fd, 11); WFIFOW(char_fd,0) = 0x2b10; WFIFOL(char_fd,2) = sd->status.char_id; WFIFOL(char_fd,6) = sd->status.fame; WFIFOB(char_fd,10) = type; WFIFOSET(char_fd,11); return 0; }
/*========================================== * Send message to char-server with a character name to do some operations (by Yor) * Used to ask Char-server about a character name to have the account number to modify account file in login-server. * type of operation: * 1: block * 2: ban * 3: unblock * 4: unban * 5: changesex *------------------------------------------*/ int chrif_char_ask_name(int id, char * character_name, short operation_type, int year, int month, int day, int hour, int minute, int second) { chrif_check(-1); WFIFOHEAD(char_fd, 44); WFIFOW(char_fd, 0) = 0x2b0e; WFIFOL(char_fd, 2) = id; // account_id of who ask (for answer) -1 if nobody memcpy(WFIFOP(char_fd,6), character_name, NAME_LENGTH); WFIFOW(char_fd, 30) = operation_type; // type of operation if (operation_type == 2) { WFIFOW(char_fd, 32) = year; WFIFOW(char_fd, 34) = month; WFIFOW(char_fd, 36) = day; WFIFOW(char_fd, 38) = hour; WFIFOW(char_fd, 40) = minute; WFIFOW(char_fd, 42) = second; } // ShowInfo("chrif : sent 0x2b0e\n"); WFIFOSET(char_fd,44); return 0; }
int ping_char_server(int tid, unsigned int tick, int id, int data) { chrif_check(-1); chrif_keepalive(char_fd); return 0; }
int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data) { chrif_check(0); auth_db->foreach(auth_db, auth_db_cleanup_sub); 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; }