Cleaned up character deletion code (#2296)
* Fixes #2271 Thanks to @Tokeiburu
This commit is contained in:
parent
de3f924afc
commit
bbd42e7f12
@ -1518,22 +1518,34 @@ int char_divorce_char_sql(int partner_id1, int partner_id2){
|
||||
/* Returns 0 if successful
|
||||
* Returns < 0 for error
|
||||
*/
|
||||
int char_delete_char_sql(uint32 char_id){
|
||||
enum e_char_del_response char_delete(struct char_session_data* sd, uint32 char_id){
|
||||
char name[NAME_LENGTH];
|
||||
char esc_name[NAME_LENGTH*2+1]; //Name needs be escaped.
|
||||
uint32 account_id;
|
||||
int party_id, guild_id, hom_id, base_level, partner_id, father_id, mother_id, elemental_id;
|
||||
time_t delete_date;
|
||||
char *data;
|
||||
size_t len;
|
||||
int i, k;
|
||||
|
||||
if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `name`,`account_id`,`party_id`,`guild_id`,`base_level`,`homun_id`,`partner_id`,`father`,`mother`,`elemental_id` FROM `%s` WHERE `char_id`='%d'", schema_config.char_db, char_id))
|
||||
ARR_FIND(0, MAX_CHARS, i, sd->found_char[i] == char_id);
|
||||
|
||||
// Such a character does not exist in the account
|
||||
if (i == MAX_CHARS) {
|
||||
ShowInfo("Char deletion aborted: %s, Account ID: %u, Character ID: %u\n", name, sd->account_id, char_id);
|
||||
return CHAR_DELETE_NOTFOUND;
|
||||
}
|
||||
|
||||
if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `name`,`account_id`,`party_id`,`guild_id`,`base_level`,`homun_id`,`partner_id`,`father`,`mother`,`elemental_id`,`delete_date` FROM `%s` WHERE `account_id`='%u' AND `char_id`='%u'", schema_config.char_db, sd->account_id, char_id)){
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return CHAR_DELETE_DATABASE;
|
||||
}
|
||||
|
||||
if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
|
||||
{
|
||||
ShowError("delete_char_sql: Unable to fetch character data, deletion aborted.\n");
|
||||
ShowInfo("Char deletion aborted: %s, Account ID: %u, Character ID: %u\n", name, sd->account_id, char_id);
|
||||
Sql_FreeResult(sql_handle);
|
||||
return -1;
|
||||
return CHAR_DELETE_NOTFOUND;
|
||||
}
|
||||
|
||||
Sql_GetData(sql_handle, 0, &data, &len); safestrncpy(name, data, NAME_LENGTH);
|
||||
@ -1546,29 +1558,34 @@ int char_delete_char_sql(uint32 char_id){
|
||||
Sql_GetData(sql_handle, 7, &data, NULL); father_id = atoi(data);
|
||||
Sql_GetData(sql_handle, 8, &data, NULL); mother_id = atoi(data);
|
||||
Sql_GetData(sql_handle, 9, &data, NULL); elemental_id = atoi(data);
|
||||
Sql_GetData(sql_handle,10, &data, NULL); delete_date = strtoul(data, NULL, 10);
|
||||
|
||||
Sql_EscapeStringLen(sql_handle, esc_name, name, zmin(len, NAME_LENGTH));
|
||||
Sql_FreeResult(sql_handle);
|
||||
|
||||
//check for config char del condition [Lupus]
|
||||
// TODO: Move this out to packet processing (0x68/0x1fb).
|
||||
if( ( charserv_config.char_config.char_del_level > 0 && base_level >= charserv_config.char_config.char_del_level )
|
||||
|| ( charserv_config.char_config.char_del_level < 0 && base_level <= -charserv_config.char_config.char_del_level )
|
||||
) {
|
||||
ShowInfo("Char deletion aborted: %s, BaseLevel: %i\n", name, base_level);
|
||||
return -1;
|
||||
return CHAR_DELETE_BASELEVEL;
|
||||
}
|
||||
|
||||
if (charserv_config.char_config.char_del_restriction&CHAR_DEL_RESTRICT_GUILD && guild_id) // character is in guild
|
||||
{
|
||||
ShowInfo("Char deletion aborted: %s, Guild ID: %i\n", name, guild_id);
|
||||
return -1;
|
||||
return CHAR_DELETE_GUILD;
|
||||
}
|
||||
|
||||
if (charserv_config.char_config.char_del_restriction&CHAR_DEL_RESTRICT_PARTY && party_id) // character is in party
|
||||
{
|
||||
ShowInfo("Char deletion aborted: %s, Party ID: %i\n", name, party_id);
|
||||
return -1;
|
||||
return CHAR_DELETE_PARTY;
|
||||
}
|
||||
|
||||
if( charserv_config.char_config.char_del_delay > 0 && ( !delete_date || delete_date > time(NULL) ) ){ // not queued or delay not yet passed
|
||||
ShowInfo("Char deletion aborted: %s, Time was not set or has not been reached ye\n", name );
|
||||
return CHAR_DELETE_TIME;
|
||||
}
|
||||
|
||||
/* Divorce [Wizputer] */
|
||||
@ -1582,7 +1599,7 @@ int char_delete_char_sql(uint32 char_id){
|
||||
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `child`='0' WHERE `char_id`='%d' OR `char_id`='%d'", schema_config.char_db, father_id, mother_id) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '410'AND (`char_id`='%d' OR `char_id`='%d')", schema_config.skill_db, father_id, mother_id) )
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '410' AND (`char_id`='%d' OR `char_id`='%d')", schema_config.skill_db, father_id, mother_id) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
|
||||
WBUFW(buf,0) = 0x2b25;
|
||||
@ -1699,7 +1716,14 @@ int char_delete_char_sql(uint32 char_id){
|
||||
mapif_parse_BreakGuild(0,guild_id);
|
||||
else if( guild_id )
|
||||
inter_guild_leave(guild_id, account_id, char_id);// Leave your guild.
|
||||
return 0;
|
||||
|
||||
// refresh character list cache
|
||||
for(k = i; k < MAX_CHARS-1; k++){
|
||||
sd->found_char[k] = sd->found_char[k+1];
|
||||
}
|
||||
sd->found_char[MAX_CHARS-1] = -1;
|
||||
|
||||
return CHAR_DELETE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,16 @@ enum e_char_delete_restriction {
|
||||
CHAR_DEL_RESTRICT_ALL
|
||||
};
|
||||
|
||||
enum e_char_del_response {
|
||||
CHAR_DELETE_OK = 0,
|
||||
CHAR_DELETE_DATABASE,
|
||||
CHAR_DELETE_NOTFOUND,
|
||||
CHAR_DELETE_BASELEVEL,
|
||||
CHAR_DELETE_GUILD,
|
||||
CHAR_DELETE_PARTY,
|
||||
CHAR_DELETE_TIME,
|
||||
};
|
||||
|
||||
struct Schema_Config {
|
||||
int db_use_sqldbs;
|
||||
char db_path[1024];
|
||||
@ -272,7 +282,7 @@ int char_mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p);
|
||||
int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p);
|
||||
int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything);
|
||||
int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf);
|
||||
int char_delete_char_sql(uint32 char_id);
|
||||
enum e_char_del_response char_delete(struct char_session_data* sd, uint32 char_id);
|
||||
int char_rename_char_sql(struct char_session_data *sd, uint32 char_id);
|
||||
int char_divorce_char_sql(int partner_id1, int partner_id2);
|
||||
int char_memitemdata_to_sql(const struct item items[], int max, int id, enum storage_type tableswitch, uint8 stor_id);
|
||||
|
@ -437,8 +437,10 @@ void chclif_char_delete2_ack(int fd, uint32 char_id, uint32 result, time_t delet
|
||||
/// 3 (0x719): A database error occurred.
|
||||
/// 4 (0x71d): Deleting not yet possible time.
|
||||
/// 5 (0x71e): Date of birth do not match.
|
||||
/// 6 Name does not match.
|
||||
/// 7 Character Deletion has failed because you have entered an incorrect e-mail address.
|
||||
/// Any (0x718): An unknown error has occurred.
|
||||
/// HC: <082a>.W <char id>.L <Msg:0-5>.L
|
||||
/// HC: <082a>.W <char id>.L <Msg>.L
|
||||
void chclif_char_delete2_accept_ack(int fd, uint32 char_id, uint32 result) {
|
||||
#if PACKETVER >= 20130000
|
||||
if(result == 1 ){
|
||||
@ -563,10 +565,7 @@ int chclif_parse_char_delete2_accept(int fd, struct char_session_data* sd) {
|
||||
FIFOSD_CHECK(12)
|
||||
{
|
||||
char birthdate[8+1];
|
||||
uint32 char_id, i, k;
|
||||
unsigned int base_level;
|
||||
char* data;
|
||||
time_t delete_date;
|
||||
uint32 char_id;
|
||||
char_id = RFIFOL(fd,2);
|
||||
|
||||
ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, char_id);
|
||||
@ -583,54 +582,36 @@ int chclif_parse_char_delete2_accept(int fd, struct char_session_data* sd) {
|
||||
birthdate[8] = 0;
|
||||
RFIFOSKIP(fd,12);
|
||||
|
||||
ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == char_id );
|
||||
if( i == MAX_CHARS )
|
||||
{// character not found
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( SQL_SUCCESS != Sql_Query(sql_handle, "SELECT `base_level`,`delete_date` FROM `%s` WHERE `char_id`='%d'", schema_config.char_db, char_id) || SQL_SUCCESS != Sql_NextRow(sql_handle) )
|
||||
{// data error
|
||||
Sql_ShowDebug(sql_handle);
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Sql_GetData(sql_handle, 0, &data, NULL); base_level = (unsigned int)strtoul(data, NULL, 10);
|
||||
Sql_GetData(sql_handle, 1, &data, NULL); delete_date = strtoul(data, NULL, 10);
|
||||
|
||||
if( !delete_date || delete_date>time(NULL) )
|
||||
{// not queued or delay not yet passed
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!chclif_delchar_check(sd, birthdate, CHAR_DEL_BIRTHDATE)) { // Only check for birthdate
|
||||
// Only check for birthdate
|
||||
if (!chclif_delchar_check(sd, birthdate, CHAR_DEL_BIRTHDATE)) {
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( ( charserv_config.char_config.char_del_level > 0 && base_level >= (unsigned int)charserv_config.char_config.char_del_level )
|
||||
|| ( charserv_config.char_config.char_del_level < 0 && base_level <= (unsigned int)(-charserv_config.char_config.char_del_level) ) )
|
||||
{// character level config restriction
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 2);
|
||||
return 1;
|
||||
switch( char_delete(sd,char_id) ){
|
||||
// success
|
||||
case CHAR_DELETE_OK:
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 1);
|
||||
break;
|
||||
// data error
|
||||
case CHAR_DELETE_DATABASE:
|
||||
// character not found
|
||||
case CHAR_DELETE_NOTFOUND:
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 3);
|
||||
break;
|
||||
// in a party
|
||||
case CHAR_DELETE_PARTY:
|
||||
// in a guild
|
||||
case CHAR_DELETE_GUILD:
|
||||
// character level config restriction
|
||||
case CHAR_DELETE_BASELEVEL:
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 2);
|
||||
break;
|
||||
// not queued or delay not yet passed
|
||||
case CHAR_DELETE_TIME:
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 4);
|
||||
break;
|
||||
}
|
||||
|
||||
// success
|
||||
if( char_delete_char_sql(char_id) < 0 ){
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// refresh character list cache
|
||||
for(k = i; k < MAX_CHARS-1; k++){
|
||||
sd->found_char[k] = sd->found_char[k+1];
|
||||
}
|
||||
sd->found_char[MAX_CHARS-1] = -1;
|
||||
|
||||
chclif_char_delete2_accept_ack(fd, char_id, 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -993,7 +974,9 @@ int chclif_parse_createnewchar(int fd, struct char_session_data* sd,int cmd){
|
||||
* 0x70 <ErrorCode>B HC_REFUSE_DELETECHAR
|
||||
* @param fd
|
||||
* @param ErrorCode
|
||||
* 00 = Incorrect Email address
|
||||
* 00 = Incorrect Email address
|
||||
* 01 = Invalid Slot
|
||||
* 02 = In a party or guild
|
||||
*/
|
||||
void chclif_refuse_delchar(int fd, uint8 errCode){
|
||||
WFIFOHEAD(fd,3);
|
||||
@ -1008,10 +991,9 @@ int chclif_parse_delchar(int fd,struct char_session_data* sd, int cmd){
|
||||
else return 0;
|
||||
{
|
||||
char email[40];
|
||||
int i, ch;
|
||||
int cid = RFIFOL(fd,2);
|
||||
uint32 cid = RFIFOL(fd,2);
|
||||
|
||||
ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
|
||||
ShowInfo(CL_RED"Request Char Deletion: "CL_GREEN"%u (%u)"CL_RESET"\n", sd->account_id, cid);
|
||||
memcpy(email, RFIFOP(fd,6), 40);
|
||||
RFIFOSKIP(fd,( cmd == 0x68) ? 46 : 56);
|
||||
|
||||
@ -1020,26 +1002,24 @@ int chclif_parse_delchar(int fd,struct char_session_data* sd, int cmd){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check if this char exists
|
||||
ARR_FIND( 0, MAX_CHARS, i, sd->found_char[i] == cid );
|
||||
if( i == MAX_CHARS ) { // Such a character does not exist in the account
|
||||
chclif_refuse_delchar(fd,0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// remove char from list and compact it
|
||||
for(ch = i; ch < MAX_CHARS-1; ch++)
|
||||
sd->found_char[ch] = sd->found_char[ch+1];
|
||||
sd->found_char[MAX_CHARS-1] = -1;
|
||||
|
||||
/* Delete character */
|
||||
if(char_delete_char_sql(cid)<0){
|
||||
//can't delete the char
|
||||
//either SQL error or can't delete by some CONFIG conditions
|
||||
//del fail
|
||||
chclif_refuse_delchar(fd,0);
|
||||
return 1;
|
||||
switch( char_delete(sd,cid) ){
|
||||
case CHAR_DELETE_OK:
|
||||
break;
|
||||
case CHAR_DELETE_DATABASE:
|
||||
case CHAR_DELETE_BASELEVEL:
|
||||
case CHAR_DELETE_TIME:
|
||||
chclif_refuse_delchar(fd, 0);
|
||||
return 1;
|
||||
case CHAR_DELETE_NOTFOUND:
|
||||
chclif_refuse_delchar(fd, 1);
|
||||
return 1;
|
||||
case CHAR_DELETE_GUILD:
|
||||
case CHAR_DELETE_PARTY:
|
||||
chclif_refuse_delchar(fd, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Char successfully deleted.*/
|
||||
WFIFOHEAD(fd,2);
|
||||
WFIFOW(fd,0) = 0x6f;
|
||||
|
Loading…
x
Reference in New Issue
Block a user