Removed account gender (#5006)

Adds an upgrade script to change all existing entries to the respective gender in their account.
Cleanup of a few strange design decisions in the character server code.
Removed SEX_ACCOUNT.

Thanks to @Daegaladh for his help.
This commit is contained in:
Lemongrass3110 2020-06-04 17:23:50 +02:00 committed by GitHub
parent afaee2f01d
commit 3ab1ada8d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 134 additions and 101 deletions

View File

@ -252,7 +252,7 @@ CREATE TABLE IF NOT EXISTS `char` (
`unban_time` int(11) unsigned NOT NULL default '0',
`font` tinyint(3) unsigned NOT NULL default '0',
`uniqueitem_counter` int(11) unsigned NOT NULL default '0',
`sex` ENUM('M','F','U') NOT NULL default 'U',
`sex` ENUM('M','F') NOT NULL,
`hotkey_rowshift` tinyint(3) unsigned NOT NULL default '0',
`hotkey_rowshift2` tinyint(3) unsigned NOT NULL default '0',
`clan_id` int(11) unsigned NOT NULL default '0',

View File

@ -0,0 +1,13 @@
UPDATE `char` `c`
INNER JOIN `login` `l`
ON `l`.`account_id` = `c`.`account_id`
SET `c`.`sex` = `l`.`sex`
WHERE
`c`.`sex` = 'U'
AND
`l`.`sex` <> 'S'
;
ALTER TABLE `char`
MODIFY `sex` ENUM('M','F') NOT NULL
;

View File

@ -857,42 +857,24 @@ bool char_memitemdata_from_sql(struct s_storage* p, int max, int id, enum storag
*
* @retval SEX_MALE if the per-character sex is male
* @retval SEX_FEMALE if the per-character sex is female
* @retval SEX_ACCOUNT if the per-character sex is not defined or the current PACKETVER doesn't support it.
*/
int char_mmo_gender(const struct char_session_data *sd, const struct mmo_charstatus *p, char sex)
{
int char_mmo_gender( const struct char_session_data *sd, const struct mmo_charstatus *p, char sex ){
switch( sex ){
#if PACKETVER >= 20141016
(void)sd; (void)p; // Unused
switch (sex) {
case 'M':
return SEX_MALE;
case 'F':
return SEX_FEMALE;
case 'U':
default:
return SEX_ACCOUNT;
}
#else
if (sex == 'M' || sex == 'F') {
if (!sd) {
// sd is not available, there isn't much we can do. Just return and print a warning.
ShowWarning("Character '%s' (CID: %d, AID: %d) has sex '%c', but PACKETVER does not support per-character sex. Defaulting to 'U'.\n",
p->name, p->char_id, p->account_id, sex);
return SEX_ACCOUNT;
}
if ((sex == 'M' && sd->sex == SEX_FEMALE)
|| (sex == 'F' && sd->sex == SEX_MALE)) {
ShowWarning("Changing sex of character '%s' (CID: %d, AID: %d) to 'U' due to incompatible PACKETVER.\n", p->name, p->char_id, p->account_id);
chlogif_parse_ackchangecharsex(p->char_id, sd->sex);
} else {
ShowInfo("Resetting sex of character '%s' (CID: %d, AID: %d) to 'U' due to incompatible PACKETVER.\n", p->name, p->char_id, p->account_id);
}
if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `sex` = 'U' WHERE `char_id` = '%d'", schema_config.char_db, p->char_id)) {
Sql_ShowDebug(sql_handle);
}
}
return SEX_ACCOUNT;
case 'M':
case 'F':
// No matter what the database says, always return the account gender
return sd->sex;
#endif
default:
ShowWarning( "Found unknown gender '%c' for character '%s' (CID: %d, AID: %d), returning account gender...\n", sex, p->name, p->char_id, p->account_id );
return sd->sex;
}
}
int char_mmo_char_tobuf(uint8* buf, struct mmo_charstatus* p);
@ -1383,22 +1365,14 @@ int char_check_char_name(char * name, char * esc_name)
//-----------------------------------
// Function to create a new character
//-----------------------------------
#if PACKETVER >= 20120307
#if PACKETVER >= 20151001
int char_make_new_char_sql(struct char_session_data* sd, char* name_, int slot, int hair_color, int hair_style, short start_job, short unknown, int sex) { // TODO: Unknown byte
#else
int char_make_new_char_sql(struct char_session_data* sd, char* name_, int slot, int hair_color, int hair_style) {
#endif
int str = 1, agi = 1, vit = 1, int_ = 1, dex = 1, luk = 1;
#else
int char_make_new_char_sql(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) {
#endif
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 startitem tmp_start_items[MAX_STARTITEM];
uint32 char_id;
int flag, k, start_point_idx = rnd() % charserv_config.start_point_count;
int status_points;
safestrncpy(name, name_, NAME_LENGTH);
normalize_name(name,TRIM_CHARS);
@ -1413,32 +1387,51 @@ int char_make_new_char_sql(struct char_session_data* sd, char* name_, int str, i
if( flag < 0 )
return flag;
//check other inputs
#if PACKETVER >= 20120307
#if PACKETVER >= 20151001
switch(sex) {
case SEX_FEMALE:
sex = 'F';
break;
case SEX_MALE:
sex = 'M';
break;
default:
sex = 'U';
break;
}
#endif
if(slot < 0 || slot >= sd->char_slots)
#else
if((slot < 0 || slot >= sd->char_slots) // slots
|| (str + agi + vit + int_ + dex + luk != 6*5 ) // stats
|| (str < 1 || str > 9 || agi < 1 || agi > 9 || vit < 1 || vit > 9 || int_ < 1 || int_ > 9 || dex < 1 || dex > 9 || luk < 1 || luk > 9) // individual stat values
|| (str + int_ != 10 || agi + luk != 10 || vit + dex != 10) ) // pairs
#endif
#if PACKETVER >= 20100413
// Check inputs from the client - never trust it!
// Check the slot
if( slot < 0 || slot >= sd->char_slots ){
return -4; // invalid slot
#else
}
// Check gender
switch( sex ){
case SEX_FEMALE:
sex = 'F';
break;
case SEX_MALE:
sex = 'M';
break;
default:
ShowWarning( "Received unsupported gender '%d'...\n", sex );
return -2; // invalid input
}
// Check status values
#if PACKETVER < 20120307
// All stats together always have to add up to a total of 30 points
if( ( str + agi + vit + int_ + dex + luk ) != 30 ){
return -2; // invalid input
}
// No status can be below 1
if( str < 1 || agi < 1 || vit < 1 || int_ < 1 || dex < 1 || luk < 1 ){
return -2; // invalid input
}
// No status can be higher than 9
if( str > 9 || agi > 9 || vit > 9 || int_ > 9 || dex > 9 || luk > 9 ){
return -2; // invalid input
}
// The status pairs always have to add up to a total of 10 points
if( ( str + int_ ) != 10 || ( agi + luk ) != 10 || ( vit + dex ) != 10 ){
return -2; // invalid input
}
status_points = 0;
#else
status_points = 48;
#endif
// check the number of already existing chars in this account
@ -1482,28 +1475,12 @@ int char_make_new_char_sql(struct char_session_data* sd, char* name_, int str, i
#endif
//Insert the new char entry to the database
#if PACKETVER >= 20151001
if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `class`, `zeny`, `status_point`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`,"
"`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`, `sex`) VALUES ("
"'%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, 48, str, agi, vit, int_, dex, luk,
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) )
#elif PACKETVER >= 20120307
if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `status_point`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`,"
"`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`) VALUES ("
"'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%u', '%u', '%u', '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
schema_config.char_db, sd->account_id , slot, esc_name, charserv_config.start_zeny, 48, 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) )
#else
if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `zeny`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`,"
"`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`) VALUES ("
"'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%u', '%u', '%u', '%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
schema_config.char_db, sd->account_id , slot, esc_name, charserv_config.start_zeny, 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) )
#endif
{
Sql_ShowDebug(sql_handle);
return -2; //No, stop the procedure!

View File

@ -306,13 +306,7 @@ void char_auth_ok(int fd, struct char_session_data *sd);
void char_set_charselect(uint32 account_id);
void char_read_fame_list(void);
#if PACKETVER >= 20151001
int char_make_new_char_sql(struct char_session_data* sd, char* name_, int slot, int hair_color, int hair_style, short start_job, short unknown, int sex);
#elif PACKETVER >= 20120307
int char_make_new_char_sql(struct char_session_data* sd, char* name_, int slot, int hair_color, int hair_style);
#else
int char_make_new_char_sql(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);
#endif
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 );
void char_set_session_flag_(int account_id, int val, bool set);
#define char_set_session_flag(account_id, val) ( char_set_session_flag_((account_id), (val), true) )

View File

@ -855,8 +855,6 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){
//Have to switch over to the DB instance otherwise data won't propagate [Kevin]
cd = (struct mmo_charstatus *)idb_get(char_db_, char_id);
if (cd->sex == SEX_ACCOUNT)
cd->sex = sd->sex;
if (charserv_config.log_char) {
char esc_name[NAME_LENGTH*2+1];
@ -951,16 +949,72 @@ int chclif_parse_createnewchar(int fd, struct char_session_data* sd,int cmd){
if( (charserv_config.char_new)==0 ) //turn character creation on/off [Kevin]
char_id = -2;
else {
char name[NAME_LENGTH];
int str, agi, vit, int_, dex, luk;
int slot;
int hair_color;
int hair_style;
short start_job;
int sex;
#if PACKETVER >= 20151001
char_id = char_make_new_char_sql(sd, RFIFOCP(fd,2),RFIFOB(fd,26),RFIFOW(fd,27),RFIFOW(fd,29),RFIFOW(fd,31),RFIFOW(fd,32),RFIFOB(fd,35));
RFIFOSKIP(fd,36);
// Sent values
safestrncpy( name, RFIFOCP( fd, 2 ), NAME_LENGTH );
slot = RFIFOB( fd, 26 );
hair_color = RFIFOW( fd, 27 );
hair_style = RFIFOW( fd, 29 );
start_job = RFIFOW( fd, 31 );
// Unknown RFIFOW( fd, 32 )
sex = RFIFOB( fd, 35 );
// Default values
str = 1;
agi = 1;
vit = 1;
int_ = 1;
dex = 1;
luk = 1;
RFIFOSKIP( fd, 36 );
#elif PACKETVER >= 20120307
char_id = char_make_new_char_sql(sd, RFIFOCP(fd,2),RFIFOB(fd,26),RFIFOW(fd,27),RFIFOW(fd,29));
RFIFOSKIP(fd,31);
// Sent values
safestrncpy( name, RFIFOCP( fd, 2 ), NAME_LENGTH );
slot = RFIFOB( fd, 26 );
hair_color = RFIFOW( fd, 27 );
hair_style = RFIFOW( fd, 29 );
// Default values
str = 1;
agi = 1;
vit = 1;
int_ = 1;
dex = 1;
luk = 1;
start_job = JOB_NOVICE;
sex = sd->sex;
RFIFOSKIP( fd, 31 );
#else
char_id = char_make_new_char_sql(sd, RFIFOCP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27),RFIFOB(fd,28),RFIFOB(fd,29),RFIFOB(fd,30),RFIFOB(fd,31),RFIFOB(fd,32),RFIFOW(fd,33),RFIFOW(fd,35));
RFIFOSKIP(fd,37);
// Sent values
safestrncpy( name, RFIFOCP( fd, 2 ), NAME_LENGTH );
str = RFIFOB( fd, 26 );
agi = RFIFOB( fd, 27 );
vit = RFIFOB( fd, 28 );
int_ = RFIFOB( fd, 29 );
dex = RFIFOB( fd, 30 );
luk = RFIFOB( fd, 31 );
slot = RFIFOB( fd, 32 );
hair_color = RFIFOW( fd, 33 );
hair_style = RFIFOW( fd, 35 );
// Default values
start_job = JOB_NOVICE;
sex = sd->sex;
RFIFOSKIP( fd, 37 );
#endif
char_id = char_make_new_char( sd, name, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, start_job, sex );
}
if (char_id < 0) {

View File

@ -1013,8 +1013,6 @@ int chmapif_parse_reqauth(int fd, int id){
}
if( runflag == CHARSERVER_ST_RUNNING && autotrade && cd ){
uint16 mmo_charstatus_len = sizeof(struct mmo_charstatus) + 25;
if (cd->sex == SEX_ACCOUNT)
cd->sex = sex;
WFIFOHEAD(fd,mmo_charstatus_len);
WFIFOW(fd,0) = 0x2afd;
@ -1042,8 +1040,6 @@ int chmapif_parse_reqauth(int fd, int id){
)
{// auth ok
uint16 mmo_charstatus_len = sizeof(struct mmo_charstatus) + 25;
if (cd->sex == SEX_ACCOUNT)
cd->sex = sex;
WFIFOHEAD(fd,mmo_charstatus_len);
WFIFOW(fd,0) = 0x2afd;

View File

@ -971,8 +971,7 @@ enum e_job {
enum e_sex {
SEX_FEMALE = 0,
SEX_MALE,
SEX_SERVER,
SEX_ACCOUNT = 99
SEX_SERVER
};
/// Item Bound Type