summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt8
-rw-r--r--conf/login_athena.conf7
-rw-r--r--src/char/char.c62
-rw-r--r--src/char/int_homun.c2
-rw-r--r--src/char_sql/char.c56
-rw-r--r--src/ladmin/ladmin.c28
-rw-r--r--src/login/Makefile.in2
-rw-r--r--src/login/login.c2047
-rw-r--r--src/login/login.h62
-rw-r--r--src/login_sql/login.c250
-rw-r--r--src/login_sql/login.h43
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/script.c2
-rw-r--r--vcproj-6/login-server_txt.dsp4
-rw-r--r--vcproj-7.1/login-server_txt.vcproj3
-rw-r--r--vcproj-8/login-server_txt.vcproj4
16 files changed, 695 insertions, 1887 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 6f0834ddb..869abd50b 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,14 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2007/11/27
+ * removed login/char server_fd[] arrays, added server[].fd instead
+ * TXT/SQL login server code synchronization [ultramage]
+ - exported several core structures to login.h
+ - split off ladmin communication code from the TXT login server
+ - removed all occurences of login_log(); a unified function should be
+ added when SQL's loginlog_db logging code gets synced with TXT
+ - removed conf setting login_log_filename
+ - fixed ladmin getting timeouts since the ping system was changed
* Moved basic max HP/SP calculation to before parsing equipment, fixes
negative absolute HP/SP bonuses not working.
* Corrected the online_data_cleanup routine setting offline characters that
diff --git a/conf/login_athena.conf b/conf/login_athena.conf
index 91da4aa16..1c9fd0836 100644
--- a/conf/login_athena.conf
+++ b/conf/login_athena.conf
@@ -34,8 +34,8 @@ stdout_with_ansisequence: no
//Example: "console_silent: 7" Hides information, status and notice messages (1+2+4)
console_silent: 0
-// Whether remote administration is enabled or disabled (1 for enabled, 0 for disabled)
-admin_state: 0
+// Whether remote administration is enabled or disabled
+admin_state: no
// Administrative password, used by ladmin (perl software) to connect remotely to server.
// NOTICE: If you enable remote administration, you should change its value for security
@@ -88,9 +88,6 @@ gm_account_filename: conf/GM_account.txt
// (in seconds; default: 15; value: 0 (disabled), or 2 or more)
gm_account_filename_check_timer: 15
-// Log Filename. All operations received by the server are logged in this file.
-login_log_filename: log/login.log
-
// To log the login server?
// NOTE: The login-sql server needs the login logs to enable dynamic pass failure bans.
log_login: yes
diff --git a/src/char/char.c b/src/char/char.c
index 8f83dbcd2..6a9e94696 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -57,12 +57,12 @@ int save_log = 1; // show loading/saving messages
char db_path[1024] = "db";
struct mmo_map_server {
+ int fd;
uint32 ip;
uint16 port;
int users;
unsigned short map[MAX_MAP_PER_SERVER];
} server[MAX_MAP_SERVERS];
-int server_fd[MAX_MAP_SERVERS];
int login_fd, char_fd;
char userid[24];
@@ -290,7 +290,7 @@ int search_character_online(int aid, int cid)
if(character &&
character->char_id == cid &&
character->server > -1)
- return server_fd[character->server];
+ return server[character->server].fd;
return -1;
}
static void * create_online_char_data(DBKey key, va_list args)
@@ -335,7 +335,7 @@ void set_char_online(int map_id, int char_id, int account_id)
if (char_id != 99)
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);
- mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
}
character->char_id = (char_id==99)?-1:char_id;
@@ -402,15 +402,14 @@ static int char_db_setoffline(DBKey key, void* data, va_list ap)
static int char_db_kickoffline(DBKey key, void* data, va_list ap)
{
struct online_char_data* character = (struct online_char_data*)data;
- int server = va_arg(ap, int);
+ int server_id = va_arg(ap, int);
- if (server > -1 && character->server != server)
+ if (server_id > -1 && character->server != server_id)
return 0;
//Kick out any connected characters, and set them offline as appropiate.
if (character->server > -1)
- mapif_disconnectplayer(server_fd[character->server],
- character->account_id, character->char_id, 1);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 1);
else if (character->waiting_disconnect == -1)
set_char_offline(character->char_id, character->account_id);
else return 0;
@@ -1375,7 +1374,7 @@ static int create_online_files_sub(DBKey key, void* data, va_list va)
}
j = character->server;
- if (server_fd[j] < 0) {
+ if (server[j].fd < 0) {
server[j].users = 0;
return -1;
}
@@ -1670,7 +1669,7 @@ int count_users(void)
users = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++)
- if (server_fd[i] >= 0)
+ if (server[i].fd >= 0)
users += server[i].users;
return users;
@@ -1915,7 +1914,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
{ // check if character is not online already. [Skotlex]
if (character->server > -1)
{ //Character already online. KICK KICK KICK
- mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
if (character->waiting_disconnect == -1)
character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0);
WFIFOW(fd,0) = 0x81;
@@ -1991,7 +1990,7 @@ int parse_fromlogin(int fd)
send_accounts_tologin(-1, gettick(), 0, 0);
// if no map-server already connected, display a message...
- ARR_FIND( 0, MAX_MAP_SERVERS, i, server_fd[i] > 0 && server[i].map[0] );
+ ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd > 0 && server[i].map[0] );
if( i == MAX_MAP_SERVERS )
ShowStatus("Awaiting maps from map-server.\n");
}
@@ -2150,9 +2149,7 @@ int parse_fromlogin(int fd)
else
{
// at least 1 map-server
- for(i = 0; i < MAX_MAP_SERVERS; i++)
- if (server_fd[i] >= 0)
- break;
+ ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd >= 0 );
if (i == MAX_MAP_SERVERS)
char_log("'ladmin': Receiving a message for broadcast, but no map-server is online.\n");
else {
@@ -2328,7 +2325,7 @@ int parse_fromlogin(int fd)
{ //Kick out this player.
if (character->server > -1)
{ //Kick it from the map server it is on.
- mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
if (character->waiting_disconnect == -1)
character->waiting_disconnect = add_timer(gettick()+15000, chardb_waiting_disconnect, character->account_id, 0);
} else { //Manual kick from char server.
@@ -2605,9 +2602,7 @@ int parse_frommap(int fd)
int i, j;
int id;
- for(id = 0; id < MAX_MAP_SERVERS; id++)
- if (server_fd[id] == fd)
- break;
+ ARR_FIND( 0, MAX_MAP_SERVERS, id, server[id].fd == fd );
if(id == MAX_MAP_SERVERS)
set_eof(fd);
if(session[fd]->eof) {
@@ -2626,7 +2621,7 @@ int parse_frommap(int fd)
WBUFW(buf,2) = j * 4 + 10;
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
- server_fd[id] = -1;
+ server[id].fd = -1;
online_char_db->foreach(online_char_db,char_db_setoffline,i); //Tag relevant chars as 'in disconnected' server.
}
do_close(fd);
@@ -2696,7 +2691,7 @@ int parse_frommap(int fd)
}
// Transmitting the maps of the other map-servers to the new map-server
for(x = 0; x < MAX_MAP_SERVERS; x++) {
- if (server_fd[x] > 0 && x != id) {
+ if (server[x].fd > 0 && x != id) {
WFIFOHEAD(fd,10 +4*MAX_MAP_PER_SERVER);
WFIFOW(fd,0) = 0x2b04;
WFIFOL(fd,4) = htonl(server[x].ip);
@@ -2768,7 +2763,7 @@ int parse_frommap(int fd)
{
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);
- mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
}
character->char_id = cid;
character->server = id;
@@ -2833,7 +2828,7 @@ int parse_frommap(int fd)
name = RFIFOW(fd,18);
map_id = search_mapserver(name, ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port.
if (map_id >= 0)
- map_fd = server_fd[map_id];
+ map_fd = server[map_id].fd;
for(i = 0; i < char_num; i++) {
if (char_dat[i].status.account_id == RFIFOL(fd,2) &&
char_dat[i].status.char_id == RFIFOL(fd,14))
@@ -3180,7 +3175,7 @@ int search_mapserver(unsigned short map, uint32 ip, uint16 port)
for(i = 0; i < MAX_MAP_SERVERS; i++)
{
- if (server_fd[i] > 0
+ if (server[i].fd > 0
&& (ip == (uint32)-1 || server[i].ip == ip)
&& (port == (uint16)-1 || server[i].port == port))
{
@@ -3355,7 +3350,7 @@ int parse_char(int fd)
if (i < 0) {
unsigned short j;
//First check that there's actually a map server online.
- ARR_FIND( 0, MAX_MAP_SERVERS, j, server_fd[j] >= 0 && server[j].map[0] );
+ ARR_FIND( 0, MAX_MAP_SERVERS, j, server[j].fd >= 0 && server[j].map[0] );
if (j == MAX_MAP_SERVERS) {
ShowInfo("Connection Closed. No map servers available.\n");
WFIFOHEAD(fd,3);
@@ -3421,10 +3416,10 @@ int parse_char(int fd)
auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr;
//Send NEW auth packet [Kevin]
- if ((map_fd = server_fd[i]) < 1 || session[map_fd] == NULL)
+ if ((map_fd = server[i].fd) < 1 || session[map_fd] == NULL)
{
ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i);
- server_fd[i] = -1;
+ server[i].fd = -1;
memset(&server[i], 0, sizeof(struct mmo_map_server));
//Send server closed.
WFIFOHEAD(fd,3);
@@ -3626,10 +3621,7 @@ int parse_char(int fd)
char* l_pass = RFIFOP(fd,26);
l_user[23] = '\0';
l_pass[23] = '\0';
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if (server_fd[i] <= 0)
- break;
- }
+ ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd <= 0 );
if (i == MAX_MAP_SERVERS || strcmp(l_user, userid) || strcmp(l_pass, passwd)) {
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2af9;
@@ -3641,7 +3633,7 @@ int parse_char(int fd)
WFIFOB(fd,2) = 0;
WFIFOSET(fd,3);
- server_fd[i] = fd;
+ server[i].fd = fd;
server[i].ip = ntohl(RFIFOL(fd,54));
server[i].port = ntohs(RFIFOW(fd,58));
server[i].users = 0;
@@ -3736,7 +3728,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len)
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
int fd;
- if ((fd = server_fd[i]) > 0) {
+ if ((fd = server[i].fd) > 0) {
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
@@ -3755,7 +3747,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
int fd;
- if ((fd = server_fd[i]) > 0 && fd != sfd) {
+ if ((fd = server[i].fd) > 0 && fd != sfd) {
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
@@ -3772,7 +3764,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
if (fd >= 0) {
for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if (fd == server_fd[i]) {
+ if (fd == server[i].fd) {
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
@@ -4229,7 +4221,7 @@ int do_init(int argc, char **argv)
for(i = 0; i < MAX_MAP_SERVERS; i++) {
memset(&server[i], 0, sizeof(struct mmo_map_server));
- server_fd[i] = -1;
+ server[i].fd = -1;
}
//Read map indexes
diff --git a/src/char/int_homun.c b/src/char/int_homun.c
index 8a6089a13..be0dcd087 100644
--- a/src/char/int_homun.c
+++ b/src/char/int_homun.c
@@ -103,7 +103,7 @@ int inter_homun_fromstr(char *str,struct s_homunculus *p)
p->hskill[i].id = tmp_int[0];
p->hskill[i].lv = tmp_int[1];
} else
- ShowError("Read Homun: Unsupported Skill ID %d for homunculus (Homun ID=%d\n)", tmp_int[0], p->hom_id);
+ ShowError("Read Homun: Unsupported Skill ID %d for homunculus (Homun ID=%d)\n", tmp_int[0], p->hom_id);
next += len;
if (str[next] == ' ')
next++;
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index b44717d65..e18475c36 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -77,12 +77,12 @@ char login_db_level[32] = "level";
int lowest_gm_level = 1;
struct mmo_map_server {
+ int fd;
uint32 ip;
uint16 port;
int users;
unsigned short map[MAX_MAP_PER_SERVER];
} server[MAX_MAP_SERVERS];
-int server_fd[MAX_MAP_SERVERS];
int login_fd, char_fd;
char userid[24];
@@ -239,7 +239,7 @@ void set_char_online(int map_id, int char_id, int account_id)
if (char_id != 99)
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);
- mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
}
character->char_id = (char_id==99)?-1:char_id;
@@ -329,15 +329,14 @@ static int char_db_setoffline(DBKey key, void* data, va_list ap)
static int char_db_kickoffline(DBKey key, void* data, va_list ap)
{
struct online_char_data* character = (struct online_char_data*)data;
- int server = va_arg(ap, int);
+ int server_id = va_arg(ap, int);
- if (server > -1 && character->server != server)
+ if (server_id > -1 && character->server != server_id)
return 0;
//Kick out any connected characters, and set them offline as appropiate.
if (character->server > -1)
- mapif_disconnectplayer(server_fd[character->server],
- character->account_id, character->char_id, 1);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 1);
else if (character->waiting_disconnect == -1)
set_char_offline(character->char_id, character->account_id);
else return 0;
@@ -1423,7 +1422,7 @@ int count_users(void)
if (login_fd > 0 && session[login_fd]){
users = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if (server_fd[i] > 0) {
+ if (server[i].fd > 0) {
users += server[i].users;
}
}
@@ -1584,7 +1583,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
{ // check if character is not online already. [Skotlex]
if (character->server > -1)
{ //Character already online. KICK KICK KICK
- mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
if (character->waiting_disconnect == -1)
character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0);
WFIFOW(fd,0) = 0x81;
@@ -1660,7 +1659,7 @@ int parse_fromlogin(int fd)
send_accounts_tologin(-1, gettick(), 0, 0);
// if no map-server already connected, display a message...
- ARR_FIND( 0, MAX_MAP_SERVERS, i, server_fd[i] > 0 && server[i].map[0] );
+ ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd > 0 && server[i].map[0] );
if( i == MAX_MAP_SERVERS )
ShowStatus("Awaiting maps from map-server.\n");
}
@@ -1892,7 +1891,7 @@ int parse_fromlogin(int fd)
{ //Kick out this player.
if( character->server != -1 )
{ //Kick it from the map server it is on.
- mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
if (character->waiting_disconnect == -1)
character->waiting_disconnect = add_timer(gettick()+15000, chardb_waiting_disconnect, character->account_id, 0);
}
@@ -2124,9 +2123,7 @@ int parse_frommap(int fd)
return 0;
}
- for(id = 0; id < MAX_MAP_SERVERS; id++)
- if (server_fd[id] == fd)
- break;
+ ARR_FIND( 0, MAX_MAP_SERVERS, id, server[id].fd == fd );
if(id == MAX_MAP_SERVERS)
set_eof(fd);
if(session[fd]->eof) {
@@ -2146,9 +2143,9 @@ int parse_frommap(int fd)
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
memset(&server[id], 0, sizeof(struct mmo_map_server));
- if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server_fd[id]) )
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server[id].fd) )
Sql_ShowDebug(sql_handle);
- server_fd[id] = -1;
+ server[id].fd = -1;
online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
}
do_close(fd);
@@ -2215,7 +2212,7 @@ int parse_frommap(int fd)
}
// Transmitting the maps of the other map-servers to the new map-server
for(x = 0; x < MAX_MAP_SERVERS; x++) {
- if (server_fd[x] > 0 && x != id) {
+ if (server[x].fd > 0 && x != id) {
WFIFOHEAD(fd,10 +4*MAX_MAP_PER_SERVER);
WFIFOW(fd,0) = 0x2b04;
WFIFOL(fd,4) = htonl(server[x].ip);
@@ -2315,7 +2312,7 @@ int parse_frommap(int fd)
{
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);
- mapif_disconnectplayer(server_fd[character->server], character->account_id, character->char_id, 2);
+ mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2);
}
character->server = id;
character->char_id = cid;
@@ -2397,7 +2394,7 @@ int parse_frommap(int fd)
map_id = search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port.
if (map_id >= 0)
- map_fd = server_fd[map_id];
+ map_fd = server[map_id].fd;
//Char should just had been saved before this packet, so this should be safe. [Skotlex]
char_data = uidb_get(char_db_,RFIFOL(fd,14));
if (char_data == NULL)
@@ -2754,7 +2751,7 @@ int search_mapserver(unsigned short map, uint32 ip, uint16 port)
for(i = 0; i < MAX_MAP_SERVERS; i++)
{
- if (server_fd[i] > 0
+ if (server[i].fd > 0
&& (ip == (uint32)-1 || server[i].ip == ip)
&& (port == (uint16)-1 || server[i].port == port))
{
@@ -2930,7 +2927,7 @@ int parse_char(int fd)
if (i < 0) {
unsigned short j;
//First check that there's actually a map server online.
- ARR_FIND( 0, MAX_MAP_SERVERS, j, server_fd[j] >= 0 && server[j].map[0] );
+ ARR_FIND( 0, MAX_MAP_SERVERS, j, server[j].fd >= 0 && server[j].map[0] );
if (j == MAX_MAP_SERVERS) {
ShowInfo("Connection Closed. No map servers available.\n");
WFIFOHEAD(fd,3);
@@ -2994,10 +2991,10 @@ int parse_char(int fd)
auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr;
//Send NEW auth packet [Kevin]
- if ((map_fd = server_fd[i]) < 1 || session[map_fd] == NULL)
+ if ((map_fd = server[i].fd) < 1 || session[map_fd] == NULL)
{
ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i);
- server_fd[i] = -1;
+ server[i].fd = -1;
memset(&server[i], 0, sizeof(struct mmo_map_server));
//Send server closed.
WFIFOHEAD(fd,3);
@@ -3174,10 +3171,7 @@ int parse_char(int fd)
char* l_pass = RFIFOP(fd,26);
l_user[23] = '\0';
l_pass[23] = '\0';
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if (server_fd[i] <= 0)
- break;
- }
+ ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd <= 0 );
if (i == MAX_MAP_SERVERS || strcmp(l_user, userid) || strcmp(l_pass, passwd)) {
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2af9;
@@ -3189,7 +3183,7 @@ int parse_char(int fd)
WFIFOB(fd,2) = 0;
WFIFOSET(fd,3);
- server_fd[i] = fd;
+ server[i].fd = fd;
server[i].ip = ntohl(RFIFOL(fd,54));
server[i].port = ntohs(RFIFOW(fd,58));
server[i].users = 0;
@@ -3284,7 +3278,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len)
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
int fd;
- if ((fd = server_fd[i]) > 0) {
+ if ((fd = server[i].fd) > 0) {
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
@@ -3302,7 +3296,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
int fd;
- if ((fd = server_fd[i]) > 0 && fd != sfd) {
+ if ((fd = server[i].fd) > 0 && fd != sfd) {
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
@@ -3318,7 +3312,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
int i;
if (fd >= 0) {
- ARR_FIND( 0, MAX_MAP_SERVERS, i, fd == server_fd[i] );
+ ARR_FIND( 0, MAX_MAP_SERVERS, i, fd == server[i].fd );
if( i < MAX_MAP_SERVERS )
{
WFIFOHEAD(fd,len);
@@ -3835,7 +3829,7 @@ int do_init(int argc, char **argv)
for(i = 0; i < MAX_MAP_SERVERS; i++) {
memset(&server[i], 0, sizeof(struct mmo_map_server));
- server_fd[i] = -1;
+ server[i].fd = -1;
}
//Read map indexes
diff --git a/src/ladmin/ladmin.c b/src/ladmin/ladmin.c
index 7a7cf3dda..6c50b5ae6 100644
--- a/src/ladmin/ladmin.c
+++ b/src/ladmin/ladmin.c
@@ -4087,37 +4087,37 @@ int parse_fromlogin(int fd)
if (defaultlanguage == 'F')
ShowMessage(" Statut: 0 [Compte Ok]\n");
else
- ShowMessage(" Statut: 0 [Account OK]\n");
+ ShowMessage(" State: 0 [Account OK]\n");
break;
case 1:
ShowMessage(" Statut: 1 [Unregistered ID]\n");
break;
case 2:
- ShowMessage(" Statut: 2 [Incorrect Password]\n");
+ ShowMessage(" State: 2 [Incorrect Password]\n");
break;
case 3:
ShowMessage(" Statut: 3 [This ID is expired]\n");
break;
case 4:
- ShowMessage(" Statut: 4 [Rejected from Server]\n");
+ ShowMessage(" State: 4 [Rejected from Server]\n");
break;
case 5:
ShowMessage(" Statut: 5 [You have been blocked by the GM Team]\n");
break;
case 6:
- ShowMessage(" Statut: 6 [Your Game's EXE file is not the latest version]\n");
+ ShowMessage(" State: 6 [Your Game's EXE file is not the latest version]\n");
break;
case 7:
ShowMessage(" Statut: 7 [You are Prohibited to log in until %s]\n", error_message);
break;
case 8:
- ShowMessage(" Statut: 8 [Server is jammed due to over populated]\n");
+ ShowMessage(" State: 8 [Server is jammed due to over populated]\n");
break;
case 9:
ShowMessage(" Statut: 9 [No MSG]\n");
break;
default: // 100
- ShowMessage(" Statut: %d [This ID is totally erased]\n", (int)RFIFOL(fd,36));
+ ShowMessage(" State: %d [This ID is totally erased]\n", (int)RFIFOL(fd,36));
break;
}
if (defaultlanguage == 'F') {
@@ -4232,6 +4232,18 @@ int Connect_login_server(void)
return 0;
}
+// sends a ping packet to login server (will receive pong 0x2718)
+int ping_login_server(int tid, unsigned int tick, int id, int data)
+{
+ if (login_fd > 0 && session[login_fd] != NULL)
+ {
+ WFIFOHEAD(login_fd,2);
+ WFIFOW(login_fd,0) = 0x2719;
+ WFIFOSET(login_fd,2);
+ }
+ return 0;
+}
+
//-----------------------------------
// Reading general configuration file
//-----------------------------------
@@ -4380,6 +4392,10 @@ int do_init(int argc, char **argv)
Connect_login_server();
+ // keep the char-login connection alive
+ add_timer_func_list(ping_login_server, "ping_login_server");
+ add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
+
// minimalist core doesn't have sockets parsing,
// so we have to do this ourselves
while (runflag) {
diff --git a/src/login/Makefile.in b/src/login/Makefile.in
index 187a3eaf0..4bdfb5935 100644
--- a/src/login/Makefile.in
+++ b/src/login/Makefile.in
@@ -10,7 +10,7 @@ COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h
../common/grfio.h ../common/mapindex.h \
../common/ers.h ../common/md5calc.h
-LOGIN_OBJ = obj/login.o
+LOGIN_OBJ = obj/login.o obj/admin.o
LOGIN_H = login.h
@SET_MAKE@
diff --git a/src/login/login.c b/src/login/login.c
index 91a2f1996..df80e69ee 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -20,36 +20,10 @@
#include <string.h>
#include <sys/stat.h> // for stat/lstat/fstat
-struct Login_Config {
-
- uint32 login_ip; // the address to bind to
- uint16 login_port; // the port to bind to
- unsigned int ip_sync_interval; // interval (in minutes) to execute a DNS/IP update (for dynamic IPs)
- bool log_login; // whether to log login server actions or not
- char date_format[32]; // date format used in messages
- bool console; // console input system enabled?
- bool new_account_flag; // autoregistration via _M/_F ?
-// bool case_sensitive; // are logins case sensitive ?
- bool use_md5_passwds; // work with password hashes instead of plaintext passwords?
-// bool login_gm_read; // should the login server handle info about gm accounts?
- 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)
-
-// bool ipban; // perform IP blocking (via contents of `ipbanlist`) ?
-// bool dynamic_pass_failure_ban; // automatic IP blocking due to failed login attemps ?
-// unsigned int dynamic_pass_failure_ban_interval; // how far to scan the loginlog for password failures
-// unsigned int dynamic_pass_failure_ban_limit; // number of failures needed to trigger the ipban
-// unsigned int dynamic_pass_failure_ban_duration; // duration of the ipban
- bool use_dnsbl; // dns blacklist blocking ?
- char dnsbl_servs[1024]; // comma-separated list of dnsbl servers
-
-} login_config;
+struct Login_Config login_config;
int login_fd; // login server socket
#define MAX_SERVERS 30
-int server_fd[MAX_SERVERS]; // char server sockets
struct mmo_char_server server[MAX_SERVERS]; // char server data
// Advanced subnet check [LuzZza]
@@ -75,11 +49,10 @@ int account_id_count = START_ACCOUNT_NUM;
char account_filename[1024] = "save/account.txt";
char GM_account_filename[1024] = "conf/GM_account.txt";
-char login_log_filename[1024] = "log/login.log";
FILE *log_fp = NULL;
char login_log_unknown_packets_filename[1024] = "log/login_unknown_packets.log";
int save_unknown_packets = 0;
-long creation_time_GM_account_file;
+long creation_time_GM_account_file; // tracks the last-changed timestamp of the gm accounts file
int gm_account_filename_check_timer = 15; // Timer to check if GM_account file has been changed and reload GM account automaticaly (in seconds; default: 15)
@@ -99,7 +72,6 @@ char *access_deny = NULL;
int access_ladmin_allownum = 0;
char *access_ladmin_allow = NULL;
-int add_to_unlimited_account = 0; // Give possibility or not to adjust (ladmin command: timeadd) the time of an unlimited account.
int start_limited_time = -1; // Starting additional sec from now for the limited time at creation of accounts (-1: unlimited time, 0 or more: additional sec from now)
struct login_session_data {
@@ -107,46 +79,17 @@ struct login_session_data {
char md5key[20];
};
-#define AUTH_FIFO_SIZE 256
-struct _auth_fifo {
- int account_id;
- uint32 login_id1, login_id2;
- uint32 ip;
- uint8 sex;
- bool delflag;
-} auth_fifo[AUTH_FIFO_SIZE];
+// auth information of incoming clients
+struct _auth_fifo auth_fifo[AUTH_FIFO_SIZE];
int auth_fifo_pos = 0;
-struct online_login_data {
- int account_id;
- int waiting_disconnect;
- int char_server;
-};
-
-// holds info about all existing accounts
-struct auth_data {
- int account_id;
- uint8 sex; // 0, 1, 2
- char userid[24];
- char pass[32+1]; // 23+1 for normal, 32+1 for md5-ed passwords
- char lastlogin[24];
- int logincount;
- uint32 state; // packet 0x006a value + 1 (0: compte OK)
- char email[40]; // e-mail (by default: a@a.com)
- char error_message[20]; // Message of error code #6 = Your are Prohibited to log in until %s (packet 0x006a)
- time_t ban_until_time; // # of seconds 1/1/1970 (timestamp): ban time limit of the account (0 = no ban)
- time_t connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- char last_ip[16]; // save of last IP of connection
- char memo[255]; // a memo field
- int account_reg2_num;
- struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
-} *auth_dat = NULL;
-
+// account database
+struct auth_data* auth_dat = NULL;
uint32 auth_num = 0, auth_max = 0;
// define the number of times that some players must authentify them before to save account file.
-// it's just about normal authentification. If an account is created or modified, save is immediatly done.
-// An authentification just change last connected IP and date. It already save in log file.
+// it's just about normal authentication. If an account is created or modified, save is immediatly done.
+// An authentication just change last connected IP and date. It already save in log file.
// set minimum auth change before save:
#define AUTH_BEFORE_SAVE_FILE 10
// set divider of auth_num to found number of change before save
@@ -158,60 +101,34 @@ char admin_pass[24] = "";
char gm_pass[64] = "";
int level_new_gm = 60;
+int parse_admin(int fd);
-static DBMap* online_db; // int account_id -> struct online_login_data*
-
-int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len);
-
-//------------------------------
-// Writing function of logs file
-//------------------------------
-int login_log(char *fmt, ...)
-{
- if( login_config.log_login ) {
- va_list ap;
- time_t raw_time;
- char tmpstr[2048];
-
- if(!log_fp)
- log_fp = fopen(login_log_filename, "a");
+//-----------------------------------------------------
+// Online User Database [Wizputer]
+//-----------------------------------------------------
- if (log_fp) {
- if (fmt[0] == '\0') // jump a line if no message
- fprintf(log_fp, "\n");
- else {
- va_start(ap, fmt);
- time(&raw_time);
- strftime(tmpstr, 24, login_config.date_format, localtime(&raw_time));
- sprintf(tmpstr + strlen(tmpstr), ": %s", fmt);
- vfprintf(log_fp, tmpstr, ap);
- va_end(ap);
- }
- fflush(log_fp); // under cygwin or windows, if software is stopped, data are not written in the file -> fflush at every line
- }
- }
+struct online_login_data {
+ int account_id;
+ int waiting_disconnect;
+ int char_server;
+};
- return 0;
-}
+static DBMap* online_db; // int account_id -> struct online_login_data*
+static int waiting_disconnect_timer(int tid, unsigned int tick, int id, int data);
static void* create_online_user(DBKey key, va_list args)
{
- struct online_login_data *p;
- p = aCalloc(1, sizeof(struct online_login_data));
+ struct online_login_data* p;
+ CREATE(p, struct online_login_data, 1);
p->account_id = key.i;
p->char_server = -1;
p->waiting_disconnect = -1;
return p;
}
-static int waiting_disconnect_timer(int tid, unsigned int tick, int id, int data);
-
-//-----------------------------------------------------
-// Online User Database [Wizputer]
-//-----------------------------------------------------
void add_online_user(int char_server, int account_id)
{
- struct online_login_data *p;
+ struct online_login_data* p;
if( !login_config.online_check )
return;
p = idb_ensure(online_db, account_id, create_online_user);
@@ -246,13 +163,26 @@ static int waiting_disconnect_timer(int tid, unsigned int tick, int id, int data
return 0;
}
-static int sync_ip_addresses(int tid, unsigned int tick, int id, int data)
+//--------------------------------------------------------------------
+// Packet send to all char-servers, except one (wos: without our self)
+//--------------------------------------------------------------------
+int charif_sendallwos(int sfd, uint8* buf, size_t len)
{
- uint8 buf[2];
- ShowInfo("IP Sync in progress...\n");
- WBUFW(buf,0) = 0x2735;
- charif_sendallwos(-1, buf, 2);
- return 0;
+ int i, c;
+
+ for( i = 0, c = 0; i < MAX_SERVERS; ++i )
+ {
+ int fd = server[i].fd;
+ if( session_isValid(fd) && fd != sfd )
+ {
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ ++c;
+ }
+ }
+
+ return c;
}
//----------------------------------------------------------------------
@@ -262,10 +192,8 @@ static int sync_ip_addresses(int tid, unsigned int tick, int id, int data)
int isGM(int account_id)
{
unsigned int i;
- for(i=0; i < GM_num; i++)
- if(gm_account_db[i].account_id == account_id)
- return gm_account_db[i].level;
- return 0;
+ ARR_FIND( 0, GM_num, i, gm_account_db[i].account_id == account_id );
+ return ( i < GM_num ) ? gm_account_db[i].level : 0;
}
//----------------------------------------------------------------------
@@ -274,39 +202,33 @@ int isGM(int account_id)
void addGM(int account_id, int level)
{
unsigned int i;
- int do_add = 0;
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == account_id) {
- do_add = 1;
- break;
+
+ ARR_FIND( 0, auth_num, i, auth_dat[i].account_id == account_id );
+ if( i < auth_num )
+ return; // no such account
+
+ ARR_FIND( 0, GM_num, i, gm_account_db[i].account_id == account_id );
+ if( i < GM_num )
+ {
+ if (gm_account_db[i].level == level)
+ ShowWarning("addGM: GM account %d defined twice (same level: %d).\n", account_id, level);
+ else {
+ ShowWarning("addGM: GM account %d defined twice (levels: %d and %d).\n", account_id, gm_account_db[i].level, level);
+ gm_account_db[i].level = level;
}
+ return; // entry already present
}
- for(i = 0; i < GM_num; i++)
- if (gm_account_db[i].account_id == account_id) {
- if (gm_account_db[i].level == level)
- ShowWarning("addGM: GM account %d defined twice (same level: %d).\n", account_id, level);
- else {
- ShowWarning("addGM: GM account %d defined twice (levels: %d and %d).\n", account_id, gm_account_db[i].level, level);
- gm_account_db[i].level = level;
- }
- return;
- }
- // if new account
- if (i == GM_num && do_add) {
- if (GM_num >= GM_max) {
- GM_max += 256;
- gm_account_db = (struct gm_account*)aRealloc(gm_account_db, sizeof(struct gm_account) * GM_max);
- memset(gm_account_db + (GM_max - 256), 0, sizeof(struct gm_account) * 256);
- }
- gm_account_db[GM_num].account_id = account_id;
- gm_account_db[GM_num].level = level;
- GM_num++;
- if (GM_num >= 4000) {
- ShowWarning("4000 GM accounts found. Next GM accounts are not read.\n");
- login_log("***WARNING: 4000 GM accounts found. Next GM accounts are not read.\n");
- }
+ // new account
+ if (GM_num >= GM_max) {
+ GM_max += 256;
+ RECREATE(gm_account_db, struct gm_account, GM_max);
}
+ gm_account_db[GM_num].account_id = account_id;
+ gm_account_db[GM_num].level = level;
+ GM_num++;
+ if (GM_num >= 4000)
+ ShowWarning("4000 GM accounts found. Next GM accounts are not read.\n");
}
//-------------------------------------------------------
@@ -322,7 +244,7 @@ int read_gm_account(void)
int start_range = 0, end_range = 0, is_range = 0, current_id = 0;
if(gm_account_db) aFree(gm_account_db);
- gm_account_db = (struct gm_account*)aCalloc(GM_max, sizeof(struct gm_account));
+ CREATE(gm_account_db, struct gm_account, 1);
GM_num = 0;
// get last modify time/date
@@ -333,9 +255,6 @@ int read_gm_account(void)
if ((fp = fopen(GM_account_filename, "r")) == NULL) {
ShowError("read_gm_account: GM accounts file [%s] not found.\n", GM_account_filename);
- ShowError(" Actually, there is no GM accounts on the server.\n");
- login_log("read_gm_account: GM accounts file [%s] not found.\n", GM_account_filename);
- login_log(" Actually, there is no GM accounts on the server.\n");
return 1;
}
@@ -373,7 +292,6 @@ int read_gm_account(void)
fclose(fp);
ShowStatus("read_gm_account: file '%s' read (%d GM accounts found).\n", GM_account_filename, GM_num);
- login_log("read_gm_account: file '%s' read (%d GM accounts found).\n", GM_account_filename, GM_num);
return 0;
}
@@ -566,7 +484,7 @@ int mmo_auth_init(void)
int server_count = 0;
auth_max = 256;
- auth_dat = (struct auth_data*)aCalloc(auth_max, sizeof(struct auth_data));
+ CREATE(auth_dat, struct auth_data, auth_max);
if ((fp = fopen(account_filename, "r")) == NULL) {
// no account file -> no account -> no login, including char-server (ERROR)
@@ -603,10 +521,7 @@ int mmo_auth_init(void)
// Some checks
if (account_id > END_ACCOUNT_NUM) {
ShowError(CL_RED"mmmo_auth_init: an account has an id higher than %d\n", END_ACCOUNT_NUM);
- ShowError(" account id #%d -> account not read (saved in log file)."CL_RESET"\n", account_id);
- login_log("mmmo_auth_init: ******Error: an account has an id higher than %d.\n", END_ACCOUNT_NUM);
- login_log(" account id #%d -> account not read (saved in next line):\n", account_id);
- login_log("%s", line);
+ ShowError(" account id #%d -> account not read (data is lost!)."CL_RESET"\n", account_id);
continue;
}
userid[23] = '\0';
@@ -614,17 +529,11 @@ int mmo_auth_init(void)
for(j = 0; j < auth_num; j++) {
if (auth_dat[j].account_id == account_id) {
ShowError(CL_RED"mmmo_auth_init: an account has an identical id to another.\n");
- ShowError(" account id #%d -> new account not read (saved in log file)."CL_RED"\n", account_id);
- login_log("mmmo_auth_init: ******Error: an account has an identical id to another.\n");
- login_log(" account id #%d -> new account not read (saved in next line):\n", account_id);
- login_log("%s", line);
+ ShowError(" account id #%d -> new account not read (data is lost!)."CL_RED"\n", account_id);
break;
} else if (strcmp(auth_dat[j].userid, userid) == 0) {
ShowError(CL_RED"mmmo_auth_init: account name already exists.\n");
- ShowError(" account name '%s' -> new account not read (saved in log file)."CL_RESET"\n", userid); // 2 lines, account name can be long.
- login_log("mmmo_auth_init: ******Error: an account has an identical name to another.\n");
- login_log(" account name '%s' -> new account not read (saved in next line):\n", userid);
- login_log("%s", line);
+ ShowError(" account name '%s' -> new account not read (data is lost!)."CL_RESET"\n", userid); // 2 lines, account name can be long.
break;
}
}
@@ -650,7 +559,7 @@ int mmo_auth_init(void)
remove_control_chars(lastlogin);
strncpy(auth_dat[auth_num].lastlogin, lastlogin, 24);
- auth_dat[auth_num].sex = (sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm');
+ auth_dat[auth_num].sex = (sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm') ? 1 : 0;
if (logincount >= 0)
auth_dat[auth_num].logincount = logincount;
@@ -725,10 +634,7 @@ int mmo_auth_init(void)
&account_id, userid, pass, lastlogin, &sex, &logincount, &state, &n)) >= 5) {
if (account_id > END_ACCOUNT_NUM) {
ShowError(CL_RED"mmmo_auth_init: an account has an id higher than %d\n", END_ACCOUNT_NUM);
- ShowError(" account id #%d -> account not read (saved in log file)."CL_RESET"\n", account_id);
- login_log("mmmo_auth_init: ******Error: an account has an id higher than %d.\n", END_ACCOUNT_NUM);
- login_log(" account id #%d -> account not read (saved in next line):\n", account_id);
- login_log("%s", line);
+ ShowError(" account id #%d -> account not read (data is lost!)."CL_RESET"\n", account_id);
continue;
}
userid[23] = '\0';
@@ -736,17 +642,11 @@ int mmo_auth_init(void)
for(j = 0; j < auth_num; j++) {
if (auth_dat[j].account_id == account_id) {
ShowError(CL_RED"mmo_auth_init: an account has an identical id to another.\n");
- ShowError(" account id #%d -> new account not read (saved in log file)."CL_RESET"\n", account_id);
- login_log("mmmo_auth_init: ******Error: an account has an identical id to another.\n");
- login_log(" account id #%d -> new account not read (saved in next line):\n", account_id);
- login_log("%s", line);
+ ShowError(" account id #%d -> new account not read (data is lost!)."CL_RESET"\n", account_id);
break;
} else if (strcmp(auth_dat[j].userid, userid) == 0) {
ShowError(CL_RED"mmo_auth_init: account name already exists.\n");
- ShowError(" account name '%s' -> new account not read (saved in log file)."CL_RESET"\n", userid);
- login_log("mmmo_auth_init: ******Error: an account has an identical id to another.\n");
- login_log(" account id #%d -> new account not read (saved in next line):\n", account_id);
- login_log("%s", line);
+ ShowError(" account name '%s' -> new account not read (data is lost!)."CL_RESET"\n", userid);
break;
}
}
@@ -755,7 +655,7 @@ int mmo_auth_init(void)
if (auth_num >= auth_max) {
auth_max += 256;
- auth_dat = (struct auth_data*)aRealloc(auth_dat, sizeof(struct auth_data) * auth_max);
+ RECREATE(auth_dat, struct auth_data, auth_max);
}
memset(&auth_dat[auth_num], '\0', sizeof(struct auth_data));
@@ -772,7 +672,7 @@ int mmo_auth_init(void)
remove_control_chars(lastlogin);
strncpy(auth_dat[auth_num].lastlogin, lastlogin, 24);
- auth_dat[auth_num].sex = (sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm');
+ auth_dat[auth_num].sex = (sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm') ? 1 : 0;
if (i >= 6) {
if (logincount >= 0)
@@ -834,39 +734,29 @@ int mmo_auth_init(void)
}
fclose(fp);
- if (auth_num == 0) {
+ if( auth_num == 0 )
ShowNotice("mmo_auth_init: No account found in %s.\n", account_filename);
- sprintf(line, "No account found in %s.", account_filename);
- } else {
- if (auth_num == 1) {
- ShowStatus("mmo_auth_init: 1 account read in %s,\n", account_filename);
- sprintf(line, "1 account read in %s,", account_filename);
- } else {
- ShowStatus("mmo_auth_init: %d accounts read in %s,\n", auth_num, account_filename);
- sprintf(line, "%u accounts read in %s,", auth_num, account_filename);
- }
- if (GM_count == 0) {
- ShowStatus(" of which is no GM account, and ");
- sprintf(str, "%s of which is no GM account and", line);
- } else if (GM_count == 1) {
- ShowStatus(" of which is 1 GM account, and ");
- sprintf(str, "%s of which is 1 GM account and", line);
- } else {
- ShowStatus(" of which is %d GM accounts, and ", GM_count);
- sprintf(str, "%s of which is %d GM accounts and", line, GM_count);
- }
- if (server_count == 0) {
- printf("no server account ('S').\n");
- sprintf(line, "%s no server account ('S').", str);
- } else if (server_count == 1) {
- printf("1 server account ('S').\n");
- sprintf(line, "%s 1 server account ('S').", str);
- } else {
- printf("%d server accounts ('S').\n", server_count);
- sprintf(line, "%s %d server accounts ('S').", str, server_count);
- }
- }
- login_log("%s\n", line);
+ else
+ if( auth_num == 1 )
+ ShowStatus("mmo_auth_init: 1 account read in %s,\n", account_filename);
+ else
+ ShowStatus("mmo_auth_init: %d accounts read in %s,\n", auth_num, account_filename);
+
+ if( GM_count == 0 )
+ ShowStatus(" of which is no GM account, and ");
+ else
+ if( GM_count == 1 )
+ ShowStatus(" of which is 1 GM account, and ");
+ else
+ ShowStatus(" of which is %d GM accounts, and ", GM_count);
+
+ if( server_count == 0 )
+ ShowStatus(" no server account ('S').\n");
+ else
+ if( server_count == 1 )
+ ShowStatus(" 1 server account ('S').\n");
+ else
+ ShowStatus(" %d server accounts ('S').\n", server_count);
return 0;
}
@@ -943,18 +833,18 @@ void mmo_auth_sync(void)
//-----------------------------------------------------
// Check if we must save accounts file or not
// every minute, we check if we must save because we
-// have do some authentifications without arrive to
-// the minimum of authentifications for the save.
+// have do some authentications without arrive to
+// the minimum of authentications for the save.
// Note: all other modification of accounts (deletion,
// change of some informations excepted lastip/
// lastlogintime, creation) are always save
// immediatly and set the minimum of
-// authentifications to its initialization value.
+// authentications to its initialization value.
//-----------------------------------------------------
int check_auth_sync(int tid, unsigned int tick, int id, int data)
{
// we only save if necessary:
- // we have do some authentifications without do saving
+ // we have do some authentications without do saving
if (auth_before_save_file < AUTH_BEFORE_SAVE_FILE ||
auth_before_save_file < (int)(auth_num / AUTH_SAVE_FILE_DIVIDER))
mmo_auth_sync();
@@ -962,23 +852,16 @@ int check_auth_sync(int tid, unsigned int tick, int id, int data)
return 0;
}
-//--------------------------------------------------------------------
-// Packet send to all char-servers, except one (wos: without our self)
-//--------------------------------------------------------------------
-int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
+//-----------------------------------------------------
+// periodic ip address synchronization
+//-----------------------------------------------------
+static int sync_ip_addresses(int tid, unsigned int tick, int id, int data)
{
- int i, c, fd;
-
- for(i = 0, c = 0; i < MAX_SERVERS; i++) {
- if ((fd = server_fd[i]) >= 0 && fd != sfd) {
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- c++;
- }
- }
-
- return c;
+ uint8 buf[2];
+ ShowInfo("IP Sync in progress...\n");
+ WBUFW(buf,0) = 0x2735;
+ charif_sendallwos(-1, buf, 2);
+ return 0;
}
//-----------------------------------------------------
@@ -1186,7 +1069,6 @@ int mmo_auth(struct mmo_account* account, int fd)
//only continue if amount in this time limit is allowed (account registration flood protection)[Kevin]
if(DIFF_TICK(gettick(), new_reg_tick) < 0 && num_regs >= allowed_regs) {
ShowNotice("Account registration denied (registration limit exceeded) to %s!\n", ip);
- login_log("Notice: Account registration denied (registration limit exceeded) to %s!", ip);
return 3;
}
newaccount = 1;
@@ -1201,14 +1083,14 @@ int mmo_auth(struct mmo_account* account, int fd)
{
if( i != auth_num )
{
- login_log("Attempt of creation of an already existant account (account: %s_%c, pass: %s, received pass: %s, ip: %s)\n", account->userid, account->userid[len-1], auth_dat[i].pass, account->passwd, ip);
+ ShowNotice("Attempt of creation of an already existant account (account: %s_%c, pass: %s, received pass: %s, ip: %s)\n", account->userid, account->userid[len-1], auth_dat[i].pass, account->passwd, ip);
return 1; // 1 = Incorrect Password
}
else
{
int new_id = mmo_auth_new(account, account->userid[len-1], "a@a.com");
unsigned int tick = gettick();
- login_log("Account creation (account %s (id: %d), pass: %s, sex: %c, connection with _F/_M, ip: %s)\n", account->userid, new_id, account->passwd, account->userid[len-1], ip);
+ ShowNotice("Account creation (account %s, id: %d, pass: %s, sex: %c, connection with _F/_M, ip: %s)\n", account->userid, new_id, account->passwd, account->userid[len-1], ip);
auth_before_save_file = 0; // Creation of an account -> save accounts file immediatly
if( DIFF_TICK(tick, new_reg_tick) > 0 )
@@ -1232,7 +1114,7 @@ int mmo_auth(struct mmo_account* account, int fd)
if( i == auth_num )
{
- login_log("Unknown account (account: %s, received pass: %s, ip: %s)\n", account->userid, account->passwd, ip);
+ ShowNotice("Unknown account (account: %s, received pass: %s, ip: %s)\n", account->userid, account->passwd, ip);
return 0; // 0 = Unregistered ID
}
@@ -1243,13 +1125,13 @@ int mmo_auth(struct mmo_account* account, int fd)
if( !check_password(session[fd]->session_data, account->passwdenc, user_password, auth_dat[i].pass) )
{
- login_log("Invalid password (account: %s, pass: %s, received pass: %s, ip: %s)\n", account->userid, auth_dat[i].pass, (account->passwdenc) ? "[MD5]" : account->passwd, ip);
+ ShowNotice("Invalid password (account: %s, pass: %s, received pass: %s, ip: %s)\n", account->userid, auth_dat[i].pass, (account->passwdenc) ? "[MD5]" : account->passwd, ip);
return 1; // 1 = Incorrect Password
}
if( auth_dat[i].connect_until_time != 0 && auth_dat[i].connect_until_time < time(NULL) )
{
- login_log("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", account->userid, account->passwd, ip);
+ ShowNotice("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", account->userid, account->passwd, ip);
return 2; // 2 = This ID is expired
}
@@ -1257,13 +1139,13 @@ int mmo_auth(struct mmo_account* account, int fd)
{
strftime(tmpstr, 20, login_config.date_format, localtime(&auth_dat[i].ban_until_time));
tmpstr[19] = '\0';
- login_log("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n", account->userid, account->passwd, tmpstr, ip);
+ ShowNotice("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n", account->userid, account->passwd, tmpstr, ip);
return 6; // 6 = Your are Prohibited to log in until %s
}
if( auth_dat[i].state )
{
- login_log("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n", account->userid, account->passwd, auth_dat[i].state, ip);
+ ShowNotice("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n", account->userid, account->passwd, auth_dat[i].state, ip);
return auth_dat[i].state - 1;
}
@@ -1273,8 +1155,8 @@ int mmo_auth(struct mmo_account* account, int fd)
if( data && data->char_server > -1 )
{
//Request char servers to kick this account out. [Skotlex]
- unsigned char buf[8];
- ShowNotice("User [%d] is already online - Rejected.\n",auth_dat[i].account_id);
+ uint8 buf[8];
+ ShowNotice("User '%s' is already online - Rejected.\n", auth_dat[i].userid);
WBUFW(buf,0) = 0x2734;
WBUFL(buf,2) = auth_dat[i].account_id;
charif_sendallwos(-1, buf, 6);
@@ -1284,7 +1166,7 @@ int mmo_auth(struct mmo_account* account, int fd)
}
}
- login_log("Authentification accepted (account: %s (id: %d), ip: %s)\n", account->userid, auth_dat[i].account_id, ip);
+ ShowNotice("Authentication accepted (account: %s, id: %d, ip: %s)\n", account->userid, auth_dat[i].account_id, ip);
// auth start : time seed
time(&raw_time);
@@ -1337,13 +1219,11 @@ int parse_fromchar(int fd)
{
uint32 i;
int j, id;
-
- uint32 ipl = session[fd]->client_addr;
+ uint32 ipl;
char ip[16];
- ip2str(ipl, ip);
- ARR_FIND( 0, MAX_SERVERS, id, server_fd[id] == fd );
- if (id == MAX_SERVERS)
+ ARR_FIND( 0, MAX_SERVERS, id, server[id].fd == fd );
+ if( id == MAX_SERVERS )
{// not a char server
set_eof(fd);
do_close(fd);
@@ -1353,23 +1233,25 @@ int parse_fromchar(int fd)
if( session[fd]->eof )
{
ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
- login_log("Char-server '%s' has disconnected (ip: %s).\n", server[id].name, ip);
- server_fd[id] = -1;
+ server[id].fd = -1;
memset(&server[id], 0, sizeof(struct mmo_char_server));
online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline.
do_close(fd);
return 0;
}
+ ipl = server[id].ip;
+ ip2str(ipl, ip);
+
while( RFIFOREST(fd) >= 2 )
{
uint16 command = RFIFOW(fd,0);
switch( command )
{
-
+
case 0x2709: // request from map-server via char-server to reload GM accounts
- login_log("Char-server '%s': Request to re-load GM configuration file (ip: %s).\n", server[id].name, ip);
+ ShowStatus("Char-server '%s': Request to re-load GM configuration file (ip: %s).\n", server[id].name, ip);
read_gm_account();
// send GM accounts to all char-servers
send_GM_accounts(-1);
@@ -1381,33 +1263,33 @@ int parse_fromchar(int fd)
return 0;
{
int account_id = RFIFOL(fd,2);
- for( i = 0; i < AUTH_FIFO_SIZE; ++i )
- {
- if( auth_fifo[i].account_id == RFIFOL(fd,2) &&
- auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
- auth_fifo[i].login_id2 == RFIFOL(fd,10) &&
- auth_fifo[i].sex == RFIFOB(fd,14) &&
- auth_fifo[i].ip == ntohl(RFIFOL(fd,15)) &&
- !auth_fifo[i].delflag)
- {
- auth_fifo[i].delflag = 1;
- break;
- }
- }
-
- if( i != AUTH_FIFO_SIZE && account_id > 0 )
+ ARR_FIND( 0, AUTH_FIFO_SIZE, i,
+ auth_fifo[i].account_id == RFIFOL(fd,2) &&
+ auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
+ auth_fifo[i].login_id2 == RFIFOL(fd,10) &&
+ auth_fifo[i].sex == RFIFOB(fd,14) &&
+ auth_fifo[i].ip == ntohl(RFIFOL(fd,15)) &&
+ !auth_fifo[i].delflag );
+
+ if( i < AUTH_FIFO_SIZE )
+ auth_fifo[i].delflag = 1;
+
+ if( i < AUTH_FIFO_SIZE && account_id > 0 )
{// send ack
time_t connect_until_time;
char email[40];
unsigned int k;
- login_log("Char-server '%s': authentification of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
+ //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
ARR_FIND( 0, auth_num, k, auth_dat[k].account_id == account_id );
- if( k != auth_num ) {
+ if( k < auth_num )
+ {
strcpy(email, auth_dat[k].email);
connect_until_time = auth_dat[k].connect_until_time;
- } else {
+ }
+ else
+ {
memset(email, 0, sizeof(email));
connect_until_time = 0;
}
@@ -1421,8 +1303,8 @@ int parse_fromchar(int fd)
WFIFOSET(fd,51);
}
else
- {// authentification not found
- login_log("Char-server '%s': authentification of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
+ {// authentication not found
+ ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
WFIFOHEAD(fd,51);
WFIFOW(fd,0) = 0x2713;
WFIFOL(fd,2) = account_id;
@@ -1437,7 +1319,7 @@ int parse_fromchar(int fd)
break;
case 0x2714:
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
//printf("parse_fromchar: Receiving of the users number of the server '%s': %d\n", server[id].name, RFIFOL(fd,2));
server[id].users = RFIFOL(fd,2);
@@ -1453,20 +1335,20 @@ int parse_fromchar(int fd)
int acc = RFIFOL(fd,2);
safestrncpy(email, (char*)RFIFOP(fd,6), 40);
remove_control_chars(email);
- if (e_mail_check(email) == 0)
- login_log("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n", server[id].name, acc, ip);
- else {
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == acc && (strcmp(auth_dat[i].email, "a@a.com") == 0 || auth_dat[i].email[0] == '\0')) {
- memcpy(auth_dat[i].email, email, 40);
- login_log("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, acc, email, ip);
- // Save
- mmo_auth_sync();
- break;
- }
+ if( e_mail_check(email) == 0 )
+ ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n", server[id].name, acc, ip);
+ else
+ {
+ ARR_FIND( 0, auth_num, i, auth_dat[i].account_id == acc && (strcmp(auth_dat[i].email, "a@a.com") == 0 || auth_dat[i].email[0] == '\0') );
+ if( i == auth_num )
+ ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, acc, ip);
+ else
+ {
+ memcpy(auth_dat[i].email, email, 40);
+ ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, acc, email, ip);
+ // Save
+ mmo_auth_sync();
}
- if (i == auth_num)
- login_log("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, acc, ip);
}
RFIFOSKIP(fd,46);
@@ -1474,24 +1356,21 @@ 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
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == (int)RFIFOL(fd,2)) {
- login_log("Char-server '%s': e-mail of the account %d found (ip: %s).\n",
- server[id].name, RFIFOL(fd,2), ip);
- WFIFOW(fd,0) = 0x2717;
- WFIFOL(fd,2) = RFIFOL(fd,2);
- memcpy(WFIFOP(fd, 6), auth_dat[i].email, 40);
- WFIFOL(fd,46) = (unsigned long)auth_dat[i].connect_until_time;
- WFIFOSET(fd,50);
- break;
- }
+ ARR_FIND( 0, auth_num, i, auth_dat[i].account_id == (int)RFIFOL(fd,2) );
+ if( i == auth_num )
+ ShowNotice("Char-server '%s': e-mail of the account %d NOT found (ip: %s).\n", server[id].name, RFIFOL(fd,2), ip);
+ else
+ {
+ //ShowNotice("Char-server '%s': e-mail of the account %d found (ip: %s).\n", server[id].name, RFIFOL(fd,2), ip);
+ WFIFOW(fd,0) = 0x2717;
+ WFIFOL(fd,2) = RFIFOL(fd,2);
+ safestrncpy((char*)WFIFOP(fd, 6), auth_dat[i].email, 40);
+ WFIFOL(fd,46) = (unsigned long)auth_dat[i].connect_until_time;
+ WFIFOSET(fd,50);
}
- if (i == auth_num)
- login_log("Char-server '%s': e-mail of the account %d NOT found (ip: %s).\n",
- server[id].name, RFIFOL(fd,2), ip);
RFIFOSKIP(fd,6);
break;
@@ -1508,55 +1387,43 @@ int parse_fromchar(int fd)
break;
case 0x2720: // Request to become a GM
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+ if( RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2) )
return 0;
{
unsigned char buf[10];
FILE *fp;
int acc = RFIFOL(fd,4);
- //printf("parse_fromchar: Request to become a GM acount from %d account.\n", acc);
WBUFW(buf,0) = 0x2721;
WBUFL(buf,2) = acc;
WBUFL(buf,6) = 0;
- if (strcmp((char*)RFIFOP(fd,8), gm_pass) == 0) {
- // only non-GM can become GM
- if (isGM(acc) == 0) {
- // if we autorise creation
- if (level_new_gm > 0) {
- // if we can open the file to add the new GM
- if ((fp = fopen(GM_account_filename, "a")) != NULL) {
- char tmpstr[24];
- time_t raw_time;
- time(&raw_time);
- strftime(tmpstr, 23, login_config.date_format, localtime(&raw_time));
- fprintf(fp, "\n// %s: @GM command on account %d\n%d %d\n", tmpstr, acc, acc, level_new_gm);
- fclose(fp);
- WBUFL(buf,6) = level_new_gm;
- read_gm_account();
- send_GM_accounts(-1);
- ShowNotice("GM Change of the account %d: level 0 -> %d.\n", acc, level_new_gm);
- login_log("Char-server '%s': GM Change of the account %d: level 0 -> %d (ip: %s).\n",
- server[id].name, acc, level_new_gm, ip);
- } else {
- ShowError("Error of GM change (suggested account: %d, correct password, unable to add a GM account in GM accounts file)\n", acc);
- login_log("Char-server '%s': Error of GM change (suggested account: %d, correct password, unable to add a GM account in GM accounts file, ip: %s).\n",
- server[id].name, acc, ip);
- }
- } else {
- ShowError("Error of GM change (suggested account: %d, correct password, but GM creation is disable (level_new_gm = 0))\n", acc);
- login_log("Char-server '%s': Error of GM change (suggested account: %d, correct password, but GM creation is disable (level_new_gm = 0), ip: %s).\n",
- server[id].name, acc, ip);
- }
- } else {
- ShowError("Error of GM change (suggested account: %d (already GM), correct password).\n", acc);
- login_log("Char-server '%s': Error of GM change (suggested account: %d (already GM), correct password, ip: %s).\n",
- server[id].name, acc, ip);
- }
- } else {
- ShowError("Error of GM change (suggested account: %d, invalid password).\n", acc);
- login_log("Char-server '%s': Error of GM change (suggested account: %d, invalid password, ip: %s).\n",
- server[id].name, acc, ip);
+
+ if( strcmp((char*)RFIFOP(fd,8), gm_pass) != 0 ) // password check
+ ShowError("Char-server '%s': Error of GM change (suggested account: %d, invalid password, ip: %s).\n", server[id].name, acc, ip);
+ else
+ if( isGM(acc) > 0 ) // only non-GM can become GM
+ ShowError("Char-server '%s': Error of GM change (suggested account: %d (already GM), correct password, ip: %s).\n", server[id].name, acc, ip);
+ else
+ if( level_new_gm == 0 ) // if we autorise creation
+ ShowError("Char-server '%s': Error of GM change (suggested account: %d, correct password, but GM creation is disable (level_new_gm = 0), ip: %s).\n", server[id].name, acc, ip);
+ else
+ if( (fp = fopen(GM_account_filename, "a")) == NULL ) // if we can open the file to add the new GM
+ ShowError("Char-server '%s': Error of GM change (suggested account: %d, correct password, unable to add a GM account in GM accounts file, ip: %s).\n", server[id].name, acc, ip);
+ else
+ {
+ char tmpstr[24];
+ time_t raw_time;
+ time(&raw_time);
+ strftime(tmpstr, 23, login_config.date_format, localtime(&raw_time));
+ fprintf(fp, "\n// %s: @GM command on account %d\n%d %d\n", tmpstr, acc, acc, level_new_gm);
+ fclose(fp);
+ WBUFL(buf,6) = level_new_gm;
+ read_gm_account();
+ send_GM_accounts(-1);
+
+ ShowNotice("Char-server '%s': GM Change of the account %d: level 0 -> %d (ip: %s).\n", server[id].name, acc, level_new_gm, ip);
+
}
+ // announce gm level update
charif_sendallwos(-1, buf, 10);
RFIFOSKIP(fd, RFIFOW(fd,2));
@@ -1573,72 +1440,59 @@ int parse_fromchar(int fd)
memcpy(actual_email, RFIFOP(fd,6), 40); actual_email[39] = '\0'; remove_control_chars(actual_email);
memcpy(new_email, RFIFOP(fd,46), 40); new_email[39] = '\0'; remove_control_chars(new_email);
if (e_mail_check(actual_email) == 0)
- login_log("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n",
- server[id].name, acc, ip);
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", server[id].name, acc, ip);
else if (e_mail_check(new_email) == 0)
- login_log("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n",
- server[id].name, acc, ip);
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n", server[id].name, acc, ip);
else if (strcmpi(new_email, "a@a.com") == 0)
- login_log("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n",
- server[id].name, acc, ip);
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", server[id].name, acc, ip);
else {
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == acc) {
- if (strcmpi(auth_dat[i].email, actual_email) == 0) {
- memcpy(auth_dat[i].email, new_email, 40);
- login_log("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n",
- server[id].name, acc, auth_dat[i].userid, new_email, ip);
- // Save
- mmo_auth_sync();
- } else
- login_log("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n",
- server[id].name, acc, auth_dat[i].userid, auth_dat[i].email, actual_email, ip);
- break;
- }
+ ARR_FIND( 0, auth_num, i, auth_dat[i].account_id == acc );
+ if( i == auth_num )
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", server[id].name, acc, ip);
+ else
+ if( strcmpi(auth_dat[i].email, actual_email) != 0 )
+ ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", server[id].name, acc, auth_dat[i].userid, auth_dat[i].email, actual_email, ip);
+ else {
+ memcpy(auth_dat[i].email, new_email, 40);
+ ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", server[id].name, acc, auth_dat[i].userid, new_email, ip);
+ // Save
+ mmo_auth_sync();
}
- if (i == auth_num)
- login_log("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n",
- server[id].name, acc, ip);
}
RFIFOSKIP(fd, 86);
}
break;
- case 0x2724: // Receiving of map-server via char-server a status change request
+ case 0x2724: // Receiving an account state update request from a map-server (relayed via char-server)
if (RFIFOREST(fd) < 10)
return 0;
{
- int acc;
- uint32 statut;
- acc = RFIFOL(fd,2);
- statut = RFIFOL(fd,6);
- for(i = 0; i < auth_num && auth_dat[i].account_id != acc; i++);
+ int account_id = RFIFOL(fd,2);
+ uint32 state = RFIFOL(fd,6);
- if (i == auth_num) {
- login_log("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n",
- server[id].name, acc, statut, ip);
- } else {
- if (auth_dat[i].state != statut) {
- login_log("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n",
- server[id].name, acc, statut, ip);
- if (statut != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
- WBUFL(buf,7) = statut; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- for(j = 0; j < AUTH_FIFO_SIZE; j++)
- if (auth_fifo[j].account_id == acc)
- auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
- }
- auth_dat[i].state = statut;
- // Save
- mmo_auth_sync();
- } else
- login_log("Char-server '%s': Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n",
- server[id].name, acc, statut, ip);
+ ARR_FIND( 0, auth_num, i, auth_dat[i].account_id == account_id );
+ if( i == auth_num )
+ ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+ else
+ if( auth_dat[i].state == state )
+ ShowNotice("Char-server '%s': Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+ else {
+ ShowNotice("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+ if (state != 0) {
+ unsigned char buf[16];
+ WBUFW(buf,0) = 0x2731;
+ WBUFL(buf,2) = account_id;
+ WBUFB(buf,6) = 0; // 0: change of state, 1: ban
+ WBUFL(buf,7) = state; // status or final date of a banishment
+ charif_sendallwos(-1, buf, 11);
+ ARR_FIND( 0, AUTH_FIFO_SIZE, j, auth_fifo[j].account_id == account_id );
+ if( j < AUTH_FIFO_SIZE )
+ auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentication)
+ }
+ auth_dat[i].state = state;
+ // Save
+ mmo_auth_sync();
}
RFIFOSKIP(fd,10);
@@ -1650,70 +1504,63 @@ int parse_fromchar(int fd)
return 0;
{
int acc = RFIFOL(fd,2);
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == acc) {
- time_t timestamp;
- struct tm *tmtime;
- if (auth_dat[i].ban_until_time == 0 || auth_dat[i].ban_until_time < time(NULL))
- timestamp = time(NULL);
+ ARR_FIND( 0, auth_num, i, auth_dat[i].account_id == acc );
+ if( i == auth_num )
+ ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", server[id].name, acc, ip);
+ else
+ {
+ time_t timestamp;
+ struct tm *tmtime;
+ if (auth_dat[i].ban_until_time == 0 || auth_dat[i].ban_until_time < time(NULL))
+ timestamp = time(NULL);
+ else
+ timestamp = auth_dat[i].ban_until_time;
+ tmtime = localtime(&timestamp);
+ tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,6);
+ tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,8);
+ tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,10);
+ tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,12);
+ tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,14);
+ tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,16);
+ timestamp = mktime(tmtime);
+ if (timestamp == -1)
+ ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", server[id].name, acc, ip);
+ else
+ {
+ if (timestamp <= time(NULL))
+ timestamp = 0;
else
- timestamp = auth_dat[i].ban_until_time;
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,6);
- tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,8);
- tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,10);
- tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,12);
- tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,14);
- tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,16);
- timestamp = mktime(tmtime);
- if (timestamp != -1) {
- if (timestamp <= time(NULL))
- timestamp = 0;
- if (auth_dat[i].ban_until_time != timestamp) {
- if (timestamp != 0) {
- unsigned char buf[16];
- char tmpstr[2048];
- strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
- login_log("Char-server '%s': Ban request (account: %d, new final date of banishment: %d (%s), ip: %s).\n",
- server[id].name, acc, timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = auth_dat[i].account_id;
- WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
- WBUFL(buf,7) = (unsigned int)timestamp; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- for(j = 0; j < AUTH_FIFO_SIZE; j++)
- if (auth_fifo[j].account_id == acc) {
- auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
- break;
- }
- } else {
- login_log("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n",
- server[id].name, acc, ip);
- }
- auth_dat[i].ban_until_time = timestamp;
- // Save
- mmo_auth_sync();
- } else {
- login_log("Char-server '%s': Error of ban request (account: %d, no change for ban date, ip: %s).\n",
- server[id].name, acc, ip);
+ {
+ if (timestamp == 0)
+ ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", server[id].name, acc, ip);
+ else
+ {
+ unsigned char buf[16];
+ char tmpstr[2048];
+ strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
+ ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %d (%s), ip: %s).\n", server[id].name, acc, timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
+ WBUFW(buf,0) = 0x2731;
+ WBUFL(buf,2) = auth_dat[i].account_id;
+ WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
+ WBUFL(buf,7) = (unsigned int)timestamp; // status or final date of a banishment
+ charif_sendallwos(-1, buf, 11);
+ ARR_FIND( 0, AUTH_FIFO_SIZE, j, auth_fifo[j].account_id == acc );
+ if( j < AUTH_FIFO_SIZE )
+ auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentication)
}
- } else {
- login_log("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n",
- server[id].name, acc, ip);
+ auth_dat[i].ban_until_time = timestamp;
+ // Save
+ mmo_auth_sync();
}
- break;
}
}
- if (i == auth_num)
- login_log("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n",
- server[id].name, acc, ip);
RFIFOSKIP(fd,18);
return 0;
}
case 0x2727: // Change of sex (sex is reversed)
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
{
uint8 sex;
@@ -1721,19 +1568,17 @@ int parse_fromchar(int fd)
for(i = 0; i < auth_num; i++) {
if (auth_dat[i].account_id == acc) {
if (auth_dat[i].sex == 2)
- login_log("Char-server '%s': Error of sex change - Server account (suggested account: %d, actual sex %d (Server), ip: %s).\n",
- server[id].name, acc, auth_dat[i].sex, ip);
+ ShowNotice("Char-server '%s': Error of sex change - Server account (suggested account: %d, actual sex %d (Server), ip: %s).\n", server[id].name, acc, auth_dat[i].sex, ip);
else {
unsigned char buf[16];
if (auth_dat[i].sex == 0)
sex = 1;
else
sex = 0;
- login_log("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n",
- server[id].name, acc, (sex == 2) ? 'S' : (sex == 1 ? 'M' : 'F'), ip);
+ ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", server[id].name, acc, (sex == 2) ? 'S' : (sex == 1 ? 'M' : 'F'), ip);
for(j = 0; j < AUTH_FIFO_SIZE; j++)
if (auth_fifo[j].account_id == acc)
- auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
+ auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentication)
auth_dat[i].sex = sex;
WBUFW(buf,0) = 0x2723;
WBUFL(buf,2) = acc;
@@ -1746,8 +1591,7 @@ int parse_fromchar(int fd)
}
}
if (i == auth_num)
- login_log("Char-server '%s': Error of sex change (account: %d not found, sex would be reversed, ip: %s).\n",
- server[id].name, acc, ip);
+ ShowNotice("Char-server '%s': Error of sex change (account: %d not found, sex would be reversed, ip: %s).\n", server[id].name, acc, ip);
RFIFOSKIP(fd,6);
return 0;
@@ -1762,11 +1606,10 @@ int parse_fromchar(int fd)
for(i = 0; i < auth_num; i++) {
if (auth_dat[i].account_id == acc) {
//unsigned char buf[rfifow(fd,2)+1];
- unsigned char *buf;
+ uint8* buf;
int len;
- buf = (unsigned char*)aCalloc(RFIFOW(fd,2)+1, sizeof(unsigned char));
- login_log("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n",
- server[id].name, acc, ip);
+ CREATE(buf, uint8, RFIFOW(fd,2)+1);
+ ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, acc, ip);
for(j=0,p=13;j<ACCOUNT_REG2_NUM && p<RFIFOW(fd,2);j++){
sscanf((char*)RFIFOP(fd,p), "%31c%n",auth_dat[i].account_reg2[j].str,&len);
auth_dat[i].account_reg2[j].str[len]='\0';
@@ -1790,9 +1633,7 @@ int parse_fromchar(int fd)
}
}
if (i == auth_num) {
-// printf("parse_fromchar: receiving (from the char-server) of account_reg2 (unknwon account id: %d).\n", acc);
- login_log("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n",
- server[id].name, acc, ip);
+ ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, acc, ip);
}
}
@@ -1800,7 +1641,7 @@ int parse_fromchar(int fd)
break;
case 0x272a: // Receiving of map-server via char-server an unban request
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
{
int acc = RFIFOL(fd,2);
@@ -1808,32 +1649,30 @@ int parse_fromchar(int fd)
if (auth_dat[i].account_id == acc) {
if (auth_dat[i].ban_until_time != 0) {
auth_dat[i].ban_until_time = 0;
- login_log("Char-server '%s': UnBan request (account: %d, ip: %s).\n",
- server[id].name, acc, ip);
+ ShowNotice("Char-server '%s': UnBan request (account: %d, ip: %s).\n", server[id].name, acc, ip);
} else {
- login_log("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n",
+ ShowNotice("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n",
server[id].name, acc, ip);
}
break;
}
}
if (i == auth_num)
- login_log("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n",
- server[id].name, acc, ip);
+ ShowNotice("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n", server[id].name, acc, ip);
RFIFOSKIP(fd,6);
return 0;
}
case 0x272b: // Set account_id to online [Wizputer]
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
add_online_user(id, RFIFOL(fd,2));
RFIFOSKIP(fd,6);
break;
-
+
case 0x272c: // Set account_id to offline [Wizputer]
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
remove_online_user(RFIFOL(fd,2));
RFIFOSKIP(fd,6);
@@ -1846,7 +1685,7 @@ int parse_fromchar(int fd)
{
struct online_login_data *p;
int aid;
- uint32 i, users;
+ uint32 i, users;
online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char-server offline first
users = RFIFOW(fd,4);
for (i = 0; i < users; i++) {
@@ -1895,7 +1734,7 @@ int parse_fromchar(int fd)
break;
case 0x2736: // WAN IP update from char-server
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
server[id].ip = ntohl(RFIFOL(fd,2));
ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
@@ -1960,974 +1799,6 @@ int parse_fromchar(int fd)
return 0;
}
-//---------------------------------------
-// Packet parsing for administation login
-//---------------------------------------
-int parse_admin(int fd)
-{
- unsigned int i, j;
- char* account_name;
-
- uint32 ipl = session[fd]->client_addr;
- char ip[16];
- ip2str(ipl, ip);
-
- if( session[fd]->eof )
- {
- do_close(fd);
- ShowInfo("Remote administration has disconnected (session #%d).\n", fd);
- return 0;
- }
-
- while( RFIFOREST(fd) >= 2 )
- {
- uint16 command = RFIFOW(fd,0);
-
- switch( command )
- {
-
- case 0x7530: // Request of the server version
- login_log("'ladmin': Sending of the server version (ip: %s)\n", ip);
- WFIFOHEAD(fd,10);
- WFIFOW(fd,0) = 0x7531;
- WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
- WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
- WFIFOB(fd,4) = ATHENA_REVISION;
- WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
- WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
- WFIFOB(fd,7) = ATHENA_SERVER_LOGIN;
- WFIFOW(fd,8) = ATHENA_MOD_VERSION;
- WFIFOSET(fd,10);
- RFIFOSKIP(fd,2);
- break;
-
- case 0x7532: // Request of end of connection
- login_log("'ladmin': End of connection (ip: %s)\n", ip);
- RFIFOSKIP(fd,2);
- set_eof(fd);
- break;
-
- case 0x7920: // Request of an accounts list
- if (RFIFOREST(fd) < 10)
- return 0;
- {
- int st, ed;
- uint16 len;
- CREATE_BUFFER(id, int, auth_num);
- st = RFIFOL(fd,2);
- ed = RFIFOL(fd,6);
- RFIFOSKIP(fd,10);
- WFIFOW(fd,0) = 0x7921;
- if (st < 0)
- st = 0;
- if (ed > END_ACCOUNT_NUM || ed < st || ed <= 0)
- ed = END_ACCOUNT_NUM;
- login_log("'ladmin': Sending an accounts list (ask: from %d to %d, ip: %s)\n", st, ed, ip);
- // Sort before send
- for(i = 0; i < auth_num; i++) {
- unsigned int k;
- id[i] = i;
- for(j = 0; j < i; j++) {
- if (auth_dat[id[i]].account_id < auth_dat[id[j]].account_id) {
- for(k = i; k > j; k--) {
- id[k] = id[k-1];
- }
- id[j] = i; // id[i]
- break;
- }
- }
- }
- // Sending accounts information
- len = 4;
- for(i = 0; i < auth_num && len < 30000; i++) {
- int account_id = auth_dat[id[i]].account_id; // use sorted index
- if (account_id >= st && account_id <= ed) {
- j = id[i];
- WFIFOL(fd,len) = account_id;
- WFIFOB(fd,len+4) = (unsigned char)isGM(account_id);
- memcpy(WFIFOP(fd,len+5), auth_dat[j].userid, 24);
- WFIFOB(fd,len+29) = auth_dat[j].sex;
- WFIFOL(fd,len+30) = auth_dat[j].logincount;
- if (auth_dat[j].state == 0 && auth_dat[j].ban_until_time != 0) // if no state and banished
- WFIFOL(fd,len+34) = 7; // 6 = Your are Prohibited to log in until %s
- else
- WFIFOL(fd,len+34) = auth_dat[j].state;
- len += 38;
- }
- }
- WFIFOW(fd,2) = len;
- WFIFOSET(fd,len);
- //if (id) free(id);
- DELETE_BUFFER(id);
- }
- break;
-
- case 0x7930: // Request for an account creation
- if (RFIFOREST(fd) < 91)
- return 0;
- {
- struct mmo_account ma;
- memcpy(ma.userid,RFIFOP(fd, 2),NAME_LENGTH);
- ma.userid[23] = '\0';
- memcpy(ma.passwd, RFIFOP(fd, 26), NAME_LENGTH);
- ma.passwd[23] = '\0';
- memcpy(ma.lastlogin, "-", 2);
- ma.sex = RFIFOB(fd,50);
- WFIFOW(fd,0) = 0x7931;
- WFIFOL(fd,2) = 0xffffffff;
- memcpy(WFIFOP(fd,6), RFIFOP(fd,2), 24);
- if (strlen(ma.userid) < 4 || strlen(ma.passwd) < 4) {
- login_log("'ladmin': Attempt to create an invalid account (account or pass is too short, ip: %s)\n",
- ip);
- } else if (ma.sex != 'F' && ma.sex != 'M') {
- login_log("'ladmin': Attempt to create an invalid account (account: %s, received pass: %s, invalid sex, ip: %s)\n",
- ma.userid, ma.passwd, ip);
- } else if (account_id_count > END_ACCOUNT_NUM) {
- login_log("'ladmin': Attempt to create an account, but there is no more available id number (account: %s, pass: %s, sex: %c, ip: %s)\n",
- ma.userid, ma.passwd, ma.sex, ip);
- } else {
- remove_control_chars(ma.userid);
- remove_control_chars(ma.passwd);
- for(i = 0; i < auth_num; i++) {
- if (strncmp(auth_dat[i].userid, ma.userid, 24) == 0) {
- login_log("'ladmin': Attempt to create an already existing account (account: %s, pass: %s, received pass: %s, ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].pass, ma.passwd, ip);
- break;
- }
- }
- if (i == auth_num) {
- int new_id;
- char email[40];
- memcpy(email, RFIFOP(fd,51), 40);
- email[39] = '\0';
- remove_control_chars(email);
- new_id = mmo_auth_new(&ma, ma.sex, email);
- login_log("'ladmin': Account creation (account: %s (id: %d), pass: %s, sex: %c, email: %s, ip: %s)\n",
- ma.userid, new_id, ma.passwd, ma.sex, auth_dat[i].email, ip);
- WFIFOL(fd,2) = new_id;
- mmo_auth_sync();
- }
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,91);
- }
- break;
-
- case 0x7932: // Request for an account deletion
- if (RFIFOREST(fd) < 26)
- return 0;
- WFIFOW(fd,0) = 0x7933;
- WFIFOL(fd,2) = 0xFFFFFFFF;
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- // Char-server is notified of deletion (for characters deletion).
- unsigned char buf[65535];
- WBUFW(buf,0) = 0x2730;
- WBUFL(buf,2) = auth_dat[i].account_id;
- charif_sendallwos(-1, buf, 6);
- // send answer
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- // save deleted account in log file
- login_log("'ladmin': Account deletion (account: %s, id: %d, ip: %s) - saved in next line:\n", auth_dat[i].userid, auth_dat[i].account_id, ip);
- mmo_auth_tostr((char*)buf, &auth_dat[i]);
- login_log("%s\n", buf);
- // delete account
- memset(auth_dat[i].userid, '\0', sizeof(auth_dat[i].userid));
- auth_dat[i].account_id = -1;
- mmo_auth_sync();
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to delete an unknown account (account: %s, ip: %s)\n", account_name, ip);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,26);
- break;
-
- case 0x7934: // Request to change a password
- if (RFIFOREST(fd) < 50)
- return 0;
- WFIFOW(fd,0) = 0x7935;
- WFIFOL(fd,2) = 0xFFFFFFFF; /// WTF??? an unsigned being set to a -1
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- memcpy(auth_dat[i].pass, RFIFOP(fd,26), 24);
- auth_dat[i].pass[23] = '\0';
- remove_control_chars(auth_dat[i].pass);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- login_log("'ladmin': Modification of a password (account: %s, new password: %s, ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].pass, ip);
- mmo_auth_sync();
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to modify the password of an unknown account (account: %s, ip: %s)\n",
- account_name, ip);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,50);
- break;
-
- case 0x7936: // Request to modify a state
- if (RFIFOREST(fd) < 50)
- return 0;
- {
- char error_message[20];
- uint32 statut;
- WFIFOW(fd,0) = 0x7937;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- statut = RFIFOL(fd,26);
- memcpy(error_message, RFIFOP(fd,30), 20);
- error_message[19] = '\0';
- remove_control_chars(error_message);
- if (statut != 7 || error_message[0] == '\0') { // 7: // 6 = Your are Prohibited to log in until %s
- strcpy(error_message, "-");
- }
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- if (auth_dat[i].state == statut && strcmp(auth_dat[i].error_message, error_message) == 0)
- login_log("'ladmin': Modification of a state, but the state of the account is already the good state (account: %s, received state: %d, ip: %s)\n",
- account_name, statut, ip);
- else {
- if (statut == 7)
- login_log("'ladmin': Modification of a state (account: %s, new state: %d - prohibited to login until '%s', ip: %s)\n",
- auth_dat[i].userid, statut, error_message, ip);
- else
- login_log("'ladmin': Modification of a state (account: %s, new state: %d, ip: %s)\n",
- auth_dat[i].userid, statut, ip);
- if (auth_dat[i].state == 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = auth_dat[i].account_id;
- WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
- WBUFL(buf,7) = statut; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- for(j = 0; j < AUTH_FIFO_SIZE; j++)
- if (auth_fifo[j].account_id == auth_dat[i].account_id)
- auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
- }
- auth_dat[i].state = statut;
- memcpy(auth_dat[i].error_message, error_message, 20);
- mmo_auth_sync();
- }
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to modify the state of an unknown account (account: %s, received state: %d, ip: %s)\n",
- account_name, statut, ip);
- }
- WFIFOL(fd,30) = statut;
- }
- WFIFOSET(fd,34);
- RFIFOSKIP(fd,50);
- break;
-
- case 0x7938: // Request for servers list and # of online players
- {
- uint8 server_num = 0;
- login_log("'ladmin': Sending of servers list (ip: %s)\n", ip);
- for(i = 0; i < MAX_SERVERS; i++) {
- if (server_fd[i] >= 0) {
- WFIFOL(fd,4+server_num*32) = htonl(server[i].ip);
- WFIFOW(fd,4+server_num*32+4) = htons(server[i].port);
- memcpy(WFIFOP(fd,4+server_num*32+6), server[i].name, 20);
- WFIFOW(fd,4+server_num*32+26) = server[i].users;
- WFIFOW(fd,4+server_num*32+28) = server[i].maintenance;
- WFIFOW(fd,4+server_num*32+30) = server[i].new_;
- server_num++;
- }
- }
- WFIFOW(fd,0) = 0x7939;
- WFIFOW(fd,2) = 4 + 32 * server_num;
- WFIFOSET(fd,4+32*server_num);
- RFIFOSKIP(fd,2);
- break;
- }
-
- case 0x793a: // Request to password check
- if (RFIFOREST(fd) < 50)
- return 0;
- WFIFOW(fd,0) = 0x793b;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- char pass[25];
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- memcpy(pass, RFIFOP(fd,26), 24);
- pass[24] = '\0';
- remove_control_chars(pass);
- if (strcmp(auth_dat[i].pass, pass) == 0) {
- WFIFOL(fd,2) = auth_dat[i].account_id;
- login_log("'ladmin': Check of password OK (account: %s, password: %s, ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].pass, ip);
- } else {
- login_log("'ladmin': Failure of password check (account: %s, proposed pass: %s, ip: %s)\n",
- auth_dat[i].userid, pass, ip);
- }
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to check the password of an unknown account (account: %s, ip: %s)\n",
- account_name, ip);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,50);
- break;
-
- case 0x793c: // Request to modify sex
- if (RFIFOREST(fd) < 27)
- return 0;
- WFIFOW(fd,0) = 0x793d;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- memcpy(WFIFOP(fd,6), account_name, 24);
- {
- char sex;
- sex = RFIFOB(fd,26);
- if (sex != 'F' && sex != 'M') {
- if (sex > 31)
- login_log("'ladmin': Attempt to give an invalid sex (account: %s, received sex: %c, ip: %s)\n",
- account_name, sex, ip);
- else
- login_log("'ladmin': Attempt to give an invalid sex (account: %s, received sex: 'control char', ip: %s)\n",
- account_name, ip);
- } else {
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- if (auth_dat[i].sex != ((sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm'))) {
- unsigned char buf[16];
- WFIFOL(fd,2) = auth_dat[i].account_id;
- for(j = 0; j < AUTH_FIFO_SIZE; j++)
- if (auth_fifo[j].account_id == auth_dat[i].account_id)
- auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
- auth_dat[i].sex = (sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm');
- login_log("'ladmin': Modification of a sex (account: %s, new sex: %c, ip: %s)\n",
- auth_dat[i].userid, sex, ip);
- mmo_auth_sync();
- // send to all char-server the change
- WBUFW(buf,0) = 0x2723;
- WBUFL(buf,2) = auth_dat[i].account_id;
- WBUFB(buf,6) = auth_dat[i].sex;
- charif_sendallwos(-1, buf, 7);
- } else {
- login_log("'ladmin': Modification of a sex, but the sex is already the good sex (account: %s, sex: %c, ip: %s)\n",
- auth_dat[i].userid, sex, ip);
- }
- } else {
- login_log("'ladmin': Attempt to modify the sex of an unknown account (account: %s, received sex: %c, ip: %s)\n",
- account_name, sex, ip);
- }
- }
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,27);
- break;
-
- case 0x793e: // Request to modify GM level
- if (RFIFOREST(fd) < 27)
- return 0;
- WFIFOW(fd,0) = 0x793f;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- memcpy(WFIFOP(fd,6), account_name, 24);
- {
- char new_gm_level;
- new_gm_level = RFIFOB(fd,26);
- if (new_gm_level < 0 || new_gm_level > 99) {
- login_log("'ladmin': Attempt to give an invalid GM level (account: %s, received GM level: %d, ip: %s)\n",
- account_name, (int)new_gm_level, ip);
- } else {
- i = search_account_index(account_name);
- if (i != -1) {
- int acc = auth_dat[i].account_id;
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- if (isGM(acc) != new_gm_level) {
- // modification of the file
- FILE *fp, *fp2;
- int lock;
- char line[512];
- int GM_account, GM_level;
- int modify_flag;
- char tmpstr[24];
- time_t raw_time;
- if ((fp2 = lock_fopen(GM_account_filename, &lock)) != NULL) {
- if ((fp = fopen(GM_account_filename, "r")) != NULL) {
- time(&raw_time);
- strftime(tmpstr, 23, login_config.date_format, localtime(&raw_time));
- modify_flag = 0;
- // read/write GM file
- while(fgets(line, sizeof(line), fp))
- {
- while(line[0] != '\0' && (line[strlen(line)-1] == '\n' || line[strlen(line)-1] == '\r'))
- line[strlen(line)-1] = '\0'; // TODO: remove this
- if ((line[0] == '/' && line[1] == '/') || line[0] == '\0')
- fprintf(fp2, "%s\n", line);
- else {
- if (sscanf(line, "%d %d", &GM_account, &GM_level) != 2 && sscanf(line, "%d: %d", &GM_account, &GM_level) != 2)
- fprintf(fp2, "%s\n", line);
- else if (GM_account != acc)
- fprintf(fp2, "%s\n", line);
- else if (new_gm_level < 1) {
- fprintf(fp2, "// %s: 'ladmin' GM level removed on account %d '%s' (previous level: %d)\n//%d %d\n", tmpstr, acc, auth_dat[i].userid, GM_level, acc, new_gm_level);
- modify_flag = 1;
- } else {
- fprintf(fp2, "// %s: 'ladmin' GM level on account %d '%s' (previous level: %d)\n%d %d\n", tmpstr, acc, auth_dat[i].userid, GM_level, acc, new_gm_level);
- modify_flag = 1;
- }
- }
- }
- if (modify_flag == 0)
- fprintf(fp2, "// %s: 'ladmin' GM level on account %d '%s' (previous level: 0)\n%d %d\n", tmpstr, acc, auth_dat[i].userid, acc, new_gm_level);
- fclose(fp);
- } else {
- login_log("'ladmin': Attempt to modify of a GM level - impossible to read GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n",
- auth_dat[i].userid, acc, (int)new_gm_level, ip);
- }
- if (lock_fclose(fp2, GM_account_filename, &lock) == 0) {
- WFIFOL(fd,2) = acc;
- login_log("'ladmin': Modification of a GM level (account: %s (%d), new GM level: %d, ip: %s)\n",
- auth_dat[i].userid, acc, (int)new_gm_level, ip);
- // read and send new GM informations
- read_gm_account();
- send_GM_accounts(-1);
- } else {
- login_log("'ladmin': Attempt to modify of a GM level - impossible to write GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n",
- auth_dat[i].userid, acc, (int)new_gm_level, ip);
- }
- } else {
- login_log("'ladmin': Attempt to modify of a GM level - impossible to write GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n",
- auth_dat[i].userid, acc, (int)new_gm_level, ip);
- }
- } else {
- login_log("'ladmin': Attempt to modify of a GM level, but the GM level is already the good GM level (account: %s (%d), GM level: %d, ip: %s)\n",
- auth_dat[i].userid, acc, (int)new_gm_level, ip);
- }
- } else {
- login_log("'ladmin': Attempt to modify the GM level of an unknown account (account: %s, received GM level: %d, ip: %s)\n",
- account_name, (int)new_gm_level, ip);
- }
- }
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,27);
- break;
-
- case 0x7940: // Request to modify e-mail
- if (RFIFOREST(fd) < 66)
- return 0;
- WFIFOW(fd,0) = 0x7941;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- memcpy(WFIFOP(fd,6), account_name, 24);
- {
- char email[40];
- memcpy(email, RFIFOP(fd,26), 40);
- if (e_mail_check(email) == 0) {
- login_log("'ladmin': Attempt to give an invalid e-mail (account: %s, ip: %s)\n",
- account_name, ip);
- } else {
- remove_control_chars(email);
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- memcpy(auth_dat[i].email, email, 40);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- login_log("'ladmin': Modification of an email (account: %s, new e-mail: %s, ip: %s)\n",
- auth_dat[i].userid, email, ip);
- mmo_auth_sync();
- } else {
- login_log("'ladmin': Attempt to modify the e-mail of an unknown account (account: %s, received e-mail: %s, ip: %s)\n",
- account_name, email, ip);
- }
- }
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,66);
- break;
-
- case 0x7942: // Request to modify memo field
- if ((int)RFIFOREST(fd) < 28 || (int)RFIFOREST(fd) < (28 + RFIFOW(fd,26)))
- return 0;
- WFIFOW(fd,0) = 0x7943;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- int size_of_memo = sizeof(auth_dat[i].memo);
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- memset(auth_dat[i].memo, '\0', size_of_memo);
- if (RFIFOW(fd,26) == 0) {
- strncpy(auth_dat[i].memo, "-", size_of_memo);
- } else if (RFIFOW(fd,26) > size_of_memo - 1) {
- memcpy(auth_dat[i].memo, RFIFOP(fd,28), size_of_memo - 1);
- } else {
- memcpy(auth_dat[i].memo, RFIFOP(fd,28), RFIFOW(fd,26));
- }
- auth_dat[i].memo[size_of_memo - 1] = '\0';
- remove_control_chars(auth_dat[i].memo);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- login_log("'ladmin': Modification of a memo field (account: %s, new memo: %s, ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].memo, ip);
- mmo_auth_sync();
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to modify the memo field of an unknown account (account: %s, ip: %s)\n",
- account_name, ip);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,28 + RFIFOW(fd,26));
- break;
-
- case 0x7944: // Request to found an account id
- if (RFIFOREST(fd) < 26)
- return 0;
- WFIFOW(fd,0) = 0x7945;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- login_log("'ladmin': Request (by the name) of an account id (account: %s, id: %d, ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].account_id, ip);
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': ID request (by the name) of an unknown account (account: %s, ip: %s)\n",
- account_name, ip);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,26);
- break;
-
- case 0x7946: // Request to found an account name
- if (RFIFOREST(fd) < 6)
- return 0;
- WFIFOW(fd,0) = 0x7947;
- WFIFOL(fd,2) = RFIFOL(fd,2);
- memset(WFIFOP(fd,6), '\0', 24);
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == (int)RFIFOL(fd,2)) {
- strncpy((char*)WFIFOP(fd,6), auth_dat[i].userid, 24);
- login_log("'ladmin': Request (by id) of an account name (account: %s, id: %d, ip: %s)\n",
- auth_dat[i].userid, RFIFOL(fd,2), ip);
- break;
- }
- }
- if (i == auth_num) {
- login_log("'ladmin': Name request (by id) of an unknown account (id: %d, ip: %s)\n",
- RFIFOL(fd,2), ip);
- strncpy((char*)WFIFOP(fd,6), "", 24);
- }
- WFIFOSET(fd,30);
- RFIFOSKIP(fd,6);
- break;
-
- case 0x7948: // Request to change the validity limit (timestamp) (absolute value)
- if (RFIFOREST(fd) < 30)
- return 0;
- {
- time_t timestamp;
- char tmpstr[2048];
- WFIFOW(fd,0) = 0x7949;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- timestamp = (time_t)RFIFOL(fd,26);
- strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- login_log("'ladmin': Change of a validity limit (account: %s, new validity: %d (%s), ip: %s)\n",
- auth_dat[i].userid, timestamp, (timestamp == 0 ? "unlimited" : tmpstr), ip);
- auth_dat[i].connect_until_time = timestamp;
- WFIFOL(fd,2) = auth_dat[i].account_id;
- mmo_auth_sync();
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to change the validity limit of an unknown account (account: %s, received validity: %d (%s), ip: %s)\n",
- account_name, timestamp, (timestamp == 0 ? "unlimited" : tmpstr), ip);
- }
- WFIFOL(fd,30) = (unsigned int)timestamp;
- }
- WFIFOSET(fd,34);
- RFIFOSKIP(fd,30);
- break;
-
- case 0x794a: // Request to change the final date of a banishment (timestamp) (absolute value)
- if (RFIFOREST(fd) < 30)
- return 0;
- {
- time_t timestamp;
- char tmpstr[2048];
- WFIFOW(fd,0) = 0x794b;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- timestamp = (time_t)RFIFOL(fd,26);
- if (timestamp <= time(NULL))
- timestamp = 0;
- strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
- i = search_account_index(account_name);
- if (i != -1) {
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- WFIFOL(fd,2) = auth_dat[i].account_id;
- login_log("'ladmin': Change of the final date of a banishment (account: %s, new final date of banishment: %d (%s), ip: %s)\n",
- auth_dat[i].userid, timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
- if (auth_dat[i].ban_until_time != timestamp) {
- if (timestamp != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = auth_dat[i].account_id;
- WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
- WBUFL(buf,7) = (unsigned int)timestamp; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- for(j = 0; j < AUTH_FIFO_SIZE; j++)
- if (auth_fifo[j].account_id == auth_dat[i].account_id)
- auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
- }
- auth_dat[i].ban_until_time = timestamp;
- mmo_auth_sync();
- }
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to change the final date of a banishment of an unknown account (account: %s, received final date of banishment: %d (%s), ip: %s)\n",
- account_name, timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
- }
- WFIFOL(fd,30) = (unsigned int)timestamp;
- }
- WFIFOSET(fd,34);
- RFIFOSKIP(fd,30);
- break;
-
- case 0x794c: // Request to change the final date of a banishment (timestamp) (relative change)
- if (RFIFOREST(fd) < 38)
- return 0;
- {
- time_t timestamp;
- struct tm *tmtime;
- char tmpstr[2048];
- WFIFOW(fd,0) = 0x794d;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- WFIFOL(fd,2) = auth_dat[i].account_id;
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- if (auth_dat[i].ban_until_time == 0 || auth_dat[i].ban_until_time < time(NULL))
- timestamp = time(NULL);
- else
- timestamp = auth_dat[i].ban_until_time;
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,26);
- tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,28);
- tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,30);
- tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,32);
- tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,34);
- tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,36);
- timestamp = mktime(tmtime);
- if (timestamp != -1) {
- if (timestamp <= time(NULL))
- timestamp = 0;
- strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
- login_log("'ladmin': Adjustment of a final date of a banishment (account: %s, (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %d (%s), ip: %s)\n",
- auth_dat[i].userid, (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
- if (auth_dat[i].ban_until_time != timestamp) {
- if (timestamp != 0) {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2731;
- WBUFL(buf,2) = auth_dat[i].account_id;
- WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
- WBUFL(buf,7) = (unsigned int)timestamp; // status or final date of a banishment
- charif_sendallwos(-1, buf, 11);
- for(j = 0; j < AUTH_FIFO_SIZE; j++)
- if (auth_fifo[j].account_id == auth_dat[i].account_id) {
- auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
- break;
- }
- }
- auth_dat[i].ban_until_time = timestamp;
- mmo_auth_sync();
- }
- } else {
- strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].ban_until_time));
- login_log("'ladmin': Impossible to adjust the final date of a banishment (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].ban_until_time, (auth_dat[i].ban_until_time == 0 ? "no banishment" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), ip);
- }
- WFIFOL(fd,30) = (unsigned long)auth_dat[i].ban_until_time;
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to adjust the final date of a banishment of an unknown account (account: %s, ip: %s)\n",
- account_name, ip);
- WFIFOL(fd,30) = 0;
- }
- }
- WFIFOSET(fd,34);
- RFIFOSKIP(fd,38);
- break;
-
- case 0x794e: // Request to send a broadcast message
- if (RFIFOREST(fd) < 8 || RFIFOREST(fd) < (8 + RFIFOL(fd,4)))
- return 0;
- WFIFOW(fd,0) = 0x794f;
- WFIFOW(fd,2) = 0xFFFF; // WTF???
- if (RFIFOL(fd,4) < 1) {
- login_log("'ladmin': Receiving a message for broadcast, but message is void (ip: %s)\n",
- ip);
- } else {
- // at least 1 char-server
- for(i = 0; i < MAX_SERVERS; i++)
- if (server_fd[i] >= 0)
- break;
- if (i == MAX_SERVERS) {
- login_log("'ladmin': Receiving a message for broadcast, but no char-server is online (ip: %s)\n",
- ip);
- } else {
- unsigned char buf[32000];
- char message[32000];
- WFIFOW(fd,2) = 0;
- memset(message, '\0', sizeof(message));
- memcpy(message, RFIFOP(fd,8), RFIFOL(fd,4));
- message[sizeof(message)-1] = '\0';
- remove_control_chars(message);
- if (RFIFOW(fd,2) == 0)
- login_log("'ladmin': Receiving a message for broadcast (message (in yellow): %s, ip: %s)\n",
- message, ip);
- else
- login_log("'ladmin': Receiving a message for broadcast (message (in blue): %s, ip: %s)\n",
- message, ip);
- // send same message to all char-servers (no answer)
- memcpy(WBUFP(buf,0), RFIFOP(fd,0), 8 + RFIFOL(fd,4));
- WBUFW(buf,0) = 0x2726;
- charif_sendallwos(-1, buf, 8 + RFIFOL(fd,4));
- }
- }
- WFIFOSET(fd,4);
- RFIFOSKIP(fd,8 + RFIFOL(fd,4));
- break;
-
- case 0x7950: // Request to change the validity limite (timestamp) (relative change)
- if (RFIFOREST(fd) < 38)
- return 0;
- {
- time_t timestamp;
- struct tm *tmtime;
- char tmpstr[2048];
- char tmpstr2[2048];
- WFIFOW(fd,0) = 0x7951;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- WFIFOL(fd,2) = auth_dat[i].account_id;
- memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
- timestamp = auth_dat[i].connect_until_time;
- if (add_to_unlimited_account == 0 && timestamp == 0) {
- login_log("'ladmin': Attempt to adjust the validity limit of an unlimited account (account: %s, ip: %s)\n",
- auth_dat[i].userid, ip);
- WFIFOL(fd,30) = 0;
- } else {
- if (timestamp == 0 || timestamp < time(NULL))
- timestamp = time(NULL);
- tmtime = localtime(&timestamp);
- tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,26);
- tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,28);
- tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,30);
- tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,32);
- tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,34);
- tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,36);
- timestamp = mktime(tmtime);
- if (timestamp != -1) {
- strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].connect_until_time));
- strftime(tmpstr2, 24, login_config.date_format, localtime(&timestamp));
- login_log("'ladmin': Adjustment of a validity limit (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %d (%s), ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].connect_until_time, (auth_dat[i].connect_until_time == 0 ? "unlimited" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), timestamp, (timestamp == 0 ? "unlimited" : tmpstr2), ip);
- auth_dat[i].connect_until_time = timestamp;
- mmo_auth_sync();
- WFIFOL(fd,30) = (unsigned long)auth_dat[i].connect_until_time;
- } else {
- strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].connect_until_time));
- login_log("'ladmin': Impossible to adjust a validity limit (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].connect_until_time, (auth_dat[i].connect_until_time == 0 ? "unlimited" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), ip);
- WFIFOL(fd,30) = 0;
- }
- }
- } else {
- memcpy(WFIFOP(fd,6), account_name, 24);
- login_log("'ladmin': Attempt to adjust the validity limit of an unknown account (account: %s, ip: %s)\n",
- account_name, ip);
- WFIFOL(fd,30) = 0;
- }
- }
- WFIFOSET(fd,34);
- RFIFOSKIP(fd,38);
- break;
-
- case 0x7952: // Request about informations of an account (by account name)
- if (RFIFOREST(fd) < 26)
- return 0;
- WFIFOW(fd,0) = 0x7953;
- WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
- account_name = (char*)RFIFOP(fd,2);
- account_name[23] = '\0';
- remove_control_chars(account_name);
- i = search_account_index(account_name);
- if (i != -1) {
- WFIFOL(fd,2) = auth_dat[i].account_id;
- WFIFOB(fd,6) = (unsigned char)isGM(auth_dat[i].account_id);
- memcpy(WFIFOP(fd,7), auth_dat[i].userid, 24);
- WFIFOB(fd,31) = auth_dat[i].sex;
- WFIFOL(fd,32) = auth_dat[i].logincount;
- WFIFOL(fd,36) = auth_dat[i].state;
- memcpy(WFIFOP(fd,40), auth_dat[i].error_message, 20);
- memcpy(WFIFOP(fd,60), auth_dat[i].lastlogin, 24);
- memcpy(WFIFOP(fd,84), auth_dat[i].last_ip, 16);
- memcpy(WFIFOP(fd,100), auth_dat[i].email, 40);
- WFIFOL(fd,140) = (unsigned long)auth_dat[i].connect_until_time;
- WFIFOL(fd,144) = (unsigned long)auth_dat[i].ban_until_time;
- WFIFOW(fd,148) = (uint16)strlen(auth_dat[i].memo);
- if (auth_dat[i].memo[0]) {
- memcpy(WFIFOP(fd,150), auth_dat[i].memo, strlen(auth_dat[i].memo));
- }
- login_log("'ladmin': Sending information of an account (request by the name; account: %s, id: %d, ip: %s)\n",
- auth_dat[i].userid, auth_dat[i].account_id, ip);
- WFIFOSET(fd,150+strlen(auth_dat[i].memo));
- } else {
- memcpy(WFIFOP(fd,7), account_name, 24);
- WFIFOW(fd,148) = 0;
- login_log("'ladmin': Attempt to obtain information (by the name) of an unknown account (account: %s, ip: %s)\n",
- account_name, ip);
- WFIFOSET(fd,150);
- }
- RFIFOSKIP(fd,26);
- break;
-
- case 0x7954: // Request about information of an account (by account id)
- if (RFIFOREST(fd) < 6)
- return 0;
- WFIFOW(fd,0) = 0x7953;
- WFIFOL(fd,2) = RFIFOL(fd,2);
- memset(WFIFOP(fd,7), '\0', 24);
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == (int)RFIFOL(fd,2)) {
- login_log("'ladmin': Sending information of an account (request by the id; account: %s, id: %d, ip: %s)\n",
- auth_dat[i].userid, RFIFOL(fd,2), ip);
- WFIFOB(fd,6) = (unsigned char)isGM(auth_dat[i].account_id);
- memcpy(WFIFOP(fd,7), auth_dat[i].userid, 24);
- WFIFOB(fd,31) = auth_dat[i].sex;
- WFIFOL(fd,32) = auth_dat[i].logincount;
- WFIFOL(fd,36) = auth_dat[i].state;
- memcpy(WFIFOP(fd,40), auth_dat[i].error_message, 20);
- memcpy(WFIFOP(fd,60), auth_dat[i].lastlogin, 24);
- memcpy(WFIFOP(fd,84), auth_dat[i].last_ip, 16);
- memcpy(WFIFOP(fd,100), auth_dat[i].email, 40);
- WFIFOL(fd,140) = (unsigned long)auth_dat[i].connect_until_time;
- WFIFOL(fd,144) = (unsigned long)auth_dat[i].ban_until_time;
- WFIFOW(fd,148) = (uint16)strlen(auth_dat[i].memo);
- if (auth_dat[i].memo[0]) {
- memcpy(WFIFOP(fd,150), auth_dat[i].memo, strlen(auth_dat[i].memo));
- }
- WFIFOSET(fd,150+strlen(auth_dat[i].memo));
- break;
- }
- }
- if (i == auth_num) {
- login_log("'ladmin': Attempt to obtain information (by the id) of an unknown account (id: %d, ip: %s)\n",
- RFIFOL(fd,2), ip);
- strncpy((char*)WFIFOP(fd,7), "", 24);
- WFIFOW(fd,148) = 0;
- WFIFOSET(fd,150);
- }
- RFIFOSKIP(fd,6);
- break;
-
- case 0x7955: // Request to reload GM file (no answer)
- login_log("'ladmin': Request to re-load GM configuration file (ip: %s).\n", ip);
- read_gm_account();
- // send GM accounts to all char-servers
- send_GM_accounts(-1);
- RFIFOSKIP(fd,2);
- break;
-
- default:
- {
- FILE *logfp;
- char tmpstr[24];
- time_t raw_time;
- logfp = fopen(login_log_unknown_packets_filename, "a");
- if (logfp) {
- time(&raw_time);
- strftime(tmpstr, 23, login_config.date_format, localtime(&raw_time));
- fprintf(logfp, "%s: receiving of an unknown packet -> disconnection\n", tmpstr);
- fprintf(logfp, "parse_admin: connection #%d (ip: %s), packet: 0x%x (with being read: %lu).\n", fd, ip, command, (unsigned long)RFIFOREST(fd));
- fprintf(logfp, "Detail (in hex):\n");
- fprintf(logfp, "---- 00-01-02-03-04-05-06-07 08-09-0A-0B-0C-0D-0E-0F\n");
- memset(tmpstr, '\0', sizeof(tmpstr));
- for(i = 0; i < RFIFOREST(fd); i++) {
- if ((i & 15) == 0)
- fprintf(logfp, "%04X ",i);
- fprintf(logfp, "%02x ", RFIFOB(fd,i));
- if (RFIFOB(fd,i) > 0x1f)
- tmpstr[i % 16] = RFIFOB(fd,i);
- else
- tmpstr[i % 16] = '.';
- if ((i - 7) % 16 == 0) // -8 + 1
- fprintf(logfp, " ");
- else if ((i + 1) % 16 == 0) {
- fprintf(logfp, " %s\n", tmpstr);
- memset(tmpstr, '\0', sizeof(tmpstr));
- }
- }
- if (i % 16 != 0) {
- for(j = i; j % 16 != 0; j++) {
- fprintf(logfp, " ");
- if ((j - 7) % 16 == 0) // -8 + 1
- fprintf(logfp, " ");
- }
- fprintf(logfp, " %s\n", tmpstr);
- }
- fprintf(logfp, "\n");
- fclose(logfp);
- }
- }
- login_log("'ladmin': End of connection, unknown packet (ip: %s)\n", ip);
- set_eof(fd);
- ShowWarning("Remote administration has been disconnected (unknown packet).\n");
- return 0;
- }
- }
- RFIFOSKIP(fd,RFIFOREST(fd));
- return 0;
-}
-
//--------------------------------------------
// Test to know if an IP come from LAN or WAN.
//--------------------------------------------
@@ -2949,7 +1820,8 @@ int parse_login(int fd)
uint32 ipl = session[fd]->client_addr;
char ip[16];
- if (session[fd]->eof) {
+ if( session[fd]->eof )
+ {
do_close(fd);
return 0;
}
@@ -2960,7 +1832,7 @@ int parse_login(int fd)
{
uint16 command = RFIFOW(fd,0);
- switch(command)
+ switch( command )
{
case 0x0200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
if (RFIFOREST(fd) < 26)
@@ -2979,12 +1851,12 @@ int parse_login(int fd)
case 0x0277: // New login packet (kRO 2006-04-24aSakexe langtype 0)
case 0x02b0: // New login packet (kRO 2007-05-14aSakexe langtype 0)
{
- int packet_len = RFIFOREST(fd); // assume no other packet was sent
+ size_t packet_len = RFIFOREST(fd); // assume no other packet was sent
- //Perform ip-ban check
+ // Perform ip-ban check
if (!check_ip(ipl))
{
- login_log("Connection refused: IP isn't authorised (deny/allow, ip: %s).\n", ip);
+ ShowStatus("Connection refused: IP isn't authorised (deny/allow, ip: %s).\n", ip);
WFIFOHEAD(fd,23);
WFIFOW(fd,0) = 0x6a;
WFIFOB(fd,2) = 3; // 3 = Rejected from Server
@@ -3004,18 +1876,19 @@ int parse_login(int fd)
// S 01dd <version>.l <account name>.24B <md5 binary>.16B <version2>.B
// S 0277 <version>.l <account name>.24B <password>.24B <junk?>.29B <version2>.B
// S 02b0 <version>.l <account name>.24B <password>.24B <junk?>.30B <version2>.B
-
+
memset(&account, 0, sizeof(account));
account.version = RFIFOL(fd,2);
- if (!account.version) account.version = 1; //Force some version...
+ if( !account.version )
+ account.version = 1; //Force some version...
memcpy(account.userid,RFIFOP(fd,6),NAME_LENGTH); account.userid[23] = '\0';
remove_control_chars(account.userid);
if (command != 0x01dd) {
- login_log("Request for connection (non encryption mode) of %s (ip: %s).\n", account.userid, ip);
+ ShowStatus("Request for connection (non encryption mode) of %s (ip: %s).\n", account.userid, ip);
memcpy(account.passwd, RFIFOP(fd,30), NAME_LENGTH); account.passwd[23] = '\0';
remove_control_chars(account.passwd);
} else {
- login_log("Request for connection (encryption mode) of %s (ip: %s).\n", account.userid, ip);
+ ShowStatus("Request for connection (encryption mode) of %s (ip: %s).\n", account.userid, ip);
memcpy(account.passwd, RFIFOP(fd,30), 16); account.passwd[16] = '\0'; // binary data here
}
account.passwdenc = (command == 0x01dd) ? PASSWORDENC : 0;
@@ -3026,8 +1899,7 @@ int parse_login(int fd)
int gm_level = isGM(account.account_id);
if( login_config.min_level_to_connect > gm_level )
{
- login_log("Connection refused: the minimum GM level for connection is %d (account: %s, GM level: %d, ip: %s).\n",
- login_config.min_level_to_connect, account.userid, gm_level, ip);
+ ShowStatus("Connection refused: the minimum GM level for connection is %d (account: %s, GM level: %d, ip: %s).\n", login_config.min_level_to_connect, account.userid, gm_level, ip);
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
WFIFOB(fd,2) = 1; // 01 = Server closed
@@ -3035,30 +1907,22 @@ int parse_login(int fd)
}
else
{
- uint8 server_num = 0;
+ uint8 server_num, n;
+ uint32 subnet_char_ip;
- WFIFOHEAD(fd,47+32*MAX_SERVERS);
+ server_num = 0;
for( i = 0; i < MAX_SERVERS; ++i )
- {
- if( session_isValid(server_fd[i]) )
- {
- // Advanced subnet check [LuzZza]
- uint32 subnet_char_ip = lan_subnetcheck(ipl);
- WFIFOL(fd,47+server_num*32) = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
- WFIFOW(fd,47+server_num*32+4) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
- memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
- WFIFOW(fd,47+server_num*32+26) = server[i].users;
- WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
- WFIFOW(fd,47+server_num*32+30) = server[i].new_;
+ if( session_isValid(server[i].fd) )
server_num++;
- }
- }
- if (server_num > 0) { // if at least 1 char-server
+
+ if( server_num > 0 )
+ {// if at least 1 char-server
if (gm_level)
ShowStatus("Connection of the GM (level:%d) account '%s' accepted.\n", gm_level, account.userid);
else
ShowStatus("Connection of the account '%s' accepted.\n", account.userid);
+ WFIFOHEAD(fd,47+32*server_num);
WFIFOW(fd,0) = 0x69;
WFIFOW(fd,2) = 47+32*server_num;
WFIFOL(fd,4) = account.login_id1;
@@ -3066,8 +1930,24 @@ int parse_login(int fd)
WFIFOL(fd,12) = account.login_id2;
WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used)
//memcpy(WFIFOP(fd,20), account.lastlogin, 24); // in old version, that was for name (not more used)
+ WFIFOW(fd,44) = 0; // unknown
WFIFOB(fd,46) = account.sex;
+ for( i = 0, n = 0; i < MAX_SERVERS; ++i )
+ {
+ if( !session_isValid(server[i].fd) )
+ continue;
+
+ subnet_char_ip = lan_subnetcheck(ipl); // Advanced subnet check [LuzZza]
+ WFIFOL(fd,47+n*32) = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
+ 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+30) = server[i].new_;
+ n++;
+ }
WFIFOSET(fd,47+32*server_num);
+
if (auth_fifo_pos >= AUTH_FIFO_SIZE)
auth_fifo_pos = 0;
auth_fifo[auth_fifo_pos].account_id = account.account_id;
@@ -3077,9 +1957,11 @@ int parse_login(int fd)
auth_fifo[auth_fifo_pos].delflag = 0;
auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr;
auth_fifo_pos++;
- } else { // if no char-server, don't send void list of servers, just disconnect the player with proper message
+ }
+ else
+ {// if no char-server, don't send void list of servers, just disconnect the player with proper message
ShowStatus("Connection refused: there is no char-server online (account: %s, ip: %s).\n", account.userid, ip);
- login_log("Connection refused: there is no char-server online (account: %s, ip: %s).\n", account.userid, ip);
+ WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
WFIFOB(fd,2) = 1; // 01 = Server closed
WFIFOSET(fd,3);
@@ -3091,7 +1973,9 @@ int parse_login(int fd)
WFIFOHEAD(fd,23);
WFIFOW(fd,0) = 0x6a;
WFIFOB(fd,2) = (uint8)result;
- if( result == 6 )
+ if( result != 6 )
+ memset(WFIFOP(fd,3), '\0', 20);
+ else
{// 6 = Your are Prohibited to log in until %s
char tmpstr[20];
time_t ban_until_time;
@@ -3100,8 +1984,6 @@ int parse_login(int fd)
strftime(tmpstr, 20, login_config.date_format, localtime(&ban_until_time));
safestrncpy((char*)WFIFOP(fd,3), tmpstr, 20); // ban timestamp goes here
}
- else
- memset(WFIFOP(fd,3), '\0', 20);
WFIFOSET(fd,23);
}
@@ -3122,13 +2004,13 @@ int parse_login(int fd)
CREATE(ld, struct login_session_data, 1);
session[fd]->session_data = ld;
-
+
// Creation of the coding key
memset(ld->md5key, '\0', sizeof(ld->md5key));
ld->md5keylen = (uint16)(12 + rand() % 4);
for( i = 0; i < ld->md5keylen; ++i )
ld->md5key[i] = (char)(1 + rand() % 255);
-
+
WFIFOHEAD(fd,4 + ld->md5keylen);
WFIFOW(fd,0) = 0x01dc;
WFIFOW(fd,2) = 4 + ld->md5keylen;
@@ -3146,7 +2028,7 @@ int parse_login(int fd)
char* server_name;
uint32 server_ip;
uint16 server_port;
-
+
memset(&account, 0, sizeof(account));
safestrncpy(account.userid, (char*)RFIFOP(fd,2), NAME_LENGTH); remove_control_chars(account.userid);
safestrncpy(account.passwd, (char*)RFIFOP(fd,26), NAME_LENGTH); remove_control_chars(account.passwd);
@@ -3154,15 +2036,13 @@ int parse_login(int fd)
server_name = (char*)RFIFOP(fd,60); server_name[20] = '\0'; remove_control_chars(server_name);
server_ip = ntohl(RFIFOL(fd, 54));
server_port = ntohs(RFIFOW(fd, 58));
-
+
ShowInfo("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (account: '%s', pass: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, account.userid, account.passwd, ip);
- login_log("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (account: '%s', pass: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, account.userid, account.passwd, ip);
-
+
result = mmo_auth(&account, fd);
- if( result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server_fd[account.account_id] == -1 )
+ if( result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server[account.account_id].fd == -1 )
{
ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
- login_log("Connection of the char-server '%s' accepted.\n", server_name);
memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
server[account.account_id].ip = ntohl(RFIFOL(fd,54));
server[account.account_id].port = ntohs(RFIFOW(fd,58));
@@ -3170,23 +2050,22 @@ int parse_login(int fd)
server[account.account_id].users = 0;
server[account.account_id].maintenance = RFIFOW(fd,82);
server[account.account_id].new_ = RFIFOW(fd,84);
- server_fd[account.account_id] = fd;
-
- WFIFOHEAD(fd,3);
+ server[account.account_id].fd = fd;
+
+ WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2711;
WFIFOB(fd,2) = 0;
WFIFOSET(fd,3);
-
+
session[fd]->func_parse = parse_fromchar;
session[fd]->client_addr = 0;
realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
-
+
send_GM_accounts(fd); // send GM account to char-server
}
else
{
ShowNotice("Connection of the char-server '%s' REFUSED.\n", server_name);
- login_log("Connection of the char-server '%s' REFUSED.\n", server_name);
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2711;
WFIFOB(fd,2) = 3;
@@ -3198,7 +2077,7 @@ int parse_login(int fd)
return 0;
case 0x7530: // Server version information request
- login_log("Sending of the server version (ip: %s)\n", ip);
+ ShowStatus("Sending server version information to ip: %s\n", ip);
WFIFOHEAD(fd,10);
WFIFOW(fd,0) = 0x7531;
WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
@@ -3214,7 +2093,7 @@ int parse_login(int fd)
break;
case 0x7532: // Request to end connection
- login_log("End of connection (ip: %s)\n", ip);
+ ShowStatus("End of connection (ip: %s)\n", ip);
set_eof(fd);
return 0;
@@ -3224,7 +2103,7 @@ int parse_login(int fd)
WFIFOW(fd,0) = 0x7919;
WFIFOB(fd,2) = 1;
if (!check_ladminip(session[fd]->client_addr)) {
- login_log("'ladmin'-login: Connection in administration mode refused: IP isn't authorised (ladmin_allow, ip: %s).\n", ip);
+ ShowNotice("'ladmin'-login: Connection in administration mode refused: IP isn't authorised (ladmin_allow, ip: %s).\n", ip);
} else {
struct login_session_data *ld = (struct login_session_data*)session[fd]->session_data;
if (RFIFOW(fd,2) == 0) { // non encrypted password
@@ -3233,14 +2112,13 @@ int parse_login(int fd)
password[24] = '\0';
remove_control_chars(password);
if( !admin_state )
- login_log("'ladmin'-login: Connection in administration mode REFUSED - remote administration is disabled (non encrypted password: %s, ip: %s)\n", password, ip);
+ ShowNotice("'ladmin'-login: Connection in administration mode REFUSED - remote administration is disabled (non encrypted password: %s, ip: %s)\n", password, ip);
else
if( strcmp(password, admin_pass) != 0)
- login_log("'ladmin'-login: Connection in administration mode REFUSED - invalid password (non encrypted password: %s, ip: %s)\n", password, ip);
+ ShowNotice("'ladmin'-login: Connection in administration mode REFUSED - invalid password (non encrypted password: %s, ip: %s)\n", password, ip);
else {
// If remote administration is enabled and password sent by client matches password read from login server configuration file
- login_log("'ladmin'-login: Connection in administration mode accepted (non encrypted password: %s, ip: %s)\n", password, ip);
- ShowNotice("Connection of a remote administration accepted (non encrypted password).\n");
+ ShowNotice("'ladmin'-login: Connection in administration mode accepted (non encrypted password: %s, ip: %s)\n", password, ip);
WFIFOB(fd,2) = 0;
session[fd]->func_parse = parse_admin;
}
@@ -3256,13 +2134,13 @@ int parse_login(int fd)
}
MD5_String2binary(md5str, md5bin);
if( !admin_state )
- login_log("'ladmin'-login: Connection in administration mode REFUSED - remote administration is disabled (encrypted password, ip: %s)\n", ip);
+ ShowNotice("'ladmin'-login: Connection in administration mode REFUSED - remote administration is disabled (encrypted password, ip: %s)\n", ip);
else
if( memcmp(md5bin, RFIFOP(fd,4), 16) != 0 )
- login_log("'ladmin'-login: Connection in administration mode REFUSED - invalid password (encrypted password, ip: %s)\n", ip);
+ ShowNotice("'ladmin'-login: Connection in administration mode REFUSED - invalid password (encrypted password, ip: %s)\n", ip);
else {
// If remote administration is enabled and password hash sent by client matches hash of password read from login server configuration file
- login_log("'ladmin'-login: Connection in administration mode accepted (encrypted password, ip: %s)\n", ip);
+ ShowNotice("'ladmin'-login: Connection in administration mode accepted (encrypted password, ip: %s)\n", ip);
ShowNotice("Connection of a remote administration accepted (encrypted password).\n");
WFIFOB(fd,2) = 0;
session[fd]->func_parse = parse_admin;
@@ -3316,7 +2194,7 @@ int parse_login(int fd)
fclose(logfp);
}
}
- login_log("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, command);
+ ShowNotice("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, command);
set_eof(fd);
return 0;
}
@@ -3338,7 +2216,6 @@ int parse_console(char* buf)
sscanf(buf, "%[^\n]", command);
ShowInfo("Console command :%s", command);
- login_log("Console command :%s\n", command);
if( strcmpi("shutdown", command) == 0 ||
strcmpi("exit", command) == 0 ||
@@ -3386,7 +2263,7 @@ int login_lan_config_read(const char *lancfgName)
FILE *fp;
int line_num = 0;
char line[1024], w1[64], w2[64], w3[64], w4[64];
-
+
if((fp = fopen(lancfgName, "r")) == NULL) {
ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
return 1;
@@ -3417,7 +2294,7 @@ int login_lan_config_read(const char *lancfgName)
subnet[subnet_count].char_ip = str2ip(w3);
subnet[subnet_count].map_ip = str2ip(w4);
- if( (subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip&subnet[subnet_count].mask) )
+ if( (subnet[subnet_count].char_ip & subnet[subnet_count].mask) != (subnet[subnet_count].map_ip & subnet[subnet_count].mask) )
{
ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
continue;
@@ -3425,7 +2302,6 @@ int login_lan_config_read(const char *lancfgName)
subnet_count++;
}
-
}
ShowStatus("Read information about %d subnetworks.\n", subnet_count);
@@ -3524,18 +2400,12 @@ int login_config_read(const char* cfgName)
gm_account_filename_check_timer = atoi(w2);
} else if (strcmpi(w1, "log_login") == 0) {
login_config.log_login = (bool)config_switch(w2);
- } else if (strcmpi(w1, "login_log_filename") == 0) {
- memset(login_log_filename, 0, sizeof(login_log_filename));
- strncpy(login_log_filename, w2, sizeof(login_log_filename));
- login_log_filename[sizeof(login_log_filename)-1] = '\0';
} else if (strcmpi(w1, "login_log_unknown_packets_filename") == 0) {
memset(login_log_unknown_packets_filename, 0, sizeof(login_log_unknown_packets_filename));
strncpy(login_log_unknown_packets_filename, w2, sizeof(login_log_unknown_packets_filename));
login_log_unknown_packets_filename[sizeof(login_log_unknown_packets_filename)-1] = '\0';
} else if (strcmpi(w1, "save_unknown_packets") == 0) {
save_unknown_packets = config_switch(w2);
- } else if (strcmpi(w1, "add_to_unlimited_account") == 0) {
- add_to_unlimited_account = config_switch(w2);
} else if (strcmpi(w1, "start_limited_time") == 0) {
start_limited_time = atoi(w2);
} else if (strcmpi(w1, "order") == 0) {
@@ -3659,16 +2529,6 @@ void display_conf_warnings(void)
level_new_gm = 60;
}
- if (login_config.new_account_flag != 0 && login_config.new_account_flag != 1) {
- ShowWarning("Invalid value for new_account parameter -> setting to 0 (no new account).\n");
- login_config.new_account_flag = 0;
- }
-
- if (login_config.login_port < 1024) {
- ShowWarning("Invalid value for login_port parameter -> setting to 6900 (default).\n");
- login_config.login_port = 6900;
- }
-
if (gm_account_filename_check_timer < 0) {
ShowWarning("Invalid value for gm_account_filename_check_timer parameter. Setting to 15 sec (default).\n");
gm_account_filename_check_timer = 15;
@@ -3677,11 +2537,6 @@ void display_conf_warnings(void)
gm_account_filename_check_timer = 2;
}
- if (save_unknown_packets != 0 && save_unknown_packets != 1) {
- ShowWarning("Invalid value for save_unknown_packets parameter -> setting to 0-no save.\n");
- save_unknown_packets = 0;
- }
-
if (login_config.min_level_to_connect < 0) { // 0: all players, 1-99 at least gm level x
ShowWarning("Invalid value for min_level_to_connect (%d) parameter -> setting 0 (any player).\n", login_config.min_level_to_connect);
login_config.min_level_to_connect = 0;
@@ -3690,12 +2545,6 @@ void display_conf_warnings(void)
login_config.min_level_to_connect = 99;
}
- if (add_to_unlimited_account != 0 && add_to_unlimited_account != 1) { // 0: no, 1: yes
- ShowWarning("Invalid value for add_to_unlimited_account parameter\n");
- ShowWarning(" -> setting to 0 (impossible to add a time to an unlimited account).\n");
- add_to_unlimited_account = 0;
- }
-
if (start_limited_time < -1) { // -1: create unlimited account, 0 or more: additionnal sec from now to create limited time
ShowWarning("Invalid value for start_limited_time parameter\n");
ShowWarning(" -> setting to -1 (new accounts are created with unlimited time).\n");
@@ -3725,133 +2574,6 @@ void display_conf_warnings(void)
return;
}
-//-------------------------------
-// Save configuration in log file
-//-------------------------------
-void save_config_in_log(void)
-{
- int i;
-
- // a newline in the log...
- login_log("");
- login_log("The login-server starting...\n");
-
- // save configuration in log file
- login_log("The configuration of the server is set:\n");
-
- if( !admin_state )
- login_log("- with no remote administration.\n");
- else if (admin_pass[0] == '\0')
- login_log("- with a remote administration with a VOID password.\n");
- else if (strcmp(admin_pass, "admin") == 0)
- login_log("- with a remote administration with the DEFAULT password.\n");
- else
- login_log("- with a remote administration with the password of %d character(s).\n", strlen(admin_pass));
- if (access_ladmin_allownum == 0 || (access_ladmin_allownum == 1 && access_ladmin_allow[0] == '\0')) {
- login_log("- to accept any IP for remote administration\n");
- } else {
- login_log("- to accept following IP for remote administration:\n");
- for(i = 0; i < access_ladmin_allownum; i++)
- login_log(" %s\n", (char *)(access_ladmin_allow + i * ACO_STRSIZE));
- }
-
- if (gm_pass[0] == '\0')
- login_log("- with a VOID 'To GM become' password (gm_pass).\n");
- else if (strcmp(gm_pass, "gm") == 0)
- login_log("- with the DEFAULT 'To GM become' password (gm_pass).\n");
- else
- login_log("- with a 'To GM become' password (gm_pass) of %d character(s).\n", strlen(gm_pass));
- if (level_new_gm == 0)
- login_log("- to refuse any creation of GM with @gm.\n");
- else
- login_log("- to create GM with level '%d' when @gm is used.\n", level_new_gm);
-
- if (login_config.new_account_flag == 1)
- login_log("- to ALLOW new users (with _F/_M).\n");
- else
- login_log("- to NOT ALLOW new users (with _F/_M).\n");
- login_log("- with port: %d.\n", login_config.login_port);
- login_log("- with the accounts file name: '%s'.\n", account_filename);
- login_log("- with the GM accounts file name: '%s'.\n", GM_account_filename);
- if (gm_account_filename_check_timer == 0)
- login_log("- to NOT check GM accounts file modifications.\n");
- else
- login_log("- to check GM accounts file modifications every %d seconds.\n", gm_account_filename_check_timer);
-
- if (login_config.use_md5_passwds == 0)
- login_log("- to save password in plain text.\n");
- else
- login_log("- to save password with MD5 encrypting.\n");
-
- // not necessary to log the 'login_log_filename', we are inside :)
-
- login_log("- with the unknown packets file name: '%s'.\n", login_log_unknown_packets_filename);
- if (save_unknown_packets)
- login_log("- to SAVE all unkown packets.\n");
- else
- login_log("- to SAVE only unkown packets sending by a char-server or a remote administration.\n");
-
- if (login_config.min_level_to_connect == 0) // 0: all players, 1-99 at least gm level x
- login_log("- with no minimum level for connection.\n");
- else if (login_config.min_level_to_connect == 99)
- login_log("- to accept only GM with level 99.\n");
- else
- login_log("- to accept only GM with level %d or more.\n", login_config.min_level_to_connect);
-
- if (add_to_unlimited_account)
- login_log("- to authorize adjustment (with timeadd ladmin) on an unlimited account.\n");
- else
- login_log("- to refuse adjustment (with timeadd ladmin) on an unlimited account. You must use timeset (ladmin command) before.\n");
-
- if (start_limited_time < 0)
- login_log("- to create new accounts with an unlimited time.\n");
- else if (start_limited_time == 0)
- login_log("- to create new accounts with a limited time: time of creation.\n");
- else
- login_log("- to create new accounts with a limited time: time of creation + %d second(s).\n", start_limited_time);
-
- if (access_order == ACO_DENY_ALLOW) {
- if (access_denynum == 0) {
- login_log("- with the IP security order: 'deny,allow' (allow if not deny). You refuse no IP.\n");
- } else if (access_denynum == 1 && access_deny[0] == '\0') {
- login_log("- with the IP security order: 'deny,allow' (allow if not deny). You refuse ALL IP.\n");
- } else {
- login_log("- with the IP security order: 'deny,allow' (allow if not deny). Refused IP are:\n");
- for(i = 0; i < access_denynum; i++)
- login_log(" %s\n", (char *)(access_deny + i * ACO_STRSIZE));
- }
- } else if (access_order == ACO_ALLOW_DENY) {
- if (access_allownum == 0) {
- login_log("- with the IP security order: 'allow,deny' (deny if not allow). But, NO IP IS AUTHORISED!\n");
- } else if (access_allownum == 1 && access_allow[0] == '\0') {
- login_log("- with the IP security order: 'allow,deny' (deny if not allow). You authorise ALL IP.\n");
- } else {
- login_log("- with the IP security order: 'allow,deny' (deny if not allow). Authorised IP are:\n");
- for(i = 0; i < access_allownum; i++)
- login_log(" %s\n", (char *)(access_allow + i * ACO_STRSIZE));
- }
- } else { // ACO_MUTUAL_FAILTURE
- login_log("- with the IP security order: 'mutual-failture' (allow if in the allow list and not in the deny list).\n");
- if (access_allownum == 0) {
- login_log(" But, NO IP IS AUTHORISED!\n");
- } else if (access_denynum == 1 && access_deny[0] == '\0') {
- login_log(" But, you refuse ALL IP!\n");
- } else {
- if (access_allownum == 1 && access_allow[0] == '\0') {
- login_log(" You authorise ALL IP.\n");
- } else {
- login_log(" Authorised IP are:\n");
- for(i = 0; i < access_allownum; i++)
- login_log(" %s\n", (char *)(access_allow + i * ACO_STRSIZE));
- }
- login_log(" Refused IP are:\n");
- for(i = 0; i < access_denynum; i++)
- login_log(" %s\n", (char *)(access_deny + i * ACO_STRSIZE));
- }
-
- }
-}
-
void login_set_defaults()
{
login_config.login_ip = INADDR_ANY;
@@ -3894,16 +2616,14 @@ void do_final(void)
if(access_allow) aFree(access_allow);
if(access_deny) aFree(access_deny);
for (i = 0; i < MAX_SERVERS; i++) {
- if ((fd = server_fd[i]) >= 0) {
- server_fd[i] = -1;
+ if ((fd = server[i].fd) >= 0) {
+ server[i].fd = -1;
memset(&server[i], 0, sizeof(struct mmo_char_server));
do_close(fd);
}
}
do_close(login_fd);
- login_log("----End of login-server (normal end with closing of all files).\n");
-
if(log_fp)
fclose(log_fp);
ShowStatus("Finished.\n");
@@ -3927,14 +2647,13 @@ void set_server_type(void)
//------------------------------
int do_init(int argc, char** argv)
{
- int i, j;
+ int i;
login_set_defaults();
// read login-server configuration
login_config_read((argc > 1) ? argv[1] : LOGIN_CONF_NAME);
display_conf_warnings(); // not in login_config_read, because we can use 'import' option, and display same message twice or more
- save_config_in_log(); // not before, because log file name can be changed
login_lan_config_read((argc > 2) ? argv[2] : LAN_CONF_NAME);
srand((unsigned int)time(NULL));
@@ -3943,7 +2662,7 @@ int do_init(int argc, char** argv)
auth_fifo[i].delflag = 1;
for( i = 0; i < MAX_SERVERS; i++ )
- server_fd[i] = -1;
+ server[i].fd = -1;
// Online user database init
online_db = idb_alloc(DB_OPT_RELEASE_DATA);
@@ -3961,14 +2680,11 @@ int do_init(int argc, char** argv)
add_timer_func_list(check_auth_sync, "check_auth_sync");
add_timer_interval(gettick() + 60000, check_auth_sync, 0, 0, 60000); // every 60 sec we check if we must save accounts file (only if necessary to save)
- // add timer to check GM accounts file modification
- j = gm_account_filename_check_timer;
- if (j == 0) // if we would not to check, we check every 60 sec, just to have timer (if we change timer, is was not necessary to check if timer already exists)
- j = 60;
-
// every x sec we check if gm file has been changed
- add_timer_func_list(check_GM_file, "check_GM_file");
- add_timer_interval(gettick() + j * 1000, check_GM_file, 0, 0, j * 1000);
+ if( gm_account_filename_check_timer ) {
+ add_timer_func_list(check_GM_file, "check_GM_file");
+ add_timer_interval(gettick() + gm_account_filename_check_timer * 1000, check_GM_file, 0, 0, gm_account_filename_check_timer * 1000);
+ }
// every 10 minutes cleanup online account db.
add_timer_func_list(online_data_cleanup, "online_data_cleanup");
@@ -3990,7 +2706,6 @@ int do_init(int argc, char** argv)
// server port open & binding
login_fd = make_listen_bind(login_config.login_ip, login_config.login_port);
- login_log("The login-server is ready (Server is listening on the port %d).\n", login_config.login_port);
ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login_config.login_port);
return 0;
diff --git a/src/login/login.h b/src/login/login.h
index 405b3fab2..ab6396a5d 100644
--- a/src/login/login.h
+++ b/src/login/login.h
@@ -4,7 +4,7 @@
#ifndef _LOGIN_H_
#define _LOGIN_H_
-#include "../common/mmo.h"
+#include "../common/mmo.h" // NAME_LENGTH
#define LOGIN_CONF_NAME "conf/login_athena.conf"
#define LAN_CONF_NAME "conf/subnet_athena.conf"
@@ -24,10 +24,12 @@ struct mmo_account {
long char_id;
char lastlogin[24];
char sex;
+ //uint8 level;
};
struct mmo_char_server {
char name[20];
+ int fd;
uint32 ip;
uint16 port;
uint16 users; // user count on this server
@@ -35,4 +37,62 @@ struct mmo_char_server {
uint16 new_; // allows creating new chars?
};
+extern struct Login_Config {
+
+ uint32 login_ip; // the address to bind to
+ uint16 login_port; // the port to bind to
+ unsigned int ip_sync_interval; // interval (in minutes) to execute a DNS/IP update (for dynamic IPs)
+ bool log_login; // whether to log login server actions or not
+ char date_format[32]; // date format used in messages
+ bool console; // console input system enabled?
+ bool new_account_flag; // autoregistration via _M/_F ?
+// bool case_sensitive; // are logins case sensitive ?
+ bool use_md5_passwds; // work with password hashes instead of plaintext passwords?
+// bool login_gm_read; // should the login server handle info about gm accounts?
+ 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)
+
+// bool ipban; // perform IP blocking (via contents of `ipbanlist`) ?
+// bool dynamic_pass_failure_ban; // automatic IP blocking due to failed login attemps ?
+// unsigned int dynamic_pass_failure_ban_interval; // how far to scan the loginlog for password failures
+// unsigned int dynamic_pass_failure_ban_limit; // number of failures needed to trigger the ipban
+// unsigned int dynamic_pass_failure_ban_duration; // duration of the ipban
+ bool use_dnsbl; // dns blacklist blocking ?
+ char dnsbl_servs[1024]; // comma-separated list of dnsbl servers
+
+} login_config;
+
+// TXT-specific account database
+// holds info about all existing accounts (entire contents of account.txt)
+extern struct auth_data {
+ int account_id;
+ uint8 sex; // 0, 1, 2
+ char userid[24];
+ char pass[32+1]; // 23+1 for normal, 32+1 for md5-ed passwords
+ char lastlogin[24];
+ int logincount;
+ uint32 state; // packet 0x006a value + 1 (0: compte OK)
+ char email[40]; // e-mail (by default: a@a.com)
+ char error_message[20]; // Message of error code #6 = Your are Prohibited to log in until %s (packet 0x006a)
+ time_t ban_until_time; // # of seconds 1/1/1970 (timestamp): ban time limit of the account (0 = no ban)
+ time_t connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
+ char last_ip[16]; // save of last IP of connection
+ char memo[255]; // a memo field
+ int account_reg2_num;
+ struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
+} *auth_dat;
+
+// stores auth information of incoming clients
+// used during charserver auth validation process
+#define AUTH_FIFO_SIZE 256
+extern struct _auth_fifo {
+ int account_id;
+ uint32 login_id1, login_id2;
+ uint32 ip;
+ uint8 sex;
+ bool delflag;
+} auth_fifo[AUTH_FIFO_SIZE];
+
#endif /* _LOGIN_H_ */
diff --git a/src/login_sql/login.c b/src/login_sql/login.c
index f72590bac..f63961f82 100644
--- a/src/login_sql/login.c
+++ b/src/login_sql/login.c
@@ -20,36 +20,10 @@
#include <string.h>
#include <sys/stat.h> // for stat/lstat/fstat
-struct Login_Config {
-
- uint32 login_ip; // the address to bind to
- uint16 login_port; // the port to bind to
- unsigned int ip_sync_interval; // interval (in minutes) to execute a DNS/IP update (for dynamic IPs)
- bool log_login; // whether to log login server actions or not
- char date_format[32]; // date format used in messages
- bool console; // console input system enabled?
- bool new_account_flag; // autoregistration via _M/_F ?
- bool case_sensitive; // are logins case sensitive ?
- bool use_md5_passwds; // work with password hashes instead of plaintext passwords?
- bool login_gm_read; // should the login server handle info about gm accounts?
- 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)
-
- bool ipban; // perform IP blocking (via contents of `ipbanlist`) ?
- bool dynamic_pass_failure_ban; // automatic IP blocking due to failed login attemps ?
- unsigned int dynamic_pass_failure_ban_interval; // how far to scan the loginlog for password failures
- unsigned int dynamic_pass_failure_ban_limit; // number of failures needed to trigger the ipban
- unsigned int dynamic_pass_failure_ban_duration; // duration of the ipban
- bool use_dnsbl; // dns blacklist blocking ?
- char dnsbl_servs[1024]; // comma-separated list of dnsbl servers
-
-} login_config;
+struct Login_Config login_config;
int login_fd; // login server socket
#define MAX_SERVERS 30
-int server_fd[MAX_SERVERS]; // char server sockets
struct mmo_char_server server[MAX_SERVERS]; // char server data
// Advanced subnet check [LuzZza]
@@ -98,25 +72,22 @@ struct login_session_data {
char md5key[20];
};
-#define AUTH_FIFO_SIZE 256
-struct _auth_fifo {
- int account_id;
- uint32 login_id1, login_id2;
- uint32 ip;
- uint8 sex;
- bool delflag;
-} auth_fifo[AUTH_FIFO_SIZE];
+// auth information of incoming clients
+struct _auth_fifo auth_fifo[AUTH_FIFO_SIZE];
int auth_fifo_pos = 0;
+//-----------------------------------------------------
+// Online User Database [Wizputer]
+//-----------------------------------------------------
+
struct online_login_data {
int account_id;
int waiting_disconnect;
int char_server;
};
-//-----------------------------------------------------
-
static DBMap* online_db; // int account_id -> struct online_login_data*
+static int waiting_disconnect_timer(int tid, unsigned int tick, int id, int data);
static void* create_online_user(DBKey key, va_list args)
{
@@ -128,13 +99,6 @@ static void* create_online_user(DBKey key, va_list args)
return p;
}
-int charif_sendallwos(int sfd, uint8* buf, size_t len);
-static int waiting_disconnect_timer(int tid, unsigned int tick, int id, int data);
-
-//-----------------------------------------------------
-// Online User Database [Wizputer]
-//-----------------------------------------------------
-
void add_online_user(int char_server, int account_id)
{
struct online_login_data* p;
@@ -172,13 +136,26 @@ static int waiting_disconnect_timer(int tid, unsigned int tick, int id, int data
return 0;
}
-static int sync_ip_addresses(int tid, unsigned int tick, int id, int data)
+//--------------------------------------------------------------------
+// Packet send to all char-servers, except one (wos: without our self)
+//--------------------------------------------------------------------
+int charif_sendallwos(int sfd, uint8* buf, size_t len)
{
- uint8 buf[2];
- ShowInfo("IP Sync in progress...\n");
- WBUFW(buf,0) = 0x2735;
- charif_sendallwos(-1, buf, 2);
- return 0;
+ int i, c;
+
+ for( i = 0, c = 0; i < MAX_SERVERS; ++i )
+ {
+ int fd = server[i].fd;
+ if( session_isValid(fd) && fd != sfd )
+ {
+ WFIFOHEAD(fd,len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd,len);
+ ++c;
+ }
+ }
+
+ return c;
}
//-----------------------------------------------------
@@ -331,7 +308,7 @@ void mmo_db_close(void)
for( i = 0; i < MAX_SERVERS; ++i )
{
- fd = server_fd[i];
+ fd = server[i].fd;
if( session_isValid(fd) )
{// Clean only data related to servers we are connected to. [Skotlex]
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `sstatus` WHERE `index` = '%d'", i) )
@@ -346,30 +323,18 @@ void mmo_db_close(void)
do_close(login_fd);
}
-
-//--------------------------------------------------------------------
-// Packet send to all char-servers, except one (wos: without our self)
-//--------------------------------------------------------------------
-int charif_sendallwos(int sfd, uint8* buf, size_t len)
+//-----------------------------------------------------
+// periodic ip address synchronization
+//-----------------------------------------------------
+static int sync_ip_addresses(int tid, unsigned int tick, int id, int data)
{
- int i, c;
-
- for( i = 0, c = 0; i < MAX_SERVERS; ++i )
- {
- int fd = server_fd[i];
- if( session_isValid(fd) && fd != sfd )
- {
- WFIFOHEAD(fd,len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
- ++c;
- }
- }
-
- return c;
+ uint8 buf[2];
+ ShowInfo("IP Sync in progress...\n");
+ WBUFW(buf,0) = 0x2735;
+ charif_sendallwos(-1, buf, 2);
+ return 0;
}
-
//-----------------------------------------------------
// encrypted/unencrypted password check
//-----------------------------------------------------
@@ -645,7 +610,7 @@ int parse_fromchar(int fd)
char ip[16];
ip2str(ipl, ip);
- ARR_FIND( 0, MAX_SERVERS, id, server_fd[id] == fd );
+ ARR_FIND( 0, MAX_SERVERS, id, server[id].fd == fd );
if( id == MAX_SERVERS )
{// not a char server
set_eof(fd);
@@ -656,7 +621,7 @@ int parse_fromchar(int fd)
if( session[fd]->eof )
{
ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
- server_fd[id] = -1;
+ server[id].fd = -1;
memset(&server[id], 0, sizeof(struct mmo_char_server));
online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline.
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `sstatus` WHERE `index`='%d'", id) )
@@ -673,6 +638,7 @@ int parse_fromchar(int fd)
{
case 0x2709: // request from map-server via char-server to reload GM accounts
+ ShowStatus("Char-server '%s': Request to re-load GM configuration file (ip: %s).\n", server[id].name, ip);
if( login_config.log_login )
{
if( SQL_ERROR == Sql_Query(sql_handle, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`log`) VALUES (NOW(), '%u', '%s', 'GM reload request')", loginlog_db, ipl, server[id].name) )
@@ -689,21 +655,18 @@ int parse_fromchar(int fd)
return 0;
{
int account_id = RFIFOL(fd,2);
- for( i = 0; i < AUTH_FIFO_SIZE; ++i )
- {
- if( auth_fifo[i].account_id == RFIFOL(fd,2) &&
- auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
- auth_fifo[i].login_id2 == RFIFOL(fd,10) &&
- auth_fifo[i].sex == RFIFOB(fd,14) &&
- auth_fifo[i].ip == ntohl(RFIFOL(fd,15)) &&
- !auth_fifo[i].delflag)
- {
- auth_fifo[i].delflag = 1;
- break;
- }
- }
-
- if( i != AUTH_FIFO_SIZE && account_id > 0 )
+ ARR_FIND( 0, AUTH_FIFO_SIZE, i,
+ auth_fifo[i].account_id == RFIFOL(fd,2) &&
+ auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
+ auth_fifo[i].login_id2 == RFIFOL(fd,10) &&
+ auth_fifo[i].sex == RFIFOB(fd,14) &&
+ auth_fifo[i].ip == ntohl(RFIFOL(fd,15)) &&
+ !auth_fifo[i].delflag );
+
+ if( i < AUTH_FIFO_SIZE )
+ auth_fifo[i].delflag = 1;
+
+ if( i < AUTH_FIFO_SIZE && account_id > 0 )
{// send ack
uint32 connect_until_time;
char email[40];
@@ -737,7 +700,8 @@ int parse_fromchar(int fd)
WFIFOSET(fd,51);
}
else
- {// authentification not found
+ {// authentication not found
+ ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
WFIFOHEAD(fd,51);
WFIFOW(fd,0) = 0x2713;
WFIFOL(fd,2) = account_id;
@@ -752,7 +716,7 @@ int parse_fromchar(int fd)
break;
case 0x2714:
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
// how many users on world? (update)
@@ -906,9 +870,8 @@ int parse_fromchar(int fd)
if (RFIFOREST(fd) < 10)
return 0;
{
- int account_id, state;
- account_id = RFIFOL(fd,2);
- state = RFIFOL(fd,6);
+ int account_id = RFIFOL(fd,2);
+ int state = RFIFOL(fd,6);
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `state` FROM `%s` WHERE `%s` = '%d'", login_db, login_db_account_id, account_id) )
Sql_ShowDebug(sql_handle);
else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
@@ -990,7 +953,7 @@ int parse_fromchar(int fd)
break;
case 0x2727: // Change of sex (sex is reversed)
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
{
int account_id;
@@ -1099,14 +1062,14 @@ int parse_fromchar(int fd)
}
case 0x272b: // Set account_id to online [Wizputer]
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
add_online_user(id, RFIFOL(fd,2));
RFIFOSKIP(fd,6);
break;
case 0x272c: // Set account_id to offline [Wizputer]
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
remove_online_user(RFIFOL(fd,2));
RFIFOSKIP(fd,6);
@@ -1179,7 +1142,7 @@ int parse_fromchar(int fd)
break;
case 0x2736: // WAN IP update from char-server
- if (RFIFOREST(fd) < 6)
+ if( RFIFOREST(fd) < 6 )
return 0;
server[id].ip = ntohl(RFIFOL(fd,2));
ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
@@ -1256,14 +1219,14 @@ int parse_login(int fd)
uint32 ipl = session[fd]->client_addr;
char ip[16];
- ip2str(ipl, ip);
-
if( session[fd]->eof )
{
do_close(fd);
return 0;
}
+ ip2str(ipl, ip);
+
while( RFIFOREST(fd) >= 2 )
{
uint16 command = RFIFOW(fd,0);
@@ -1287,11 +1250,12 @@ int parse_login(int fd)
case 0x0277: // New login packet (kRO 2006-04-24aSakexe langtype 0)
case 0x02b0: // New login packet (kRO 2007-05-14aSakexe langtype 0)
{
- size_t packet_len = RFIFOREST(fd);
+ size_t packet_len = RFIFOREST(fd); // assume no other packet was sent
// Perform ip-ban check
if( login_config.ipban && login_ip_ban_check(ipl) )
{
+ ShowStatus("Connection refused: IP isn't authorised (deny/allow, ip: %s).\n", ip);
WFIFOHEAD(fd,23);
WFIFOW(fd,0) = 0x6a;
WFIFOB(fd,2) = 3; // 3 = Rejected from Server
@@ -1326,6 +1290,7 @@ int parse_login(int fd)
{ // auth success
if( login_config.min_level_to_connect > account.level )
{
+ ShowStatus("Connection refused: the minimum GM level for connection is %d (account: %s, GM level: %d, ip: %s).\n", login_config.min_level_to_connect, account.userid, account.level, ip);
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
WFIFOB(fd,2) = 1; // 01 = Server closed
@@ -1333,32 +1298,24 @@ int parse_login(int fd)
}
else
{
- uint8 server_num = 0;
+ uint8 server_num, n;
+ uint32 subnet_char_ip;
- if( login_config.log_login && SQL_ERROR == Sql_Query(sql_handle, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, ipl, esc_userid) )
- Sql_ShowDebug(sql_handle);
- if( account.level )
- ShowStatus("Connection of the GM (level:%d) account '%s' accepted.\n", account.level, account.userid);
- else
- ShowStatus("Connection of the account '%s' accepted.\n", account.userid);
-
- WFIFOHEAD(fd,47+32*MAX_SERVERS);
+ server_num = 0;
for( i = 0; i < MAX_SERVERS; ++i )
- {
- if( session_isValid(server_fd[i]) )
- {
- // Advanced subnet check [LuzZza]
- uint32 subnet_char_ip = lan_subnetcheck(ipl);
- WFIFOL(fd,47+server_num*32) = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
- WFIFOW(fd,47+server_num*32+4) = ntows(htons(server[i].port)); // [!] LE byte order here [!]
- memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
- WFIFOW(fd,47+server_num*32+26) = server[i].users;
- WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
- WFIFOW(fd,47+server_num*32+30) = server[i].new_;
+ if( session_isValid(server[i].fd) )
server_num++;
- }
- }
- if (server_num > 0) { // if at least 1 char-server
+
+ if( server_num > 0 )
+ {// if at least 1 char-server
+ if( login_config.log_login && SQL_ERROR == Sql_Query(sql_handle, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, ipl, esc_userid) )
+ Sql_ShowDebug(sql_handle);
+ if( account.level )
+ ShowStatus("Connection of the GM (level:%d) account '%s' accepted.\n", account.level, account.userid);
+ else
+ ShowStatus("Connection of the account '%s' accepted.\n", account.userid);
+
+ WFIFOHEAD(fd,47+32*server_num);
WFIFOW(fd,0) = 0x69;
WFIFOW(fd,2) = 47+32*server_num;
WFIFOL(fd,4) = account.login_id1;
@@ -1366,8 +1323,24 @@ int parse_login(int fd)
WFIFOL(fd,12) = account.login_id2;
WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used)
//memcpy(WFIFOP(fd,20), account.lastlogin, 24); // in old version, that was for name (not more used)
+ WFIFOW(fd,44) = 0; // unknown
WFIFOB(fd,46) = account.sex;
+ for( i = 0, n = 0; i < MAX_SERVERS; ++i )
+ {
+ if( !session_isValid(server[i].fd) )
+ continue;
+
+ subnet_char_ip = lan_subnetcheck(ipl); // Advanced subnet check [LuzZza]
+ WFIFOL(fd,47+n*32) = htonl((subnet_char_ip) ? subnet_char_ip : server[i].ip);
+ 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+30) = server[i].new_;
+ n++;
+ }
WFIFOSET(fd,47+32*server_num);
+
if (auth_fifo_pos >= AUTH_FIFO_SIZE)
auth_fifo_pos = 0;
auth_fifo[auth_fifo_pos].account_id = account.account_id;
@@ -1377,7 +1350,11 @@ int parse_login(int fd)
auth_fifo[auth_fifo_pos].delflag = 0;
auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr;
auth_fifo_pos++;
- } else { // if no char-server, don't send void list of servers, just disconnect the player with proper message
+ }
+ else
+ {// if no char-server, don't send void list of servers, just disconnect the player with proper message
+ ShowStatus("Connection refused: there is no char-server online (account: %s, ip: %s).\n", account.userid, ip);
+ WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
WFIFOB(fd,2) = 1; // 01 = Server closed
WFIFOSET(fd,3);
@@ -1445,7 +1422,9 @@ int parse_login(int fd)
WFIFOHEAD(fd,23);
WFIFOW(fd,0) = 0x6a;
WFIFOB(fd,2) = (uint8)result;
- if( result == 6 )
+ if( result != 6 )
+ memset(WFIFOP(fd,3), '\0', 20);
+ else
{// 6 = Your are Prohibited to log in until %s
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `ban_until` FROM `%s` WHERE `%s` = %s '%s'", login_db, login_db_userid, (login_config.case_sensitive ? "BINARY" : ""), esc_userid) )
Sql_ShowDebug(sql_handle);
@@ -1461,8 +1440,6 @@ int parse_login(int fd)
strftime((char*)WFIFOP(fd,3), 20, login_config.date_format, localtime(&ban_until_time));
}
}
- else
- memset(WFIFOP(fd,3), '\0', 20);
WFIFOSET(fd,23);
}
@@ -1526,7 +1503,7 @@ int parse_login(int fd)
Sql_ShowDebug(sql_handle);
result = mmo_auth(&account, fd);
- if( result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server_fd[account.account_id] == -1 )
+ if( result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server[account.account_id].fd == -1 )
{
ShowStatus("Connection of the char-server '%s' accepted.\n", esc_server_name);
memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
@@ -1536,7 +1513,7 @@ int parse_login(int fd)
server[account.account_id].users = 0;
server[account.account_id].maintenance = RFIFOW(fd,82);
server[account.account_id].new_ = RFIFOW(fd,84);
- server_fd[account.account_id] = fd;
+ server[account.account_id].fd = fd;
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2711;
@@ -1560,14 +1537,12 @@ int parse_login(int fd)
WFIFOB(fd,2) = 3;
WFIFOSET(fd,3);
}
-
+ }
RFIFOSKIP(fd,86);
return 0;
- }
case 0x7530: // Server version information request
- {
- ShowInfo ("Athena version check...\n");
+ ShowStatus("Sending server version information to ip: %s\n", ip);
WFIFOHEAD(fd,10);
WFIFOW(fd,0) = 0x7531;
WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
@@ -1580,7 +1555,6 @@ int parse_login(int fd)
WFIFOSET(fd,10);
RFIFOSKIP(fd,2);
- }
break;
case 0x7532: // Request to end connection
@@ -1589,7 +1563,7 @@ int parse_login(int fd)
break;
default:
- ShowStatus("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, RFIFOW(fd,0));
+ ShowNotice("Abnormal end of connection (ip: %s): Unknown packet 0x%x\n", ip, command);
set_eof(fd);
return 0;
}
@@ -1618,7 +1592,7 @@ int parse_console(char* buf)
strcmpi("end", command) == 0 )
runflag = 0;
else
- if( strcmpi("alive", command) == 0 ||
+ if( strcmpi("alive", command) == 0 ||
strcmpi("status", command) == 0 )
ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
else
@@ -1931,7 +1905,7 @@ int do_init(int argc, char** argv)
auth_fifo[i].delflag = 1;
for( i = 0; i < MAX_SERVERS; i++ )
- server_fd[i] = -1;
+ server[i].fd = -1;
// Online user database init
online_db = idb_alloc(DB_OPT_RELEASE_DATA);
diff --git a/src/login_sql/login.h b/src/login_sql/login.h
index bc6337f42..b67d202cb 100644
--- a/src/login_sql/login.h
+++ b/src/login_sql/login.h
@@ -4,6 +4,8 @@
#ifndef _LOGIN_SQL_H_
#define _LOGIN_SQL_H_
+#include "../common/mmo.h" // NAME_LENGTH
+
#define LOGIN_CONF_NAME "conf/login_athena.conf"
#define SQL_CONF_NAME "conf/inter_athena.conf"
#define LAN_CONF_NAME "conf/subnet_athena.conf"
@@ -18,9 +20,9 @@ struct mmo_account {
int passwdenc;
int account_id;
- int char_id;
long login_id1;
long login_id2;
+ int char_id;
char lastlogin[24];
int sex;
uint8 level;
@@ -28,6 +30,7 @@ struct mmo_account {
struct mmo_char_server {
char name[20];
+ int fd;
uint32 ip;
uint16 port;
int users;
@@ -35,4 +38,42 @@ struct mmo_char_server {
int new_;
};
+extern struct Login_Config {
+
+ uint32 login_ip; // the address to bind to
+ uint16 login_port; // the port to bind to
+ unsigned int ip_sync_interval; // interval (in minutes) to execute a DNS/IP update (for dynamic IPs)
+ bool log_login; // whether to log login server actions or not
+ char date_format[32]; // date format used in messages
+ bool console; // console input system enabled?
+ bool new_account_flag; // autoregistration via _M/_F ?
+ bool case_sensitive; // are logins case sensitive ?
+ bool use_md5_passwds; // work with password hashes instead of plaintext passwords?
+ bool login_gm_read; // should the login server handle info about gm accounts?
+ 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)
+
+ bool ipban; // perform IP blocking (via contents of `ipbanlist`) ?
+ bool dynamic_pass_failure_ban; // automatic IP blocking due to failed login attemps ?
+ unsigned int dynamic_pass_failure_ban_interval; // how far to scan the loginlog for password failures
+ unsigned int dynamic_pass_failure_ban_limit; // number of failures needed to trigger the ipban
+ unsigned int dynamic_pass_failure_ban_duration; // duration of the ipban
+ bool use_dnsbl; // dns blacklist blocking ?
+ char dnsbl_servs[1024]; // comma-separated list of dnsbl servers
+
+} login_config;
+
+// stores auth information of incoming clients
+// used during charserver auth validation process
+#define AUTH_FIFO_SIZE 256
+extern struct _auth_fifo {
+ int account_id;
+ uint32 login_id1, login_id2;
+ uint32 ip;
+ uint8 sex;
+ bool delflag;
+} auth_fifo[AUTH_FIFO_SIZE];
+
#endif /* _LOGIN_SQL_H_ */
diff --git a/src/map/clif.h b/src/map/clif.h
index ca26a9b67..daca310ef 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -30,7 +30,7 @@ struct guild;
// v8 - 2007-05-21aSakexe+ - 0x283
// v9 - 2007-11-06aSakexe+ - 0x78, 0x7c, 0x22c
#ifndef PACKETVER
- #define PACKETVER 8
+ #define PACKETVER 7
#endif
// packet DB
diff --git a/src/map/script.c b/src/map/script.c
index 4e81e752e..bf8b3ea93 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -11610,7 +11610,7 @@ BUILDIN_FUNC(query_sql)
num_cols = Sql_NumColumns(mmysql_handle);
if( num_vars < num_cols )
{
- ShowWarning("script:query_sql: Too many columns, discarting last %u columns.\n", (unsigned int)(num_cols-num_vars));
+ ShowWarning("script:query_sql: Too many columns, discarding last %u columns.\n", (unsigned int)(num_cols-num_vars));
script_reportsrc(st);
}
else if( num_vars > num_cols )
diff --git a/vcproj-6/login-server_txt.dsp b/vcproj-6/login-server_txt.dsp
index 51cbbc1c7..c6b39002f 100644
--- a/vcproj-6/login-server_txt.dsp
+++ b/vcproj-6/login-server_txt.dsp
@@ -187,6 +187,10 @@ SOURCE=..\src\common\version.h
# PROP Default_Filter ""
# Begin Source File
+SOURCE=..\src\login\admin.c
+# End Source File
+# Begin Source File
+
SOURCE=..\src\login\login.c
# End Source File
# Begin Source File
diff --git a/vcproj-7.1/login-server_txt.vcproj b/vcproj-7.1/login-server_txt.vcproj
index d1ae81345..b31316fa0 100644
--- a/vcproj-7.1/login-server_txt.vcproj
+++ b/vcproj-7.1/login-server_txt.vcproj
@@ -148,6 +148,9 @@
Name="login_txt"
Filter="">
<File
+ RelativePath="..\src\login\admin.c">
+ </File>
+ <File
RelativePath="..\src\login\login.c">
</File>
<File
diff --git a/vcproj-8/login-server_txt.vcproj b/vcproj-8/login-server_txt.vcproj
index 048f6860f..d4611de8d 100644
--- a/vcproj-8/login-server_txt.vcproj
+++ b/vcproj-8/login-server_txt.vcproj
@@ -204,6 +204,10 @@
Name="login_txt"
>
<File
+ RelativePath="..\src\login\admin.c"
+ >
+ </File>
+ <File
RelativePath="..\src\login\login.c"
>
</File>