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:
parent
3faf700443
commit
4b434fa669
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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',
|
||||
|
1
sql-files/upgrades/email_extends.sql
Normal file
1
sql-files/upgrades/email_extends.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `login` MODIFY COLUMN `email` VARCHAR(49) NULL DEFAULT '';
|
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user