Improved char_del_option

* Renamed to `char_deletion_code` and moved to login_athena.conf
* The value is now using column name instead the number, available options are:
  * `email` (except a@a.com),
  * `birthday` (YYMMDD),
  * `pincode`,
  * and the last is `Sub-query` which allows you to defines your custom deletion code (as example you ask user for secret code while registering an account, or one-time-password for character deletion)
* Extends E-mail length from 39 to 49
* Reordering `0x2717` to make notation with variable length be on last
This commit is contained in:
Cydh Ramdh 2018-07-02 17:28:58 +07:00
parent 3faf700443
commit 4b434fa669
14 changed files with 148 additions and 148 deletions

View File

@ -170,18 +170,6 @@ char_del_level: 0
// NOTE: Requires client 2010-08-03aragexeRE or newer.
char_del_delay: 86400
// Restrict character deletion by email address or birthdate.
// This restricts players from changing the langtype and deleting characters.
// Defaults based on client date.
// 1: Email address
// 2: Birthdate
// 3: Email address or Birthdate
// IMPORTANT!
// - This config only works for clients that send 0x0068 or 0x01fb for delete request.
// - Use langtype 1 for newer clients (2013+), to use 0x01fb.
// - Clients that are not using 0x0068 or 0x01fb, only use birthdate (YYMMDD) as default.
char_del_option: 2
// Restrict character deletion as long as he is still in a party or guild
// 0: No restriction is applied
// 1: Character cannot be deleted as long as he remains in a party

View File

@ -110,6 +110,18 @@ start_limited_time: -1
// NOTE: Will not work with clients that use <passwordencrypt>
use_MD5_passwords: no
// Available values, choose one
// `email` : Email address
// `birthdate` : Birthdate (YYMMDD of birthdate, YY is last 2 digit of birth year)
// `pincode` : Pincode (pin that used in login)
// (Sub-query) : EXPERT ONLY
//
// IMPORTANT!
// - Length of confirmation code which is sent by client depends on its packet
// - Packet 0x0068 is 39 chars, 0x01fb is 49 chars, while 0x0829 only 6 chars.
// - For 2013 clients must use langtype 1 to uses 0x01fb
char_deletion_code: `birthdate`
// Ipban features
ipban_enable: yes
// Dynamic password failure ipban system

View File

@ -89,22 +89,23 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket.
0x2717
Type: AH
Structure: <cmd>.W <aid>.L <email>.40B <expiration_time>.L <group_id>.B <char_slots>.B <birthdate>.11B <pincode>.5B <pincode_change>.L <isvip>.B <char_vip>.B <MAX_CHAR_BILLING>.B
index: 0,2,6,46,50,51,52,63,68,72,73,74
Structure: <cmd>.W <aid>.L <expiration_time>.L <group_id>.B <char_slots>.B <pincode_change>.L <isvip>.B <char_vip>.B <MAX_CHAR_BILLING>.B <email>.50S <birthdate>.11S <pincode>.5S <deletion_code>.50S
index: 0,2,6,10,11,12,16,17,18,19,69,80,85
len: 75
parameter:
- cmd: packet identification (0x2717)
- aid: account identification
- email: email of aid
- expiration_time: unknow @FIXME
- group_id: the group the aid belong too
- char_slots: number of slot available the account have (will be displayed on client)
- birthdate: birthdate of aid
- pincode: current pincode of aid
- pincode_change: new pincode of aid
- isvip: if this aid is currently vip or not
- char_vip: number of charslot that are vip (could only do creation on if you are vip)
- MAX_CHAR_BILLING: number of charslort that are for billing
- email: email of aid
- birthdate: birthdate of aid
- pincode: current pincode of aid
- deletion_code: code used for deleting character
desc:
- Request account data

View File

