* Removed online_check config options. (always active now)
* Clarified char_maintenance config option. * Changed packet 0x2712. (added request_id) * Changed packet 0x2713. (added sex, request_id, version, clienttype; removed email, expiration time, gmlevel) * Delayed user count check and mmo_char_send006b to when the account data arrives. * Created auxiliary function MD5_Salt. (split from a future commit that was getting to big for my taste) git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13652 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
07c0a7ddc3
commit
e7607efb6c
@ -3,6 +3,13 @@ Date Added
|
||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2009/04/01
|
||||
* Removed online_check config options. (always active now) [FlavioJS]
|
||||
* Clarified char_maintenance config option.
|
||||
* Changed packet 0x2712. (added request_id)
|
||||
* Changed packet 0x2713. (added sex, request_id, version, clienttype; removed email, expiration time, gmlevel)
|
||||
* Delayed user count check and mmo_char_send006b to when the account data arrives.
|
||||
* Created auxiliary function MD5_Salt.
|
||||
2009/03/31
|
||||
* Gunslinger Tracking can be canceled if you get hit.
|
||||
* Gunslinger Disarm always shows skill animation.
|
||||
|
@ -1,13 +1,17 @@
|
||||
Date Added
|
||||
2009/3/31
|
||||
|
||||
2009/04/01
|
||||
* Removed online_check config options. [FlavioJS]
|
||||
* Clarified char_maintenance config option.
|
||||
2009/03/31
|
||||
* Added missing pet_equip_min_friendly config option [ultramage]
|
||||
2009/3/23
|
||||
2009/03/23
|
||||
* Added setting display_status_timers to client.conf for new status change packet. [Sara]
|
||||
2009/1/26
|
||||
2009/01/26
|
||||
* Rev. 13494 Changed guild_skill_relog_delay to yes. Relogging no longer resets delay on guild skills. [L0ne_W0lf]
|
||||
2009/1/12
|
||||
2009/01/12
|
||||
* Second agitend corrected to agitend2 [SketchyPhoenix]
|
||||
2009/1/5
|
||||
2009/01/05
|
||||
* Added @charcommands to return a list of available # commands [SketchyPhoenix]
|
||||
2008/12/26
|
||||
* Rev. 13444 Marked new Morroc fields as nomemo. [L0ne_W0lf]
|
||||
|
@ -77,7 +77,10 @@ console: off
|
||||
// So, default is 0, because administrator must explain to their players before to activate this option.
|
||||
email_creation: 0
|
||||
|
||||
// Is Character server in maintainence mode?
|
||||
// Type of server.
|
||||
// No functional side effects at the moment.
|
||||
// Displayed next to the server name in the client.
|
||||
// 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=P2P
|
||||
char_maintenance: 0
|
||||
|
||||
// Enable or disable creation of new characters.
|
||||
@ -90,13 +93,6 @@ char_new_display: 0
|
||||
// Maximum users able to connect to the server. Set to 0 for unlimited.
|
||||
max_connect_user: 0
|
||||
|
||||
// When set to yes, the char server will refuse connections from players already online.
|
||||
// When a login attempt is rejected, the account in question will be booted from all the connected map servers.
|
||||
// Note that this only works within the char-server and it's connected mapservers,
|
||||
// the charserver cannot know if the same account is logged on in other char servers.
|
||||
// it's safe to turn off if the char-server only has a single map-server connected to it.
|
||||
online_check: yes
|
||||
|
||||
// Minimum GM level that is allowed to bypass the server limit of users.
|
||||
gm_allow_level: 99
|
||||
|
||||
|
@ -65,12 +65,6 @@ login_log_filename: log/login.log
|
||||
// NOTE: The login-sql server needs the login logs to enable dynamic pass failure bans.
|
||||
log_login: yes
|
||||
|
||||
//When set to yes, the login server will refuse connections from accounts that are considered online already.
|
||||
//When a login attempt is rejected, the account in question is also kicked from all connected char-servers.
|
||||
//It's safe to turn this off if there's only one char-server connected, or if the char-servers don't share
|
||||
//the same backend (ie: Multiple char servers reading from the same SQL tables)
|
||||
online_check: yes
|
||||
|
||||
// Indicate how to display date in logs, to players, etc.
|
||||
date_format: %Y-%m-%d %H:%M:%S
|
||||
|
||||
|
@ -93,8 +93,6 @@ bool char_rename = true;
|
||||
int log_char = 1; // loggin char or not [devil]
|
||||
int log_inter = 1; // loggin inter or not [devil]
|
||||
|
||||
static int online_check = 1; //If one, it won't let players connect when their account is already registered online and will send the relevant map server a kick user request. [Skotlex]
|
||||
|
||||
// Advanced subnet check [LuzZza]
|
||||
struct s_subnet {
|
||||
uint32 mask;
|
||||
@ -110,6 +108,8 @@ struct char_session_data {
|
||||
char email[40]; // 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 gmlevel;
|
||||
uint32 version;
|
||||
uint8 clienttype;
|
||||
};
|
||||
|
||||
int char_id_count = START_CHAR_NUM;
|
||||
@ -197,7 +197,7 @@ void set_char_online(int map_id, int char_id, int account_id)
|
||||
struct online_char_data* character;
|
||||
|
||||
character = (struct online_char_data*)idb_ensure(online_char_db, account_id, create_online_char_data);
|
||||
if (online_check && character->char_id != -1 && character->server > -1 && character->server != map_id && map_id != -3)
|
||||
if( character->char_id != -1 && character->server > -1 && character->server != map_id && map_id != -3 )
|
||||
{
|
||||
//char == 99 <- Character logging in, so someone has logged in while one
|
||||
//char is still on map-server, so kick him out, but don't print "error"
|
||||
@ -1878,16 +1878,8 @@ static int char_delete(struct mmo_charstatus *cs)
|
||||
static void char_auth_ok(int fd, struct char_session_data *sd)
|
||||
{
|
||||
struct online_char_data* character;
|
||||
if (max_connect_user && count_users() >= max_connect_user && sd->gmlevel < gm_allow_level)
|
||||
{
|
||||
// refuse connection (over populated)
|
||||
WFIFOW(fd,0) = 0x6c;
|
||||
WFIFOW(fd,2) = 0;
|
||||
WFIFOSET(fd,3);
|
||||
return;
|
||||
}
|
||||
|
||||
if( online_check && (character = (struct online_char_data*)idb_get(online_char_db, sd->account_id)) != NULL )
|
||||
if( (character = (struct online_char_data*)idb_get(online_char_db, sd->account_id)) != NULL )
|
||||
{ // check if character is not online already. [Skotlex]
|
||||
if (character->server > -1)
|
||||
{ //Character already online. KICK KICK KICK
|
||||
@ -1910,8 +1902,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
|
||||
}
|
||||
|
||||
if (login_fd > 0) {
|
||||
// request to login-server to obtain e-mail/time limit
|
||||
//FIXME: isn't this part of the auth_ok packet? [ultramage]
|
||||
// request account data
|
||||
WFIFOHEAD(login_fd,6);
|
||||
WFIFOW(login_fd,0) = 0x2716;
|
||||
WFIFOL(login_fd,2) = sd->account_id;
|
||||
@ -1924,8 +1915,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
|
||||
// set char online on charserver
|
||||
set_char_online(-1, 99, sd->account_id);
|
||||
|
||||
// send characters to player
|
||||
mmo_char_send006b(fd, sd);
|
||||
// continues when account data is received...
|
||||
}
|
||||
|
||||
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data);
|
||||
@ -1985,50 +1975,66 @@ int parse_fromlogin(int fd)
|
||||
|
||||
// acknowledgement of account authentication request
|
||||
case 0x2713:
|
||||
if (RFIFOREST(fd) < 60)
|
||||
if (RFIFOREST(fd) < 25)
|
||||
return 0;
|
||||
{
|
||||
int account_id = RFIFOL(fd,2);
|
||||
int login_id1 = RFIFOL(fd,6);
|
||||
int login_id2 = RFIFOL(fd,10);
|
||||
bool result = RFIFOB(fd,14);
|
||||
const char* email = (const char*)RFIFOP(fd,15);
|
||||
time_t expiration_time = (time_t)RFIFOL(fd,55);
|
||||
int gmlevel = RFIFOB(fd,59);
|
||||
uint32 login_id1 = RFIFOL(fd,6);
|
||||
uint32 login_id2 = RFIFOL(fd,10);
|
||||
uint8 sex = RFIFOB(fd,14);
|
||||
uint8 result = RFIFOB(fd,15);
|
||||
int request_id = RFIFOL(fd,16);
|
||||
uint32 version = RFIFOL(fd,20);
|
||||
uint8 clienttype = RFIFOB(fd,24);
|
||||
RFIFOSKIP(fd,25);
|
||||
|
||||
// find the session with this account id
|
||||
ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) &&
|
||||
sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 );
|
||||
if( i < fd_max )
|
||||
if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) &&
|
||||
!sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex )
|
||||
{
|
||||
if( result ) { // failure
|
||||
WFIFOHEAD(i,3);
|
||||
WFIFOW(i,0) = 0x6c;
|
||||
WFIFOB(i,2) = 0x42;
|
||||
WFIFOSET(i,3);
|
||||
} else { // success
|
||||
memcpy(sd->email, email, 40);
|
||||
sd->expiration_time = expiration_time;
|
||||
sd->gmlevel = gmlevel;
|
||||
char_auth_ok(i, sd);
|
||||
int client_fd = request_id;
|
||||
sd->version = version;
|
||||
sd->clienttype = clienttype;
|
||||
switch( result )
|
||||
{
|
||||
case 0:// ok
|
||||
char_auth_ok(client_fd, sd);
|
||||
break;
|
||||
case 1:// auth failed
|
||||
WFIFOHEAD(client_fd,3);
|
||||
WFIFOW(client_fd,0) = 0x6c;
|
||||
WFIFOB(client_fd,2) = 0;// rejected from server
|
||||
WFIFOSET(client_fd,3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
RFIFOSKIP(fd,60);
|
||||
break;
|
||||
|
||||
// Receiving of an e-mail/time limit from the login-server (answer of a request because a player comes back from map-server to char-server) by [Yor]
|
||||
case 0x2717:
|
||||
case 0x2717: // account data
|
||||
if (RFIFOREST(fd) < 51)
|
||||
return 0;
|
||||
|
||||
// find the session with this account id
|
||||
ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == RFIFOL(fd,2) );
|
||||
// find the authenticated session with this account id
|
||||
ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) );
|
||||
if( i < fd_max )
|
||||
{
|
||||
memcpy(sd->email, RFIFOP(fd,6), 40);
|
||||
sd->expiration_time = (time_t)RFIFOL(fd,46);
|
||||
sd->gmlevel = RFIFOB(fd,50);
|
||||
|
||||
// continued from char_auth_ok...
|
||||
if( max_connect_user && count_users() >= max_connect_user && sd->gmlevel < gm_allow_level )
|
||||
{
|
||||
// refuse connection (over populated)
|
||||
WFIFOW(i,0) = 0x6c;
|
||||
WFIFOW(i,2) = 0;
|
||||
WFIFOSET(i,3);
|
||||
}
|
||||
else
|
||||
{
|
||||
// send characters to player
|
||||
mmo_char_send006b(i, sd);
|
||||
}
|
||||
}
|
||||
RFIFOSKIP(fd,51);
|
||||
break;
|
||||
@ -2696,7 +2702,7 @@ int parse_frommap(int fd)
|
||||
aid = RFIFOL(fd,6+i*8);
|
||||
cid = RFIFOL(fd,6+i*8+4);
|
||||
character = (struct online_char_data*)idb_ensure(online_char_db, aid, create_online_char_data);
|
||||
if (online_check && character->server > -1 && character->server != id)
|
||||
if( character->server > -1 && character->server != id )
|
||||
{
|
||||
ShowNotice("Set map user: Character (%d:%d) marked on map server %d, but map server %d claims to have (%d:%d) online!\n",
|
||||
character->account_id, character->char_id, character->server, id, aid, cid);
|
||||
@ -3281,14 +3287,15 @@ int parse_char(int fd)
|
||||
else
|
||||
{// authentication not found (coming from login server)
|
||||
if (login_fd > 0) { // don't send request if no login-server
|
||||
WFIFOHEAD(login_fd,19);
|
||||
WFIFOHEAD(login_fd,23);
|
||||
WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
|
||||
WFIFOL(login_fd,2) = sd->account_id;
|
||||
WFIFOL(login_fd,6) = sd->login_id1;
|
||||
WFIFOL(login_fd,10) = sd->login_id2;
|
||||
WFIFOB(login_fd,14) = sd->sex;
|
||||
WFIFOL(login_fd,15) = htonl(ipl);
|
||||
WFIFOSET(login_fd,19);
|
||||
WFIFOL(login_fd,19) = fd;
|
||||
WFIFOSET(login_fd,23);
|
||||
} else { // if no login-server, we must refuse connection
|
||||
WFIFOHEAD(fd,3);
|
||||
WFIFOW(fd,0) = 0x6c;
|
||||
@ -4022,8 +4029,6 @@ int char_config_read(const char *cfgName)
|
||||
gm_allow_level = atoi(w2);
|
||||
if(gm_allow_level < 0)
|
||||
gm_allow_level = 99;
|
||||
} else if (strcmpi(w1, "online_check") == 0) {
|
||||
online_check = config_switch(w2);
|
||||
} else if (strcmpi(w1, "autosave_time") == 0) {
|
||||
autosave_interval = atoi(w2)*1000;
|
||||
if (autosave_interval <= 0)
|
||||
|
@ -114,8 +114,6 @@ int save_log = 0; //Have the logs be off by default when converting
|
||||
int save_log = 1;
|
||||
#endif
|
||||
|
||||
static int online_check = 1; //If one, it won't let players connect when their account is already registered online and will send the relevant map server a kick user request. [Skotlex]
|
||||
|
||||
// Advanced subnet check [LuzZza]
|
||||
struct s_subnet {
|
||||
uint32 mask;
|
||||
@ -131,6 +129,8 @@ struct char_session_data {
|
||||
char email[40]; // 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 gmlevel;
|
||||
uint32 version;
|
||||
uint8 clienttype;
|
||||
};
|
||||
|
||||
int char_num, char_max;
|
||||
@ -245,7 +245,7 @@ void set_char_online(int map_id, int char_id, int account_id)
|
||||
|
||||
//Check to see for online conflicts
|
||||
character = (struct online_char_data*)idb_ensure(online_char_db, account_id, create_online_char_data);
|
||||
if (online_check && character->char_id != -1 && character->server > -1 && character->server != map_id)
|
||||
if( character->char_id != -1 && character->server > -1 && character->server != map_id )
|
||||
{
|
||||
ShowNotice("set_char_online: Character %d:%d marked in map server %d, but map server %d claims to have (%d:%d) online!\n",
|
||||
character->account_id, character->char_id, character->server, map_id, account_id, char_id);
|
||||
@ -1608,16 +1608,8 @@ int char_family(int pl1, int pl2, int pl3)
|
||||
static void char_auth_ok(int fd, struct char_session_data *sd)
|
||||
{
|
||||
struct online_char_data* character;
|
||||
if (max_connect_user && count_users() >= max_connect_user && sd->gmlevel < gm_allow_level)
|
||||
{
|
||||
// refuse connection (over populated)
|
||||
WFIFOW(fd,0) = 0x6c;
|
||||
WFIFOW(fd,2) = 0;
|
||||
WFIFOSET(fd,3);
|
||||
return;
|
||||
}
|
||||
|
||||
if( online_check && (character = (struct online_char_data*)idb_get(online_char_db, sd->account_id)) != NULL )
|
||||
if( (character = (struct online_char_data*)idb_get(online_char_db, sd->account_id)) != NULL )
|
||||
{ // check if character is not online already. [Skotlex]
|
||||
if (character->server > -1)
|
||||
{ //Character already online. KICK KICK KICK
|
||||
@ -1640,7 +1632,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
|
||||
}
|
||||
|
||||
if (login_fd > 0) {
|
||||
// request to login-server to obtain e-mail/time limit
|
||||
// request account data
|
||||
WFIFOHEAD(login_fd,6);
|
||||
WFIFOW(login_fd,0) = 0x2716;
|
||||
WFIFOL(login_fd,2) = sd->account_id;
|
||||
@ -1653,8 +1645,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
|
||||
// set char online on charserver
|
||||
set_char_charselect(sd->account_id);
|
||||
|
||||
// send characters to player
|
||||
mmo_char_send006b(fd, sd);
|
||||
// continues when account data is received...
|
||||
}
|
||||
|
||||
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data);
|
||||
@ -1714,50 +1705,66 @@ int parse_fromlogin(int fd)
|
||||
|
||||
// acknowledgement of account authentication request
|
||||
case 0x2713:
|
||||
if (RFIFOREST(fd) < 60)
|
||||
if (RFIFOREST(fd) < 25)
|
||||
return 0;
|
||||
{
|
||||
int account_id = RFIFOL(fd,2);
|
||||
int login_id1 = RFIFOL(fd,6);
|
||||
int login_id2 = RFIFOL(fd,10);
|
||||
bool result = RFIFOB(fd,14);
|
||||
const char* email = (const char*)RFIFOP(fd,15);
|
||||
time_t expiration_time = (time_t)RFIFOL(fd,55);
|
||||
int gmlevel = RFIFOB(fd,59);
|
||||
uint32 login_id1 = RFIFOL(fd,6);
|
||||
uint32 login_id2 = RFIFOL(fd,10);
|
||||
uint8 sex = RFIFOB(fd,14);
|
||||
uint8 result = RFIFOB(fd,15);
|
||||
int request_id = RFIFOL(fd,16);
|
||||
uint32 version = RFIFOL(fd,20);
|
||||
uint8 clienttype = RFIFOB(fd,24);
|
||||
RFIFOSKIP(fd,25);
|
||||
|
||||
// find the session with this account id
|
||||
ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) &&
|
||||
sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 );
|
||||
if( i < fd_max )
|
||||
if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) &&
|
||||
!sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex )
|
||||
{
|
||||
if( result ) { // failure
|
||||
WFIFOHEAD(i,3);
|
||||
WFIFOW(i,0) = 0x6c;
|
||||
WFIFOB(i,2) = 0x42;
|
||||
WFIFOSET(i,3);
|
||||
} else { // success
|
||||
memcpy(sd->email, email, 40);
|
||||
sd->expiration_time = expiration_time;
|
||||
sd->gmlevel = gmlevel;
|
||||
char_auth_ok(i, sd);
|
||||
int client_fd = request_id;
|
||||
sd->version = version;
|
||||
sd->clienttype = clienttype;
|
||||
switch( result )
|
||||
{
|
||||
case 0:// ok
|
||||
char_auth_ok(client_fd, sd);
|
||||
break;
|
||||
case 1:// auth failed
|
||||
WFIFOHEAD(client_fd,3);
|
||||
WFIFOW(client_fd,0) = 0x6c;
|
||||
WFIFOB(client_fd,2) = 0;// rejected from server
|
||||
WFIFOSET(client_fd,3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
RFIFOSKIP(fd,60);
|
||||
break;
|
||||
|
||||
// acknowledgement of e-mail/limited time request
|
||||
case 0x2717:
|
||||
case 0x2717: // account data
|
||||
if (RFIFOREST(fd) < 51)
|
||||
return 0;
|
||||
|
||||
// find the session with this account id
|
||||
ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == RFIFOL(fd,2) );
|
||||
// find the authenticated session with this account id
|
||||
ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) );
|
||||
if( i < fd_max )
|
||||
{
|
||||
memcpy(sd->email, RFIFOP(fd,6), 40);
|
||||
sd->expiration_time = (time_t)RFIFOL(fd,46);
|
||||
sd->gmlevel = RFIFOB(fd,50);
|
||||
|
||||
// continued from char_auth_ok...
|
||||
if( max_connect_user && count_users() >= max_connect_user && sd->gmlevel < gm_allow_level )
|
||||
{
|
||||
// refuse connection (over populated)
|
||||
WFIFOW(i,0) = 0x6c;
|
||||
WFIFOW(i,2) = 0;
|
||||
WFIFOSET(i,3);
|
||||
}
|
||||
else
|
||||
{
|
||||
// send characters to player
|
||||
mmo_char_send006b(i, sd);
|
||||
}
|
||||
}
|
||||
RFIFOSKIP(fd,51);
|
||||
break;
|
||||
@ -2948,14 +2955,15 @@ int parse_char(int fd)
|
||||
else
|
||||
{// authentication not found (coming from login server)
|
||||
if (login_fd > 0) { // don't send request if no login-server
|
||||
WFIFOHEAD(login_fd,19);
|
||||
WFIFOHEAD(login_fd,23);
|
||||
WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
|
||||
WFIFOL(login_fd,2) = sd->account_id;
|
||||
WFIFOL(login_fd,6) = sd->login_id1;
|
||||
WFIFOL(login_fd,10) = sd->login_id2;
|
||||
WFIFOB(login_fd,14) = sd->sex;
|
||||
WFIFOL(login_fd,15) = htonl(ipl);
|
||||
WFIFOSET(login_fd,19);
|
||||
WFIFOL(login_fd,19) = fd;
|
||||
WFIFOSET(login_fd,23);
|
||||
} else { // if no login-server, we must refuse connection
|
||||
WFIFOHEAD(fd,3);
|
||||
WFIFOW(fd,0) = 0x6c;
|
||||
@ -3728,8 +3736,6 @@ int char_config_read(const char* cfgName)
|
||||
gm_allow_level = atoi(w2);
|
||||
if(gm_allow_level < 0)
|
||||
gm_allow_level = 99;
|
||||
} else if (strcmpi(w1, "online_check") == 0) {
|
||||
online_check = config_switch(w2);
|
||||
} else if (strcmpi(w1, "autosave_time") == 0) {
|
||||
autosave_interval = atoi(w2)*1000;
|
||||
if (autosave_interval <= 0)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "md5calc.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef UINT_MAX
|
||||
#define UINT_MAX 4294967295U
|
||||
@ -227,3 +228,12 @@ void MD5_String(const char * string, char * output)
|
||||
digest[ 8], digest[ 9], digest[10], digest[11],
|
||||
digest[12], digest[13], digest[14], digest[15]);
|
||||
}
|
||||
|
||||
/** output is a sequence of non-zero characters to be used as password salt. */
|
||||
void MD5_Salt(unsigned int len, char * output)
|
||||
{
|
||||
unsigned int i;
|
||||
for( i = 0; i < len; ++i )
|
||||
output[i] = (char)(1 + rand() % 255);
|
||||
|
||||
}
|
||||
|
@ -3,5 +3,6 @@
|
||||
|
||||
void MD5_String(const char * string, char * output);
|
||||
void MD5_Binary(const char * string, unsigned char * output);
|
||||
void MD5_Salt(unsigned int len, char * output);
|
||||
|
||||
#endif /* _MD5CALC_H_ */
|
||||
|
@ -83,6 +83,8 @@ struct auth_node {
|
||||
uint32 login_id2;
|
||||
uint32 ip;
|
||||
char sex;
|
||||
uint32 version;
|
||||
uint8 clienttype;
|
||||
};
|
||||
|
||||
static DBMap* auth_db; // int account_id -> struct auth_node*
|
||||
@ -114,8 +116,6 @@ static void* create_online_user(DBKey key, va_list args)
|
||||
struct online_login_data* add_online_user(int char_server, int account_id)
|
||||
{
|
||||
struct online_login_data* p;
|
||||
if( !login_config.online_check )
|
||||
return NULL;
|
||||
p = (struct online_login_data*)idb_ensure(online_db, account_id, create_online_user);
|
||||
p->char_server = char_server;
|
||||
if( p->waiting_disconnect != -1 )
|
||||
@ -129,8 +129,6 @@ struct online_login_data* add_online_user(int char_server, int account_id)
|
||||
void remove_online_user(int account_id)
|
||||
{
|
||||
struct online_login_data* p;
|
||||
if( !login_config.online_check )
|
||||
return;
|
||||
p = (struct online_login_data*)idb_get(online_db, account_id);
|
||||
if( p == NULL )
|
||||
return;
|
||||
@ -395,7 +393,7 @@ int parse_fromchar(int fd)
|
||||
{
|
||||
|
||||
case 0x2712: // request from char-server to authenticate an account
|
||||
if( RFIFOREST(fd) < 19 )
|
||||
if( RFIFOREST(fd) < 23 )
|
||||
return 0;
|
||||
{
|
||||
struct auth_node* node;
|
||||
@ -403,61 +401,51 @@ int parse_fromchar(int fd)
|
||||
int account_id = RFIFOL(fd,2);
|
||||
uint32 login_id1 = RFIFOL(fd,6);
|
||||
uint32 login_id2 = RFIFOL(fd,10);
|
||||
char sex = sex_num2str(RFIFOB(fd,14));
|
||||
uint8 sex = RFIFOB(fd,14);
|
||||
uint32 ip_ = ntohl(RFIFOL(fd,15));
|
||||
RFIFOSKIP(fd,19);
|
||||
int request_id = RFIFOL(fd,19);
|
||||
RFIFOSKIP(fd,23);
|
||||
|
||||
node = (struct auth_node*)idb_get(auth_db, account_id);
|
||||
if( node != NULL &&
|
||||
node->account_id == account_id &&
|
||||
node->login_id1 == login_id1 &&
|
||||
node->login_id2 == login_id2 &&
|
||||
node->sex == sex &&
|
||||
node->sex == sex_num2str(sex) &&
|
||||
node->ip == ip_ )
|
||||
{// found
|
||||
struct mmo_account acc;
|
||||
time_t expiration_time = 0;
|
||||
const char* email = "";
|
||||
int gmlevel = 0;
|
||||
|
||||
//ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
|
||||
|
||||
// each auth entry can only be used once
|
||||
idb_remove(auth_db, account_id);
|
||||
|
||||
// retrieve email and account expiration time and gm level
|
||||
if( accounts->load_num(accounts, &acc, account_id) )
|
||||
{
|
||||
email = acc.email;
|
||||
expiration_time = acc.expiration_time;
|
||||
gmlevel = acc.level;
|
||||
}
|
||||
|
||||
// send ack
|
||||
WFIFOHEAD(fd,60);
|
||||
WFIFOHEAD(fd,25);
|
||||
WFIFOW(fd,0) = 0x2713;
|
||||
WFIFOL(fd,2) = account_id;
|
||||
WFIFOL(fd,6) = login_id1;
|
||||
WFIFOL(fd,10) = login_id2;
|
||||
WFIFOB(fd,14) = 0;
|
||||
safestrncpy((char*)WFIFOP(fd,15), email, 40);
|
||||
WFIFOL(fd,55) = (uint32)expiration_time;
|
||||
WFIFOB(fd,59) = gmlevel;
|
||||
WFIFOSET(fd,60);
|
||||
WFIFOB(fd,14) = sex;
|
||||
WFIFOB(fd,15) = 0;// ok
|
||||
WFIFOL(fd,16) = request_id;
|
||||
WFIFOL(fd,20) = node->version;
|
||||
WFIFOB(fd,24) = node->clienttype;
|
||||
WFIFOSET(fd,25);
|
||||
}
|
||||
else
|
||||
{// authentication not found
|
||||
ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
|
||||
WFIFOHEAD(fd,60);
|
||||
WFIFOHEAD(fd,25);
|
||||
WFIFOW(fd,0) = 0x2713;
|
||||
WFIFOL(fd,2) = account_id;
|
||||
WFIFOL(fd,6) = login_id1;
|
||||
WFIFOL(fd,10) = login_id2;
|
||||
WFIFOB(fd,14) = 1;
|
||||
//safestrncpy((char*)WFIFOP(fd,15), "", 40);
|
||||
//WFIFOL(fd,55) = (uint32)0;
|
||||
//WFIFOB(fd,59) = 0;
|
||||
WFIFOSET(fd,60);
|
||||
WFIFOB(fd,14) = sex;
|
||||
WFIFOB(fd,15) = 1;// auth failed
|
||||
WFIFOL(fd,16) = request_id;
|
||||
WFIFOL(fd,20) = 0;
|
||||
WFIFOB(fd,24) = 0;
|
||||
WFIFOSET(fd,25);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -504,7 +492,7 @@ int parse_fromchar(int fd)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2716: // received an e-mail/limited time request, because a player comes back from a map-server to the char-server
|
||||
case 0x2716: // request account data
|
||||
if( RFIFOREST(fd) < 6 )
|
||||
return 0;
|
||||
{
|
||||
@ -517,7 +505,7 @@ int parse_fromchar(int fd)
|
||||
RFIFOSKIP(fd,6);
|
||||
|
||||
if( !accounts->load_num(accounts, &acc, account_id) )
|
||||
ShowNotice("Char-server '%s': e-mail of the account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
|
||||
ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
|
||||
else
|
||||
{
|
||||
safestrncpy(email, acc.email, sizeof(email));
|
||||
@ -790,7 +778,6 @@ int parse_fromchar(int fd)
|
||||
case 0x272d: // Receive list of all online accounts. [Skotlex]
|
||||
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
|
||||
return 0;
|
||||
if( login_config.online_check )
|
||||
{
|
||||
struct online_login_data *p;
|
||||
int aid;
|
||||
@ -1079,7 +1066,6 @@ void login_auth_ok(struct login_session_data* sd)
|
||||
return;
|
||||
}
|
||||
|
||||
if( login_config.online_check )
|
||||
{
|
||||
struct online_login_data* data = (struct online_login_data*)idb_get(online_db, sd->account_id);
|
||||
if( data )
|
||||
@ -1139,7 +1125,7 @@ void login_auth_ok(struct login_session_data* sd)
|
||||
WFIFOW(fd,47+n*32+4) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
|
||||
memcpy(WFIFOP(fd,47+n*32+6), server[i].name, 20);
|
||||
WFIFOW(fd,47+n*32+26) = server[i].users;
|
||||
WFIFOW(fd,47+n*32+28) = server[i].maintenance;
|
||||
WFIFOW(fd,47+n*32+28) = server[i].type;
|
||||
WFIFOW(fd,47+n*32+30) = server[i].new_;
|
||||
n++;
|
||||
}
|
||||
@ -1152,9 +1138,10 @@ void login_auth_ok(struct login_session_data* sd)
|
||||
node->login_id2 = sd->login_id2;
|
||||
node->sex = sd->sex;
|
||||
node->ip = ip;
|
||||
node->version = sd->version;
|
||||
node->clienttype = sd->clienttype;
|
||||
idb_put(auth_db, sd->account_id, node);
|
||||
|
||||
if( login_config.online_check )
|
||||
{
|
||||
struct online_login_data* data;
|
||||
|
||||
@ -1359,12 +1346,9 @@ int parse_login(int fd)
|
||||
case 0x791a: // Sending request of the coding key (administration packet)
|
||||
RFIFOSKIP(fd,2);
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
memset(sd->md5key, '\0', sizeof(sd->md5key));
|
||||
sd->md5keylen = (uint16)(12 + rand() % 4);
|
||||
for( i = 0; i < sd->md5keylen; ++i )
|
||||
sd->md5key[i] = (char)(1 + rand() % 255);
|
||||
MD5_Salt(sd->md5keylen, sd->md5key);
|
||||
|
||||
WFIFOHEAD(fd,4 + sd->md5keylen);
|
||||
WFIFOW(fd,0) = 0x01dc;
|
||||
@ -1382,7 +1366,7 @@ int parse_login(int fd)
|
||||
char message[256];
|
||||
uint32 server_ip;
|
||||
uint16 server_port;
|
||||
uint16 maintenance;
|
||||
uint16 type;
|
||||
uint16 new_;
|
||||
|
||||
safestrncpy(sd->userid, (char*)RFIFOP(fd,2), NAME_LENGTH);
|
||||
@ -1394,7 +1378,7 @@ int parse_login(int fd)
|
||||
server_ip = ntohl(RFIFOL(fd,54));
|
||||
server_port = ntohs(RFIFOW(fd,58));
|
||||
safestrncpy(server_name, (char*)RFIFOP(fd,60), 20);
|
||||
maintenance = RFIFOW(fd,82);
|
||||
type = RFIFOW(fd,82);
|
||||
new_ = RFIFOW(fd,84);
|
||||
RFIFOSKIP(fd,86);
|
||||
|
||||
@ -1411,7 +1395,7 @@ int parse_login(int fd)
|
||||
server[sd->account_id].ip = server_ip;
|
||||
server[sd->account_id].port = server_port;
|
||||
server[sd->account_id].users = 0;
|
||||
server[sd->account_id].maintenance = maintenance;
|
||||
server[sd->account_id].type = type;
|
||||
server[sd->account_id].new_ = new_;
|
||||
|
||||
session[fd]->func_parse = parse_fromchar;
|
||||
@ -1497,7 +1481,6 @@ void login_set_defaults()
|
||||
login_config.new_account_flag = true;
|
||||
login_config.use_md5_passwds = false;
|
||||
login_config.min_level_to_connect = 0;
|
||||
login_config.online_check = true;
|
||||
login_config.check_client_version = false;
|
||||
login_config.client_version_to_connect = 20;
|
||||
|
||||
@ -1572,8 +1555,6 @@ int login_config_read(const char* cfgName)
|
||||
allowed_regs = atoi(w2);
|
||||
else if(!strcmpi(w1, "time_allowed"))
|
||||
time_allowed = atoi(w2);
|
||||
else if(!strcmpi(w1, "online_check"))
|
||||
login_config.online_check = (bool)config_switch(w2);
|
||||
else if(!strcmpi(w1, "use_dnsbl"))
|
||||
login_config.use_dnsbl = (bool)config_switch(w2);
|
||||
else if(!strcmpi(w1, "dnsbl_servers"))
|
||||
|
@ -40,7 +40,7 @@ struct mmo_char_server {
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
uint16 users; // user count on this server
|
||||
uint16 maintenance; // in maintenance mode?
|
||||
uint16 type; // 0=normal, 1=maintenance, 2=over 18, 3=paying, 4=P2P
|
||||
uint16 new_; // should display as 'new'?
|
||||
};
|
||||
|
||||
@ -56,7 +56,6 @@ struct Login_Config {
|
||||
int start_limited_time; // new account expiration time (-1: unlimited)
|
||||
bool use_md5_passwds; // work with password hashes instead of plaintext passwords?
|
||||
int min_level_to_connect; // minimum level of player/GM (0: player, 1-99: GM) to connect
|
||||
bool online_check; // reject incoming players that are already registered as online ?
|
||||
bool check_client_version; // check the clientversion set in the clientinfo ?
|
||||
int client_version_to_connect; // the client version needed to connect (if checking is enabled)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user