* TXT/SQL login server code synchronization
- 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 - removed login/char server_fd[] arrays, added server[].fd instead git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11826 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
4b8cf3c768
commit
ea5212c5a8
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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@
|
||||
|
2061
src/login/login.c
2061
src/login/login.c
File diff suppressed because it is too large
Load Diff
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
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 && account_id > 0 )
|
||||
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);
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
|
@ -147,6 +147,9 @@
|
||||
<Filter
|
||||
Name="login_txt"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\src\login\admin.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\login\login.c">
|
||||
</File>
|
||||
|
@ -203,6 +203,10 @@
|
||||
<Filter
|
||||
Name="login_txt"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\src\login\admin.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\login\login.c"
|
||||
>
|
||||
|
Loading…
x
Reference in New Issue
Block a user