@ -705,7 +705,7 @@ CREATE TABLE IF NOT EXISTS `login` (
`userid` varchar(23) NOT NULL default '',
`user_pass` varchar(32) NOT NULL default '',
`sex` enum('M','F','S') NOT NULL default 'M',
`email` varchar(39) NOT NULL default '',
`email` varchar(49) NOT NULL default '',
`group_id` tinyint(3) NOT NULL default '0',
`state` int(11) unsigned NOT NULL default '0',
`unban_time` int(11) unsigned NOT NULL default '0',

View File

@ -0,0 +1 @@
ALTER TABLE `login` MODIFY COLUMN `email` VARCHAR(49) NULL DEFAULT '';

View File

@ -7,7 +7,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include "../common/cbasetypes.hpp"
@ -2704,11 +2704,6 @@ void char_set_defaults(){
charserv_config.char_config.char_per_account = 0; //Maximum chars per account (default unlimited) [Sirius]
charserv_config.char_config.char_del_level = 0; //From which level u can delete character [Lupus]
charserv_config.char_config.char_del_delay = 86400;
#if PACKETVER >= 20100803
charserv_config.char_config.char_del_option = CHAR_DEL_BIRTHDATE;
#else
charserv_config.char_config.char_del_option = CHAR_DEL_EMAIL;
#endif
charserv_config.char_config.char_del_restriction = CHAR_DEL_RESTRICT_ALL;
// charserv_config.userid[24];
@ -2996,8 +2991,6 @@ bool char_config_read(const char* cfgName, bool normal){
charserv_config.char_config.char_del_level = atoi(w2);
} else if (strcmpi(w1, "char_del_delay") == 0) {
charserv_config.char_config.char_del_delay = atoi(w2);
} else if (strcmpi(w1, "char_del_option") == 0) {
charserv_config.char_config.char_del_option = atoi(w2);
} else if (strcmpi(w1, "char_del_restriction") == 0) {
charserv_config.char_config.char_del_restriction = atoi(w2);
} else if (strcmpi(w1, "char_rename_party") == 0) {
@ -3080,12 +3073,6 @@ bool char_config_read(const char* cfgName, bool normal){
* Checks for values out of range.
*/
void char_config_adjust() {
#if PACKETVER < 20100803
if (charserv_config.char_config.char_del_option&CHAR_DEL_BIRTHDATE) {
ShowWarning("conf/char_athena.conf:char_del_option birthdate is enabled but it requires PACKETVER 2010-08-03 or newer, defaulting to email...\n");
charserv_config.char_config.char_del_option &= ~CHAR_DEL_BIRTHDATE;
}
#endif
}
/*

View File

@ -4,6 +4,8 @@
#ifndef _CHAR_HPP_
#define _CHAR_HPP_
#include <string>
#include "../common/core.hpp" // CORE_ST_LAST
#include "../common/mmo.hpp"
#include "../common/msg_conf.hpp"
@ -22,11 +24,6 @@ enum E_CHARSERVER_ST {
CHARSERVER_ST_LAST
};
enum e_char_delete {
CHAR_DEL_EMAIL = 1,
CHAR_DEL_BIRTHDATE
};
enum e_char_delete_restriction {
CHAR_DEL_RESTRICT_PARTY = 1,
CHAR_DEL_RESTRICT_GUILD,
@ -133,7 +130,6 @@ struct Char_Config {
char unknown_char_name[NAME_LENGTH]; // Name to use when the requested name cannot be determined
char char_name_letters[1024]; // list of letters/symbols allowed (or not) in a character name. by [Yor]
int char_name_option; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor]
int char_del_option; // Character deletion type, email = 1, birthdate = 2 (default)
int char_del_restriction; // Character deletion restriction (0: none, 1: if the character is in a party, 2: if the character is in a guild, 3: if the character is in a party or a guild)
bool char_rename_party; // Character renaming in a party
bool char_rename_guild; // Character renaming in a guild
@ -229,7 +225,7 @@ struct char_session_data {
bool auth; // whether the session is authed or not
uint32 account_id, login_id1, login_id2, sex;
int found_char[MAX_CHARS]; // ids of chars on this account
char email[40]; // e-mail (default: a@a.com) by [Yor]
char email[49+1]; // e-mail (default: a@a.com) by [Yor]
time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
int group_id; // permission
uint8 char_slots; // total number of characters that can be created
@ -249,6 +245,7 @@ struct char_session_data {
time_t unban_time[MAX_CHARS];
int charblock_timer;
uint8 flag; // &1 - Retrieving guild bound items
std::string deletion_passcode;
};

View File

@ -4,7 +4,7 @@
#include "char_clif.hpp"
#include <stdlib.h>
#include <string.h>
#include <string>
#include "../common/malloc.hpp"
#include "../common/mapindex.hpp"
@ -535,58 +535,40 @@ int chclif_parse_char_delete2_req(int fd, struct char_session_data* sd) {
/**
* Check char deletion code
* @param sd
* @param delcode E-mail or birthdate
* @param flag Delete flag
* @param char_id Requested Char ID
* @param delcode Deletion code from cleint
* @return true:Success, false:Failure
**/
bool chclif_delchar_check(struct char_session_data *sd, char *delcode, uint8 flag) {
// E-Mail check
if (flag&CHAR_DEL_EMAIL && (
!stricmp(delcode, sd->email) || //email does not match or
(
!stricmp("a@a.com", sd->email) && //it is default email and
!strcmp("", delcode) //user sent an empty email
))) {
ShowInfo("" CL_RED "Char Deleted" CL_RESET " " CL_GREEN "(E-Mail)" CL_RESET ".\n");
return true;
bool chclif_delchar_check(struct char_session_data *sd, uint32 char_id, std::string delcode) {
if (!sd->deletion_passcode.size()) {
ShowInfo("Character deletion failed, player's deletion code is never been set yet.\n");
return false;
}
// Birthdate (YYMMDD)
if (flag&CHAR_DEL_BIRTHDATE && (
!strcmp(sd->birthdate+2, delcode) || // +2 to cut off the century
(
!strcmp("",sd->birthdate) && // it is default birthdate and
!strcmp("",delcode) // user sent an empty birthdate
))) {
ShowInfo("" CL_RED "Char Deleted" CL_RESET " " CL_GREEN "(Birthdate)" CL_RESET ".\n");
return true;
if (sd->deletion_passcode != delcode) {
ShowInfo("Character deletion failed. Player's deletion code is invalid.\n");
return false;
}
return false;
ShowInfo("" CL_RED "Deleted" CL_RESET " char_id:%u.\n", char_id);
return true;
}
// CH: <0829>.W <char id>.L <birth date:YYMMDD>.6B
int chclif_parse_char_delete2_accept(int fd, struct char_session_data* sd) {
FIFOSD_CHECK(12)
{
char birthdate[8+1];
char birthdate[6+1];
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);
// construct "YY-MM-DD"
birthdate[0] = RFIFOB(fd,6);
birthdate[1] = RFIFOB(fd,7);
birthdate[2] = '-';
birthdate[3] = RFIFOB(fd,8);
birthdate[4] = RFIFOB(fd,9);
birthdate[5] = '-';
birthdate[6] = RFIFOB(fd,10);
birthdate[7] = RFIFOB(fd,11);
birthdate[8] = 0;
safestrncpy(birthdate, (char*)RFIFOP(fd, 6), sizeof(birthdate));
RFIFOSKIP(fd,12);
// Only check for birthdate
if (!chclif_delchar_check(sd, birthdate, CHAR_DEL_BIRTHDATE)) {
if (!chclif_delchar_check(sd, char_id, birthdate)) {
chclif_char_delete2_accept_ack(fd, char_id, 5);
return 1;
}
@ -988,19 +970,23 @@ void chclif_refuse_delchar(int fd, uint8 errCode){
WFIFOSET(fd,3);
}
/**
* CH <0068>.W <char_id>.L <email>.40S
* CH <01FB>.W <char_id>.L <email>.50S
*/
int chclif_parse_delchar(int fd,struct char_session_data* sd, int cmd){
if (cmd == 0x68) FIFOSD_CHECK(46)
else if (cmd == 0x1fb) FIFOSD_CHECK(56)
else return 0;
int offset = (cmd == 0x1fb) ? 10 : 0;
size_t len = 46 + offset;
FIFOSD_CHECK(len)
{
char email[40];
char delcode[49+1];
uint32 cid = RFIFOL(fd,2);
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);
safestrncpy(delcode, (char*)RFIFOP(fd,6), 40 + offset);
RFIFOSKIP(fd, len);
if (!chclif_delchar_check(sd, email, charserv_config.char_config.char_del_option)) {
if (!chclif_delchar_check(sd, cid, delcode)) {
chclif_refuse_delchar(fd,0); // 00 = Incorrect Email address
return 1;
}

View File

@ -4,7 +4,7 @@
#include "char_logif.hpp"
#include <stdlib.h>
#include <string.h>
#include <string>
#include "../common/showmsg.hpp"
#include "../common/socket.hpp"
@ -332,11 +332,11 @@ int chlogif_parse_ackaccreq(int fd, struct char_session_data* sd){
/**
* Receive account data from login-server
* AH 0x2717 <aid>.L <email>.40B <expiration_time>.L <group_id>.B <birthdate>.11B <pincode>.5B <pincode_change>.L <isvip>.B <char_vip>.B <char_billing>.B
* AH 0x2717 <aid>.L <expiration_time>.L <group_id>.B <pincode_change>.L <isvip>.B <char_vip>.B <char_billing>.B <email>.50B <birthdate>.11B <pincode>.5B <deletion_passcode>.50B
**/
int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
int u_fd; //user fd
if (RFIFOREST(fd) < 75)
if (RFIFOREST(fd) < 135)
return 0;
// find the authenticated session with this account id
@ -344,21 +344,22 @@ int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
if( u_fd < fd_max )
{
int server_id;
memcpy(sd->email, RFIFOP(fd,6), 40);
sd->expiration_time = (time_t)RFIFOL(fd,46);
sd->group_id = RFIFOB(fd,50);
sd->char_slots = RFIFOB(fd,51);
sd->expiration_time = (time_t)RFIFOL(fd, 6);
sd->group_id = RFIFOB(fd, 10);
sd->char_slots = RFIFOB(fd, 11);
if( sd->char_slots > MAX_CHARS ) {
ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.hpp! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots);
sd->char_slots = MAX_CHARS;/* cap to maximum */
} else if ( !sd->char_slots )/* no value aka 0 in sql */
sd->char_slots = MIN_CHARS;/* cap to minimum */
safestrncpy(sd->birthdate, RFIFOCP(fd,52), sizeof(sd->birthdate));
safestrncpy(sd->pincode, RFIFOCP(fd,63), sizeof(sd->pincode));
sd->pincode_change = (time_t)RFIFOL(fd,68);
sd->isvip = RFIFOB(fd,72);
sd->chars_vip = RFIFOB(fd,73);
sd->chars_billing = RFIFOB(fd,74);
sd->pincode_change = (time_t)RFIFOL(fd, 12);
sd->isvip = RFIFOB(fd, 16);
sd->chars_vip = RFIFOB(fd, 17);
sd->chars_billing = RFIFOB(fd, 18);
safestrncpy(sd->email, RFIFOCP(fd, 19), sizeof(sd->email));
safestrncpy(sd->birthdate, RFIFOCP(fd, 69), sizeof(sd->birthdate));
safestrncpy(sd->pincode, RFIFOCP(fd, 80), sizeof(sd->pincode));
sd->deletion_passcode = RFIFOCP(fd, 85);
ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, map_server[server_id].fd > 0 && map_server[server_id].map[0] );
// continued from char_auth_ok...
if( server_id == ARRAYLENGTH(map_server) || //server not online, bugreport:2359
@ -374,7 +375,7 @@ int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
#endif
}
}
RFIFOSKIP(fd,75);
RFIFOSKIP(fd, 135);
return 1;
}

View File

@ -2,10 +2,11 @@
// For more information, see LICENCE in the main folder
#include "account.hpp"
#include "login.hpp"
#include <algorithm> //min / max
#include <stdlib.h>
#include <string.h>
#include <string>
#include "../common/malloc.hpp"
#include "../common/mmo.hpp"
@ -495,12 +496,13 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, uint32
// retrieve login entry for the specified account
if( SQL_ERROR == Sql_Query(sql_handle,
"SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change`"
", IF(`sex` != 'S',%s,'') AS delcode"
#ifdef VIP_ENABLE
"SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change`, `vip_time`, `old_group` FROM `%s` WHERE `account_id` = %d",
#else
"SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change` FROM `%s` WHERE `account_id` = %d",
", `vip_time`, `old_group`"
#endif
db->account_db, account_id )
" FROM `%s` WHERE `account_id` = %d",
login_config.delcode_col.c_str(), db->account_db, account_id )
) {
Sql_ShowDebug(sql_handle);
return false;
@ -528,12 +530,31 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, uint32
Sql_GetData(sql_handle, 13, &data, NULL); acc->char_slots = (uint8) atoi(data);
Sql_GetData(sql_handle, 14, &data, NULL); safestrncpy(acc->pincode, data, sizeof(acc->pincode));
Sql_GetData(sql_handle, 15, &data, NULL); acc->pincode_change = atol(data);
Sql_GetData(sql_handle, 16, &data, NULL); acc->deletion_passcode = (data == NULL ? "" : data);
#ifdef VIP_ENABLE
Sql_GetData(sql_handle, 16, &data, NULL); acc->vip_time = atol(data);
Sql_GetData(sql_handle, 17, &data, NULL); acc->old_group = atoi(data);
Sql_GetData(sql_handle, 17, &data, NULL); acc->vip_time = atol(data);
Sql_GetData(sql_handle, 18, &data, NULL); acc->old_group = atoi(data);
#endif
Sql_FreeResult(sql_handle);
if (acc->deletion_passcode.size()) {
// Make sure the delcode for birthdate from YYYY-MM-DD to YYMMDD
if (login_config.delcode_col == "`birthdate`") {
const std::string str = acc->deletion_passcode;
acc->deletion_passcode.clear();
acc->deletion_passcode.append(str, 2, 1);
acc->deletion_passcode.append(str, 3, 1);
acc->deletion_passcode.append(str, 5, 1);
acc->deletion_passcode.append(str, 6, 1);
acc->deletion_passcode.append(str, 8, 1);
acc->deletion_passcode.append(str, 9, 1);
}
// Unset if email is default a@a.com
else if (login_config.delcode_col == "`email`" && acc->deletion_passcode == "a@a.com") {
acc->deletion_passcode = "";
}
}
return true;
}
@ -562,12 +583,16 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
if( is_new )
{// insert into account table
if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
"INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`"
#ifdef VIP_ENABLE
"INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`, `vip_time`, `old_group` ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
#else
"INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
",`vip_time`, `old_group`"
#endif
db->account_db)
")"
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"
#ifdef VIP_ENABLE
",?,?"
#endif
")", db->account_db)
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_INT, (void*)&acc->account_id, sizeof(acc->account_id))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass))
@ -596,13 +621,12 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
}
else
{// update account table
if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
"UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=?"
#ifdef VIP_ENABLE
"UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=?, `vip_time`=?, `old_group`=? WHERE `account_id` = '%d'",
#else
"UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=? WHERE `account_id` = '%d'",
",`vip_time`=?, `old_group`=?"
#endif
db->account_db, acc->account_id)
" WHERE `account_id` = '%d'", db->account_db, acc->account_id)
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex))

View File

@ -4,6 +4,8 @@
#ifndef _ACCOUNT_HPP_
#define _ACCOUNT_HPP_
#include <string>
#include "../common/cbasetypes.hpp"
#include "../common/mmo.hpp" // ACCOUNT_REG2_NUM
#include "../config/core.hpp"
@ -20,7 +22,7 @@ struct mmo_account {
char userid[NAME_LENGTH];
char pass[32+1]; // 23+1 for plaintext, 32+1 for md5-ed passwords
char sex; // gender (M/F/S)
char email[40]; // e-mail (by default: a@a.com)
char email[49+1]; // e-mail (by default: a@a.com)
unsigned int group_id; // player group id
uint8 char_slots; // this accounts maximum character slots (maximum is limited to MAX_CHARS define in char server)
unsigned int state; // packet 0x006a value + 1 (0: compte OK)
@ -32,6 +34,7 @@ struct mmo_account {
char birthdate[10+1]; // assigned birth date (format: YYYY-MM-DD)
char pincode[PINCODE_LENGTH+1]; // pincode system
time_t pincode_change; // (timestamp): last time of pincode change
std::string deletion_passcode; // Stores code for deleting character based on char_deletion_code config
#ifdef VIP_ENABLE
int old_group;
time_t vip_time;

View File

@ -5,7 +5,6 @@
#include "login.hpp"
#include <stdlib.h>
#include <string.h>
#include <string>
#include "../common/cli.hpp"
@ -241,6 +240,7 @@ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, con
safestrncpy(acc.pincode, "", sizeof(acc.pincode));
acc.pincode_change = 0;
acc.char_slots = MIN_CHARS;
acc.deletion_passcode = "";
#ifdef VIP_ENABLE
acc.vip_time = 0;
acc.old_group = 0;
@ -638,6 +638,9 @@ bool login_config_read(const char* cfgName, bool normal) {
login_config.char_per_account = MIN_CHARS;
}
}
else if (strcmpi(w1, "char_deletion_code") == 0) {
login_config.delcode_col = w2;
}
#ifdef VIP_ENABLE
else if(strcmpi(w1,"vip_group")==0)
login_config.vip_sys.group = cap_value(atoi(w2),0,99);
@ -700,6 +703,12 @@ void login_set_defaults() {
login_config.client_hash_check = 0;
login_config.client_hash_nodes = NULL;
login_config.char_per_account = MAX_CHARS - MAX_CHAR_VIP - MAX_CHAR_BILLING;
#if PACKETVER >= 20100803
login_config.delcode_col = "`birthdate`";
#else
login_config.delcode_col = "`email`";
#endif
#ifdef VIP_ENABLE
login_config.vip_sys.char_increase = MAX_CHAR_VIP;
login_config.vip_sys.group = 5;
@ -866,6 +875,7 @@ int do_init(int argc, char** argv) {
do_init_logincnslif();
ShowInfo("Column used for character deletion is '" CL_WHITE "%s" CL_RESET "'\n", login_config.delcode_col.c_str());
ShowStatus("The login-server is " CL_GREEN "ready" CL_RESET " (Server is listening on the port %u).\n\n", login_config.login_port);
login_log(0, "login server", 100, "login server started");

View File

@ -5,6 +5,7 @@
#define _LOGIN_HPP_
#include <memory>
#include <string>
#include "../common/cbasetypes.hpp"
#include "../common/core.hpp" // CORE_ST_LAST
@ -97,6 +98,7 @@ struct Login_Config {
char lanconf_name[256]; /// name of lan config file
int char_per_account; /// number of characters an account can have
std::string delcode_col;
#ifdef VIP_ENABLE
struct {
unsigned int group; /// VIP group ID

View File

@ -4,7 +4,7 @@
#include "loginchrif.hpp"
#include <stdlib.h>
#include <string.h>
#include <string>
#include "../common/showmsg.hpp" //show notice
#include "../common/socket.hpp" //wfifo session
@ -152,50 +152,38 @@ int logchrif_parse_ackusercount(int fd, int id){
*/
int logchrif_send_accdata(int fd, uint32 aid) {
struct mmo_account acc;
time_t expiration_time = 0;
char email[40] = "";
int group_id = 0;
char birthdate[10+1] = "";
char pincode[PINCODE_LENGTH+1];
char isvip = false;
uint8 char_slots = MIN_CHARS, char_vip = 0, char_billing = 0;
AccountDB* accounts = login_get_accounts_db();
memset(pincode,0,PINCODE_LENGTH+1);
if( !accounts->load_num(accounts, &acc, aid) )
return -1;
else {
safestrncpy(email, acc.email, sizeof(email));
expiration_time = acc.expiration_time;
group_id = acc.group_id;
safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
safestrncpy(pincode, acc.pincode, sizeof(pincode));
#ifdef VIP_ENABLE
char_vip = login_config.vip_sys.char_increase;
if( acc.vip_time > time(NULL) ) {
isvip = true;
char_slots = login_config.char_per_account + char_vip;
} else
char_slots = login_config.char_per_account;
char_billing = MAX_CHAR_BILLING; //TODO create a config for this
char_vip = login_config.vip_sys.char_increase;
if( acc.vip_time > time(NULL) ) {
isvip = true;
char_slots = login_config.char_per_account + char_vip;
} else
char_slots = login_config.char_per_account;
char_billing = MAX_CHAR_BILLING; //TODO create a config for this
#endif
}
WFIFOHEAD(fd,75);
WFIFOW(fd,0) = 0x2717;
WFIFOL(fd,2) = aid;
safestrncpy(WFIFOCP(fd,6), email, 40);
WFIFOL(fd,46) = (uint32)expiration_time;
WFIFOB(fd,50) = (unsigned char)group_id;
WFIFOB(fd,51) = char_slots;
safestrncpy(WFIFOCP(fd,52), birthdate, 10+1);
safestrncpy(WFIFOCP(fd,63), pincode, 4+1 );
WFIFOL(fd,68) = (uint32)acc.pincode_change;
WFIFOB(fd,72) = isvip;
WFIFOB(fd,73) = char_vip;
WFIFOB(fd,74) = char_billing;
WFIFOSET(fd,75);
WFIFOHEAD(fd, 135);
WFIFOW(fd, 0) = 0x2717;
WFIFOL(fd, 2) = aid;
WFIFOL(fd, 6) = (uint32)acc.expiration_time;
WFIFOB(fd, 10) = (unsigned char)acc.group_id;
WFIFOB(fd, 11) = char_slots;
WFIFOL(fd, 12) = (uint32)acc.pincode_change;
WFIFOB(fd, 16) = isvip;
WFIFOB(fd, 17) = char_vip;
WFIFOB(fd, 18) = char_billing;
safestrncpy(WFIFOCP(fd, 19), acc.email, 50);
safestrncpy(WFIFOCP(fd, 69), acc.birthdate, 10 + 1);
safestrncpy(WFIFOCP(fd, 80), acc.pincode, 4 + 1);
safestrncpy(WFIFOCP(fd, 85), acc.deletion_passcode.c_str(), 50/*DELCODE_LENGTH*/);
WFIFOSET(fd, 135);
return 1;
}