summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-04-05 18:49:57 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-04-05 18:49:57 +0000
commit88a5d0cdda513357496b9d53878618e1620f47e8 (patch)
tree4f3c2bedbac4b715ff783de5e1c8d1aefe4395af /src
parenta7fd6bfe9bcce1862b554f5841d9ff1aedf473e3 (diff)
downloadhercules-88a5d0cdda513357496b9d53878618e1620f47e8.tar.gz
hercules-88a5d0cdda513357496b9d53878618e1620f47e8.tar.bz2
hercules-88a5d0cdda513357496b9d53878618e1620f47e8.tar.xz
hercules-88a5d0cdda513357496b9d53878618e1620f47e8.zip
* Made a crazy attempt to at least partially synchronize login&char code
* Major edit to the way the servers handle ip addresses, making them obey the "host byte order inside, network byte order outside" rule - hopefully covered all entry- and exit-points for IP address data - discovered several places where Gravity's client breaks the convention, will need to come up with a suitable countermeasure for that - other than that, the code should be portable, except for printing and ipban mask testing (those still assume a specific byte order) - tested both txt and sql in all usual situations; tested single- and multi-server setups, all seems to work (but watch out for hidden bugs!) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10162 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c426
-rw-r--r--src/char_sql/char.c588
-rw-r--r--src/common/mmo.h4
-rw-r--r--src/common/socket.c70
-rw-r--r--src/common/socket.h18
-rw-r--r--src/common/strlib.c46
-rw-r--r--src/common/strlib.h17
-rw-r--r--src/common/utils.c46
-rw-r--r--src/login/login.c773
-rw-r--r--src/login_sql/login.c361
-rw-r--r--src/login_sql/login.h4
-rw-r--r--src/map/chrif.c147
-rw-r--r--src/map/chrif.h12
-rw-r--r--src/map/clif.c51
-rw-r--r--src/map/clif.h10
-rw-r--r--src/map/map.c21
-rw-r--r--src/map/map.h10
-rw-r--r--src/map/pc.c15
18 files changed, 1230 insertions, 1389 deletions
diff --git a/src/char/char.c b/src/char/char.c
index a09ca72dd..65e1dc3e6 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -44,8 +44,8 @@
#ifndef TXT_SQL_CONVERT
struct mmo_map_server{
- long ip;
- short port;
+ uint32 ip;
+ uint16 port;
int users;
unsigned short map[MAX_MAP_PER_SERVER];
} server[MAX_MAP_SERVERS];
@@ -57,13 +57,13 @@ char passwd[24];
char server_name[20];
char wisp_server_name[NAME_LENGTH] = "Server";
char login_ip_str[128];
-in_addr_t login_ip;
-int login_port = 6900;
+uint32 login_ip;
+uint16 login_port = 6900;
char char_ip_str[128];
-in_addr_t char_ip;
+uint32 char_ip;
char bind_ip_str[128];
-in_addr_t bind_ip;
-int char_port = 6121;
+uint32 bind_ip;
+uint16 char_port = 6121;
int char_maintenance;
int char_new;
int char_new_display;
@@ -80,10 +80,10 @@ char db_path[1024]="db";
// Advanced subnet check [LuzZza]
struct _subnet {
- long subnet;
- long mask;
- long char_ip;
- long map_ip;
+ uint32 subnet;
+ uint32 mask;
+ uint32 char_ip;
+ uint32 map_ip;
} subnet[16];
int subnet_count = 0;
@@ -106,7 +106,10 @@ struct char_session_data{
#define AUTH_FIFO_SIZE 256
struct {
- int account_id, char_id, login_id1, login_id2, ip, char_pos, delflag, sex;
+ int account_id, char_id, login_id1, login_id2;
+ uint32 ip;
+ int delflag;
+ int sex;
time_t connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
} auth_fifo[AUTH_FIFO_SIZE];
int auth_fifo_pos = 0;
@@ -137,7 +140,7 @@ struct fame_list chemist_fame_list[MAX_FAME_LIST];
struct fame_list taekwon_fame_list[MAX_FAME_LIST];
// Initial position (it's possible to set it in conf file)
-struct point start_point = { 0, 53, 111};
+struct point start_point = { 0, 53, 111 };
struct gm_account *gm_account = NULL;
int GM_num = 0;
@@ -2004,7 +2007,7 @@ int parse_tologin(int fd) {
sd = (struct char_session_data*)session[fd]->session_data;
- while(RFIFOREST(fd) >= 2 && !session[fd]->eof) {
+ while(RFIFOREST(fd) >= 2) {
// printf("parse_tologin: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));
switch(RFIFOW(fd,0)) {
@@ -2105,9 +2108,8 @@ int parse_tologin(int fd) {
auth_fifo[i].login_id1 = RFIFOL(fd,6);
auth_fifo[i].login_id2 = RFIFOL(fd,10);
auth_fifo[i].delflag = 2; // 0: auth_fifo canceled/void, 2: auth_fifo received from login/map server in memory, 1: connection authentified
- auth_fifo[i].char_pos = 0;
auth_fifo[i].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
- auth_fifo[i].ip = RFIFOL(fd,14);
+ auth_fifo[i].ip = ntohl(RFIFOL(fd,14));
RFIFOSKIP(fd,18);
break;
@@ -2472,7 +2474,7 @@ int parse_tologin(int fd) {
case 0x2735:
{
unsigned char buf[2];
- in_addr_t new_ip = 0;
+ uint32 new_ip = 0;
RFIFOSKIP(fd,2);
WBUFW(buf,0) = 0x2b1e;
@@ -2487,9 +2489,9 @@ int parse_tologin(int fd) {
{ //Update ip.
WFIFOHEAD(fd,6);
char_ip = new_ip;
- ShowInfo("Updating IP for [%s].\n",char_ip_str);
+ ShowInfo("Updating IP for [%s].\n", char_ip_str);
WFIFOW(fd,0) = 0x2736;
- WFIFOL(fd,2) = char_ip;
+ WFIFOL(fd,2) = htonl(char_ip);
WFIFOSET(fd,6);
}
break;
@@ -2693,9 +2695,10 @@ void char_update_fame_list(int type, int index, int fame)
mapif_sendall(buf, 8);
}
-int search_mapserver(unsigned short map, long ip, short port);
+int search_mapserver(unsigned short map, uint32 ip, uint16 port);
-int parse_frommap(int fd) {
+int parse_frommap(int fd)
+{
int i, j;
int id;
RFIFOHEAD(fd);
@@ -2711,8 +2714,8 @@ int parse_frommap(int fd) {
ShowStatus("Map-server %d has disconnected.\n", id);
//Notify other map servers that this one is gone. [Skotlex]
WBUFW(buf,0) = 0x2b20;
- WBUFL(buf,4) = server[id].ip;
- WBUFW(buf,8) = server[id].port;
+ WBUFL(buf,4) = htonl(server[id].ip);
+ WBUFW(buf,8) = htons(server[id].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
if (server[id].map[i])
@@ -2734,15 +2737,13 @@ int parse_frommap(int fd) {
switch(RFIFOW(fd,0)) {
- // map-server alive packet
- case 0x2718:
+ case 0x2718: // map-server alive packet
if (RFIFOREST(fd) < 2)
return 0;
RFIFOSKIP(fd,2);
break;
- // request from map-server to reload GM accounts. Transmission to login-server (by Yor)
- case 0x2af7:
+ case 0x2af7: // request from map-server to reload GM accounts. Transmission to login-server
if (login_fd > 0) { // don't send request if no login-server
WFIFOHEAD(login_fd, 2);
WFIFOW(login_fd,0) = 0x2709;
@@ -2751,71 +2752,70 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd,2);
break;
- // Receiving map names list from the map-server
- case 0x2afa:
+ case 0x2afa: // Receiving map names list from the map-server
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
+
memset(server[id].map, 0, sizeof(server[id].map));
j = 0;
for(i = 4; i < RFIFOW(fd,2); i += 4) {
server[id].map[j] = RFIFOW(fd,i);
j++;
}
- {
- unsigned char *p = (unsigned char *)&server[id].ip;
- ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
- id, j, p[0], p[1], p[2], p[3], server[id].port);
- ShowStatus("Map-server %d loading complete.\n", id);
- char_log("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d. Map-server %d loading complete." RETCODE,
- id, j, p[0], p[1], p[2], p[3], server[id].port, id);
-
- if (max_account_id != DEFAULT_MAX_ACCOUNT_ID || max_char_id != DEFAULT_MAX_CHAR_ID)
- mapif_send_maxid(max_account_id, max_char_id); //Send the current max ids to the server to keep in sync [Skotlex]
- }
+
+ ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
+ id, j, CONVIP(server[id].ip), server[id].port);
+ ShowStatus("Map-server %d loading complete.\n", id);
+ char_log("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d. Map-server %d loading complete." RETCODE,
+ id, j, CONVIP(server[id].ip), server[id].port, id);
+
+ if (max_account_id != DEFAULT_MAX_ACCOUNT_ID || max_char_id != DEFAULT_MAX_CHAR_ID)
+ mapif_send_maxid(max_account_id, max_char_id); //Send the current max ids to the server to keep in sync [Skotlex]
+
WFIFOHEAD(fd, 3 + NAME_LENGTH);
WFIFOW(fd,0) = 0x2afb;
WFIFOB(fd,2) = 0;
memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH); // name for wisp to player
WFIFOSET(fd,3+NAME_LENGTH);
- //WFIFOSET(fd,27);
+
char_send_fame_list(fd); //Send fame list.
+
{
- unsigned char buf[16384];
- int x;
- if (j == 0) {
- ShowWarning("Map-Server %d have NO map.\n", id);
- char_log("WARNING: Map-Server %d have NO map." RETCODE, id);
+ unsigned char buf[16384];
+ int x;
+ if (j == 0) {
+ ShowWarning("Map-server %d has NO maps.\n", id);
+ char_log("WARNING: Map-server %d has NO maps." RETCODE, id);
+ } else {
// Transmitting maps information to the other map-servers
- } else {
- WBUFW(buf,0) = 0x2b04;
- WBUFW(buf,2) = j * 4 + 10;
- WBUFL(buf,4) = server[id].ip;
- WBUFW(buf,8) = server[id].port;
- memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4);
- mapif_sendallwos(fd, buf, WBUFW(buf,2));
- }
- // 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) {
- WFIFOW(fd,0) = 0x2b04;
- WFIFOL(fd,4) = server[x].ip;
- WFIFOW(fd,8) = server[x].port;
- j = 0;
- for(i = 0; i < MAX_MAP_PER_SERVER; i++)
- if (server[x].map[i])
- WFIFOW(fd,10+(j++)*4) = server[x].map[i];
- if (j > 0) {
- WFIFOW(fd,2) = j * 4 + 10;
- WFIFOSET(fd,WFIFOW(fd,2));
- }
+ WBUFW(buf,0) = 0x2b04;
+ WBUFW(buf,2) = j * 4 + 10;
+ WBUFL(buf,4) = htonl(server[id].ip);
+ WBUFW(buf,8) = htons(server[id].port);
+ memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4);
+ mapif_sendallwos(fd, buf, WBUFW(buf,2));
+ }
+ // 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) {
+ WFIFOW(fd,0) = 0x2b04;
+ WFIFOL(fd,4) = htonl(server[x].ip);
+ WFIFOW(fd,8) = htons(server[x].port);
+ j = 0;
+ for(i = 0; i < MAX_MAP_PER_SERVER; i++)
+ if (server[x].map[i])
+ WFIFOW(fd,10+(j++)*4) = server[x].map[i];
+ if (j > 0) {
+ WFIFOW(fd,2) = j * 4 + 10;
+ WFIFOSET(fd,WFIFOW(fd,2));
}
}
}
+ }
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
- //Packet command is now used for sc_data request. [Skotlex]
- case 0x2afc:
+ case 0x2afc: //Packet command is now used for sc_data request. [Skotlex]
if (RFIFOREST(fd) < 10)
return 0;
{
@@ -2844,8 +2844,7 @@ int parse_frommap(int fd) {
break;
}
- //set MAP user count
- case 0x2afe:
+ case 0x2afe: //set MAP user count
if (RFIFOREST(fd) < 4)
return 0;
if (RFIFOW(fd,2) != server[id].users) {
@@ -2854,8 +2853,8 @@ int parse_frommap(int fd) {
}
RFIFOSKIP(fd, 4);
break;
- //set MAP users
- case 0x2aff:
+
+ case 0x2aff: //set MAP users
if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
//TODO: When data mismatches memory, update guild/party online/offline states.
@@ -2887,9 +2886,7 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd,6+i*8);
break;
- // キャラデータ保存
- // Recieve character data from map-server
- case 0x2b01:
+ case 0x2b01: // Receive character data from map-server for saving
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
for(i = 0; i < char_num; i++) {
@@ -2902,28 +2899,28 @@ int parse_frommap(int fd) {
if (RFIFOB(fd,12))
{ //Flag, set character offline. [Skotlex]
set_char_offline(RFIFOL(fd,8),RFIFOL(fd,4));
- WFIFOW(fd, 0) = 0x2b21; //Save ack only needed on final save.
- WFIFOL(fd, 2) = RFIFOL(fd,4);
- WFIFOL(fd, 6) = RFIFOL(fd,8);
- WFIFOSET(fd, 10);
+ WFIFOW(fd,0) = 0x2b21; //Save ack only needed on final save.
+ WFIFOL(fd,2) = RFIFOL(fd,4);
+ WFIFOL(fd,6) = RFIFOL(fd,8);
+ WFIFOSET(fd,10);
}
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
- // キャラセレ要求
- case 0x2b02:
+ case 0x2b02: // req char selection
if (RFIFOREST(fd) < 18)
return 0;
+
if (auth_fifo_pos >= AUTH_FIFO_SIZE)
auth_fifo_pos = 0;
+
auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd,2);
auth_fifo[auth_fifo_pos].char_id = 0;
auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd,6);
auth_fifo[auth_fifo_pos].login_id2 = RFIFOL(fd,10);
auth_fifo[auth_fifo_pos].delflag = 2;
- auth_fifo[auth_fifo_pos].char_pos = 0;
auth_fifo[auth_fifo_pos].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
- auth_fifo[auth_fifo_pos].ip = RFIFOL(fd,14);
+ auth_fifo[auth_fifo_pos].ip = ntohl(RFIFOL(fd,14));
auth_fifo_pos++;
WFIFOW(fd,0) = 0x2b03;
WFIFOL(fd,2) = RFIFOL(fd,2);
@@ -2932,8 +2929,7 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd,18);
break;
- // request "change map server"
- case 0x2b05:
+ case 0x2b05: // request "change map server"
if (RFIFOREST(fd) < 35)
return 0;
{
@@ -2943,7 +2939,7 @@ int parse_frommap(int fd) {
struct mmo_charstatus* char_data;
name = RFIFOW(fd,18);
- map_id = search_mapserver(name, RFIFOL(fd,24), RFIFOW(fd,28)); //Locate mapserver by ip and port.
+ 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];
for(i = 0; i < char_num; i++) {
@@ -2951,16 +2947,16 @@ int parse_frommap(int fd) {
char_dat[i].status.char_id == RFIFOL(fd,14))
break;
}
- char_data = i< char_num? &char_dat[i].status:NULL;
+ char_data = i < char_num ? &char_dat[i].status : NULL;
//Tell the new map server about this player using Kevin's new auth packet. [Skotlex]
- if (map_fd>=0 && session[map_fd] && char_data)
+ if (map_fd >= 0 && session[map_fd] && char_data)
{ //Send the map server the auth of this player.
//Update the "last map" as this is where the player must be spawned on the new map server.
WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus));
char_data->last_point.map = RFIFOW(fd,18);
char_data->last_point.x = RFIFOW(fd,20);
char_data->last_point.y = RFIFOW(fd,22);
- char_data->sex = RFIFOB(fd,30); // Buuyo^
+ char_data->sex = RFIFOB(fd,30);
WFIFOW(map_fd,0) = 0x2afd;
WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus);
@@ -2988,8 +2984,7 @@ int parse_frommap(int fd) {
}
break;
- // キャラ名検索
- case 0x2b08:
+ case 0x2b08: // char name check
if (RFIFOREST(fd) < 6)
return 0;
for(i = 0; i < char_num; i++) {
@@ -3006,8 +3001,7 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd,6);
break;
- // it is a request to become GM
- case 0x2b0a:
+ case 0x2b0a: // request to become GM
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
// printf("parse_frommap: change gm -> login, account: %d, pass: '%s'.\n", RFIFOL(fd,4), RFIFOP(fd,8));
@@ -3026,8 +3020,7 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd, RFIFOW(fd,2));
break;
- // Map server send information to change an email of an account -> login-server
- case 0x2b0c:
+ case 0x2b0c: // Map server send information to change an email of an account -> login-server
if (RFIFOREST(fd) < 86)
return 0;
if (login_fd > 0) { // don't send request if no login-server
@@ -3039,15 +3032,14 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd, 86);
break;
- // Map server ask char-server about a character name to do some operations (all operations are transmitted to login-server)
- case 0x2b0e:
+ case 0x2b0e: // Request from map-server to change a char's status (all operations are transmitted to login-server)
if (RFIFOREST(fd) < 44)
return 0;
{
char character_name[NAME_LENGTH];
int acc = RFIFOL(fd,2); // account_id of who ask (-1 if nobody)
memcpy(character_name, RFIFOP(fd,6), NAME_LENGTH-1);
- character_name[NAME_LENGTH -1] = '\0';
+ character_name[NAME_LENGTH-1] = '\0';
// prepare answer
WFIFOW(fd,0) = 0x2b0f; // answer
WFIFOL(fd,2) = acc; // who want do operation
@@ -3151,8 +3143,7 @@ int parse_frommap(int fd) {
// case 0x2b0f: Not used anymore, available for future use
- // Update and send fame ranking list [DracoRPG]
- case 0x2b10:
+ case 0x2b10: // Update and send fame ranking list
if (RFIFOREST(fd) < 12)
return 0;
{
@@ -3181,8 +3172,7 @@ int parse_frommap(int fd) {
size = 0;
break;
}
- if(!size)
- break;
+ if(!size) break; //No list.
if(pos)
{
pos--; //Convert from pos to index.
@@ -3200,10 +3190,11 @@ int parse_frommap(int fd) {
list[size-1].id = 0;
list[size-1].fame = 0;
}
+
// Find the position where the player has to be inserted
for(i = 0; i < size && fame < list[i].fame; i++);
- // When found someone with less or as much fame, insert just above
if(i >= size) break;//Out of ranking.
+ // When found someone with less or as much fame, insert just above
memmove(list+i+1, list+i, (size-i-1) * sizeof(struct fame_list));
list[i].id = cid;
list[i].fame = fame;
@@ -3217,38 +3208,33 @@ int parse_frommap(int fd) {
}
break;
- // Recieve rates [Wizputer]
- case 0x2b16:
+ case 0x2b16: // Recieve rates [Wizputer]
if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,8))
return 0;
// Txt doesn't need this packet, so just skip it
RFIFOSKIP(fd,RFIFOW(fd,8));
break;
- // Character disconnected set online 0 [Wizputer]
- case 0x2b17:
+ case 0x2b17: // Character disconnected set online 0 [Wizputer]
if (RFIFOREST(fd) < 6)
return 0;
set_char_offline(RFIFOL(fd,2),RFIFOL(fd,6));
RFIFOSKIP(fd,10);
break;
- // Reset all chars to offline [Wizputer]
- case 0x2b18:
+ case 0x2b18: // Reset all chars to offline [Wizputer]
set_all_offline(id);
RFIFOSKIP(fd,2);
break;
- // Character set online [Wizputer]
- case 0x2b19:
+ case 0x2b19: // Character set online [Wizputer]
if (RFIFOREST(fd) < 6)
return 0;
set_char_online(id, RFIFOL(fd,2),RFIFOL(fd,6));
RFIFOSKIP(fd,10);
break;
- // Build and send fame ranking lists [DracoRPG]
- case 0x2b1a:
+ case 0x2b1a: // Build and send fame ranking lists [DracoRPG]
if (RFIFOREST(fd) < 2)
return 0;
char_read_fame_list();
@@ -3256,14 +3242,14 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd,2);
break;
- //Request to save status change data. [Skotlex]
- case 0x2b1c:
+ case 0x2b1c: //Request to save status change data. [Skotlex]
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
{
#ifdef ENABLE_SC_SAVING
int count, aid, cid;
struct scdata *data;
+
aid = RFIFOL(fd, 4);
cid = RFIFOL(fd, 8);
count = RFIFOW(fd, 12);
@@ -3279,14 +3265,14 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd, RFIFOW(fd, 2));
break;
}
- case 0x2736:
+
+ case 0x2736: // ip address update
if (RFIFOREST(fd) < 6) return 0;
- ShowInfo("Updated IP address of Server #%d to %d.%d.%d.%d.\n",id,
- (int)RFIFOB(fd,2),(int)RFIFOB(fd,3),
- (int)RFIFOB(fd,4),(int)RFIFOB(fd,5));
- server[id].ip = RFIFOL(fd, 2);
+ server[id].ip = ntohl(RFIFOL(fd, 2));
+ ShowInfo("Updated IP address of map-server #%d to %d.%d.%d.%d.\n", id, CONVIP(server[id].ip));
RFIFOSKIP(fd,6);
break;
+
default:
// inter server処理に渡す
{
@@ -3305,16 +3291,17 @@ int parse_frommap(int fd) {
return 0;
}
-int search_mapserver(unsigned short map, long ip, short port) {
+int search_mapserver(unsigned short map, uint32 ip, uint16 port)
+{
int i, j;
for(i = 0; i < MAX_MAP_SERVERS; i++)
- if (server_fd[i] >= 0)
+ if (server_fd[i] > 0)
for (j = 0; server[i].map[j]; j++)
if (server[i].map[j] == map) {
- if (ip > 0 && server[i].ip != ip)
+ if (ip != (uint32)-1 && server[i].ip != ip)
continue;
- if (port > 0 && server[i].port != port)
+ if (port != (uint16)-1 && server[i].port != port)
continue;
return i;
}
@@ -3329,45 +3316,41 @@ static int char_mapif_init(int fd) {
//--------------------------------------------
// Test to know if an IP come from LAN or WAN.
-// Rewrote: Adnvanced subnet check [LuzZza]
//--------------------------------------------
-int lan_subnetcheck(long *p) {
-
+int lan_subnetcheck(uint32 ip)
+{
int i;
- unsigned char *sbn, *msk, *src = (unsigned char *)p;
- for(i=0; i<subnet_count; i++) {
+ for(i = 0; i < subnet_count; i++) {
- if(subnet[i].subnet == (*p & subnet[i].mask)) {
-
- sbn = (unsigned char *)&subnet[i].subnet;
- msk = (unsigned char *)&subnet[i].mask;
+ if((subnet[i].subnet & subnet[i].mask) == (ip & subnet[i].mask)) {
ShowInfo("Subnet check [%u.%u.%u.%u]: Matches "CL_CYAN"%u.%u.%u.%u/%u.%u.%u.%u"CL_RESET"\n",
- src[0], src[1], src[2], src[3], sbn[0], sbn[1], sbn[2], sbn[3], msk[0], msk[1], msk[2], msk[3]);
+ CONVIP(ip), CONVIP(subnet[i].subnet), CONVIP(subnet[i].mask));
return subnet[i].map_ip;
}
}
- ShowInfo("Subnet check [%u.%u.%u.%u]: "CL_CYAN"WAN"CL_RESET"\n", src[0], src[1], src[2], src[3]);
+ ShowInfo("Subnet check [%u.%u.%u.%u]: "CL_CYAN"WAN"CL_RESET"\n", CONVIP(ip));
return 0;
}
-int parse_char(int fd) {
+int parse_char(int fd)
+{
int i, ch;
unsigned short cmd;
char email[40];
int map_fd;
struct char_session_data *sd;
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
- long subnet_map_ip;
+ uint32 ipl = session[fd]->client_addr;
+ uint32 subnet_map_ip;
RFIFOHEAD(fd);
sd = (struct char_session_data*)session[fd]->session_data;
- if (login_fd < 0)
+ if(login_fd < 0)
session[fd]->eof = 1;
if(session[fd]->eof) { // disconnect any player (already connected to char-server or coming back from map-server) if login-server is diconnected.
if (fd == login_fd)
@@ -3384,7 +3367,7 @@ int parse_char(int fd) {
return 0;
}
- while(RFIFOREST(fd) >= 2 && !session[fd]->eof) {
+ while(RFIFOREST(fd) >= 2) {
cmd = RFIFOW(fd,0);
// crc32のスキップ用
if( sd==NULL && // 未ログインor管理パケット
@@ -3412,9 +3395,10 @@ int parse_char(int fd) {
case 0x65: // 接続要求
if (RFIFOREST(fd) < 17)
return 0;
- {
+ {
int GM_value;
WFIFOHEAD(fd, 4);
+
if (sd) {
//Received again auth packet for already authentified account?? Discard it.
//TODO: Perhaps log this as a hack attempt?
@@ -3425,7 +3409,8 @@ int parse_char(int fd) {
ShowInfo("Account Logged On; Account ID: %d (GM level %d).\n", RFIFOL(fd,2), GM_value);
else
ShowInfo("Account Logged On; Account ID: %d.\n", RFIFOL(fd,2));
- sd = (struct char_session_data*)aCalloc(sizeof(struct char_session_data), 1);
+ CREATE(session[fd]->session_data, struct char_session_data, 1);
+ sd = (struct char_session_data*)session[fd]->session_data;
session[fd]->session_data = sd;
strncpy(sd->email, "no mail", 40); // put here a mail without '@' to refuse deletion if we don't receive the e-mail
sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
@@ -3441,14 +3426,14 @@ int parse_char(int fd) {
auth_fifo[i].account_id == sd->account_id &&
auth_fifo[i].login_id1 == sd->login_id1 &&
auth_fifo[i].login_id2 == sd->login_id2 && // relate to the versions higher than 18
- auth_fifo[i].ip == session[fd]->client_addr.sin_addr.s_addr &&
+ auth_fifo[i].ip == session[fd]->client_addr &&
auth_fifo[i].delflag == 2)
; i++);
if (i < AUTH_FIFO_SIZE) {
auth_fifo[i].delflag = 1;
char_auth_ok(fd, sd);
- } else { // authentification not found
+ } else { // authentication not found
if (login_fd > 0) { // don't send request if no login-server
WFIFOHEAD(login_fd,19);
WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
@@ -3456,20 +3441,20 @@ int parse_char(int fd) {
WFIFOL(login_fd,6) = sd->login_id1;
WFIFOL(login_fd,10) = sd->login_id2; // relate to the versions higher than 18
WFIFOB(login_fd,14) = sd->sex;
- WFIFOL(login_fd,15) = session[fd]->client_addr.sin_addr.s_addr;
+ WFIFOL(login_fd,15) = htonl(session[fd]->client_addr);
WFIFOSET(login_fd,19);
} else { // if no login-server, we must refuse connection
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x6c;
- WFIFOW(fd,2) = 0;
+ WFIFOB(fd,2) = 0;
WFIFOSET(fd,3);
}
}
- }
+ }
RFIFOSKIP(fd,17);
break;
- case 0x66: // キャラ選択
+ case 0x66: // char select
FIFOSD_CHECK(3);
{
int char_num = RFIFOB(fd,2);
@@ -3500,6 +3485,7 @@ int parse_char(int fd) {
// searching map server
i = search_mapserver(cd->last_point.map,-1,-1);
+
// if map is not found, we check major cities
if (i < 0) {
unsigned short j;
@@ -3549,18 +3535,18 @@ int parse_char(int fd) {
char map_name[MAP_NAME_LENGTH];
snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(cd->last_point.map));
- WFIFOHEAD(fd, 28);
+ WFIFOHEAD(fd,28);
WFIFOW(fd,0) = 0x71;
WFIFOL(fd,2) = cd->char_id;
memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH);
// Advanced subnet check [LuzZza]
- if((subnet_map_ip = lan_subnetcheck((long *)p)))
- WFIFOL(fd,22) = subnet_map_ip;
+ if(subnet_map_ip = lan_subnetcheck(ipl))
+ WFIFOL(fd,22) = htonl(subnet_map_ip);
else
- WFIFOL(fd,22) = server[i].ip;
+ WFIFOL(fd,22) = htonl(server[i].ip);
- WFIFOW(fd,26) = server[i].port;
+ WFIFOW(fd,26) = server[i].port; // /!\ must be sent in intel host byte order /!\ (client bug)
WFIFOSET(fd,28);
ShowInfo("Character selection '%s' (account: %d, slot: %d).\n",
@@ -3573,14 +3559,13 @@ int parse_char(int fd) {
auth_fifo[auth_fifo_pos].login_id1 = sd->login_id1;
auth_fifo[auth_fifo_pos].login_id2 = sd->login_id2;
auth_fifo[auth_fifo_pos].delflag = 0;
- auth_fifo[auth_fifo_pos].char_pos = sd->found_char[ch];
auth_fifo[auth_fifo_pos].sex = sd->sex;
auth_fifo[auth_fifo_pos].connect_until_time = sd->connect_until_time;
- auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
+ 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)
- { //0 Should not be a valid server_fd [Skotlex]
+ {
WFIFOHEAD(fd, 3);
ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i);
server_fd[i] = -1;
@@ -3602,19 +3587,21 @@ int parse_char(int fd) {
memcpy(WFIFOP(map_fd,20), cd, sizeof(struct mmo_charstatus));
WFIFOSET(map_fd, WFIFOW(map_fd,2));
}
+
set_char_online(i, cd->char_id, cd->account_id);
auth_fifo_pos++;
+ break;
}
- break;
- case 0x67: // 作成
+ case 0x67: // make new
FIFOSD_CHECK(37);
if(char_new == 0) //turn character creation on/off [Kevin]
i = -2;
else
i = make_new_char(fd, RFIFOP(fd,2));
- //added some better fail reporting to client on the txt version [Kevin]
+
+ //'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3)
if (i < 0)
{
WFIFOHEAD(fd, 3);
@@ -3634,6 +3621,7 @@ int parse_char(int fd) {
WFIFOW(fd,0) = 0x6d;
len = 2 + mmo_char_tobuf(WFIFOP(fd,2), &char_dat[i].status);
WFIFOSET(fd,len);
+
RFIFOSKIP(fd,37);
}
for(ch = 0; ch < MAX_CHARS; ch++) {
@@ -3642,19 +3630,23 @@ int parse_char(int fd) {
break;
}
}
+ break;
- case 0x68: // delete char //Yor's Fix
+ case 0x68: // delete char
FIFOSD_CHECK(46);
{
int cid = RFIFOL(fd,2);
struct mmo_charstatus *cs = NULL;
WFIFOHEAD(fd, 46);
WFIFOHEAD(login_fd,46);
+ ShowInfo(CL_RED" Request Char Deletion:"CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
memcpy(email, RFIFOP(fd,6), 40);
RFIFOSKIP(fd,46);
+
if (e_mail_check(email) == 0)
strncpy(email, "a@a.com", 40); // default e-mail
+ // BEGIN HACK: "change email using the char deletion 'confirm email' menu"
// if we activated email creation and email is default email
if (email_creation != 0 && strcmp(sd->email, "a@a.com") == 0 && login_fd > 0) { // to modify an e-mail, login-server must be online
// if sended email is incorrect e-mail
@@ -3688,6 +3680,8 @@ int parse_char(int fd) {
}
break;
}
+ // END HACK
+
// otherwise, we delete the character
if (strcmpi(email, sd->email) != 0) { // if it's an invalid email
WFIFOW(fd, 0) = 0x70;
@@ -3695,16 +3689,18 @@ int parse_char(int fd) {
WFIFOSET(fd, 3);
break;
}
+
for (i = 0; i < MAX_CHARS; i++) {
if (sd->found_char[i] == -1) continue;
if (char_dat[sd->found_char[i]].status.char_id == cid) break;
}
- if (i == MAX_CHARS) {
+ if (i == MAX_CHARS) { // Such a character does not exist in the account
WFIFOW(fd,0) = 0x70;
WFIFOB(fd,2) = 0;
WFIFOSET(fd,3);
break;
}
+
// deletion process
cs = &char_dat[sd->found_char[i]].status;
char_delete(cs);
@@ -3734,36 +3730,37 @@ int parse_char(int fd) {
WFIFOSET(fd,2);
break;
}
- case 0x2af8: // マップサーバーログイン
+
+ case 0x2af8: // login as map-server
if (RFIFOREST(fd) < 60)
return 0;
{
- char *l_user = RFIFOP(fd, 2);
- char *l_pass = RFIFOP(fd, 26);
+ char *l_user = RFIFOP(fd,2);
+ char *l_pass = RFIFOP(fd,26);
WFIFOHEAD(fd, 4+5*GM_num);
l_user[23] = '\0';
l_pass[23] = '\0';
WFIFOW(fd,0) = 0x2af9;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if (server_fd[i] < 0)
+ if (server_fd[i] <= 0)
break;
}
if (i == MAX_MAP_SERVERS ||
strcmp(l_user, userid) ||
- strcmp(l_pass, passwd)){
+ strcmp(l_pass, passwd)) {
WFIFOB(fd,2) = 3;
WFIFOSET(fd,3);
RFIFOSKIP(fd,60);
} else {
int len;
WFIFOB(fd,2) = 0;
+ WFIFOSET(fd,3);
session[fd]->func_parse = parse_frommap;
server_fd[i] = fd;
- server[i].ip = RFIFOL(fd,54);
- server[i].port = RFIFOW(fd,58);
+ server[i].ip = ntohl(RFIFOL(fd,54));
+ server[i].port = ntohs(RFIFOW(fd,58));
server[i].users = 0;
memset(server[i].map, 0, sizeof(server[i].map));
- WFIFOSET(fd,3);
RFIFOSKIP(fd,60);
realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
char_mapif_init(fd);
@@ -3777,18 +3774,17 @@ int parse_char(int fd) {
}
WFIFOW(fd,2) = len;
WFIFOSET(fd,len);
- return 0;
}
- }
break;
+ }
- case 0x187: // Alive信号?
+ case 0x187: // Alive?
if (RFIFOREST(fd) < 6)
return 0;
RFIFOSKIP(fd, 6);
break;
- case 0x7530: // Athena情報所得
+ case 0x7530: // Athena info get
{
WFIFOHEAD(fd, 10);
WFIFOW(fd,0) = 0x7531;
@@ -3803,7 +3799,7 @@ int parse_char(int fd) {
RFIFOSKIP(fd,2);
return 0;
}
- case 0x7532: // 接続の切断(defaultと処理は一緒だが明示的にするため)
+ case 0x7532: // disconnect(default also disconnect)
default:
session[fd]->eof = 1;
return 0;
@@ -3850,22 +3846,14 @@ 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 0 //This seems to have been fixed long long ago.
- if (session[fd] == NULL)
- { //Could this be the crash's source? [Skotlex]
- ShowError("mapif_sendall: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", fd, i);
- server_fd[i] = -1;
- memset(&server[i], 0, sizeof(struct mmo_map_server));
- continue;
- }
-#endif
- WFIFOHEAD(fd, len);
+ if ((fd = server_fd[i]) > 0) {
+ WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
c++;
}
}
+
return c;
}
@@ -3876,15 +3864,14 @@ 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_fd[i]) > 0 && fd != sfd) {
WFIFOHEAD(fd, len);
- if (WFIFOSPACE(fd) < len) //Increase buffer size.
- realloc_writefifo(fd, len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd, len);
c++;
}
}
+
return c;
}
// MAPサーバーにデータ送信(map鯖生存確認有り)
@@ -3894,9 +3881,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]) {
- WFIFOHEAD(fd, len);
- if (WFIFOSPACE(fd) < len) //Increase buffer size.
- realloc_writefifo(fd, len);
+ WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
return 1;
@@ -3912,7 +3897,7 @@ int send_users_tologin(int tid, unsigned int tick, int id, int data) {
if (login_fd > 0 && session[login_fd]) {
// send number of user to login server
- WFIFOHEAD(login_fd, 6);
+ WFIFOHEAD(login_fd,6);
WFIFOW(login_fd,0) = 0x2714;
WFIFOL(login_fd,2) = users;
WFIFOSET(login_fd,6);
@@ -3962,26 +3947,26 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) {
ShowInfo("Attempt to connect to login-server...\n");
login_fd = make_connection(login_ip, login_port);
if (login_fd == -1)
- { //Try again later... [Skotlex]
+ { //Try again later. [Skotlex]
login_fd = 0;
return 0;
}
session[login_fd]->func_parse = parse_tologin;
realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+ {
WFIFOHEAD(login_fd, 86);
WFIFOW(login_fd,0) = 0x2710;
memcpy(WFIFOP(login_fd,2), userid, 24);
memcpy(WFIFOP(login_fd,26), passwd, 24);
WFIFOL(login_fd,50) = 0;
- WFIFOL(login_fd,54) = char_ip;
- WFIFOL(login_fd,58) = char_port;
+ WFIFOL(login_fd,54) = htonl(char_ip);
+ WFIFOL(login_fd,58) = htons(char_port);
memcpy(WFIFOP(login_fd,60), server_name, 20);
WFIFOW(login_fd,80) = 0;
WFIFOW(login_fd,82) = char_maintenance;
-
- WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin]
-
+ WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin]
WFIFOSET(login_fd,86);
+ }
return 1;
}
@@ -4050,9 +4035,9 @@ int char_lan_config_read(const char *lancfgName) {
if(strcmpi(w1, "subnet") == 0) {
- subnet[subnet_count].mask = inet_addr(w2);
- subnet[subnet_count].char_ip = inet_addr(w3);
- subnet[subnet_count].map_ip = inet_addr(w4);
+ subnet[subnet_count].mask = ntohl(inet_addr(w2));
+ subnet[subnet_count].char_ip = ntohl(inet_addr(w3));
+ subnet[subnet_count].map_ip = ntohl(inet_addr(w4));
subnet[subnet_count].subnet = subnet[subnet_count].char_ip&subnet[subnet_count].mask;
if (subnet[subnet_count].subnet != (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);
@@ -4072,7 +4057,7 @@ int char_lan_config_read(const char *lancfgName) {
int char_config_read(const char *cfgName) {
char line[1024], w1[1024], w2[1024];
- FILE *fp = fopen(cfgName, "r");
+ FILE* fp = fopen(cfgName, "r");
if (fp == NULL) {
ShowFatalError("Configuration file not found: %s.\n", cfgName);
@@ -4173,9 +4158,9 @@ int char_config_read(const char *cfgName) {
} else if (strcmpi(w1, "save_log") == 0) {
save_log = config_switch(w2);
} else if (strcmpi(w1, "start_point") == 0) {
- char map[32];
+ char map[MAP_NAME_LENGTH];
int x, y;
- if (sscanf(w2, "%[^,],%d,%d", map, &x, &y) < 3)
+ if (sscanf(w2, "%16[^,],%d,%d", map, &x, &y) < 3)
continue;
start_point.map = mapindex_name2id(map);
if (!start_point.map) {
@@ -4184,8 +4169,6 @@ int char_config_read(const char *cfgName) {
}
start_point.x = x;
start_point.y = y;
- } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil]
- log_char = atoi(w2);
} else if (strcmpi(w1, "start_zeny") == 0) {
start_zeny = atoi(w2);
if (start_zeny < 0)
@@ -4198,6 +4181,8 @@ int char_config_read(const char *cfgName) {
start_armor = atoi(w2);
if (start_armor < 0)
start_armor = 0;
+ } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil]
+ log_char = atoi(w2);
} else if (strcmpi(w1, "unknown_char_name") == 0) {
strcpy(unknown_char_name, w2);
unknown_char_name[NAME_LENGTH-1] = '\0';
@@ -4326,7 +4311,8 @@ static int online_data_cleanup(int tid, unsigned int tick, int id, int data)
return 0;
}
-int do_init(int argc, char **argv) {
+int do_init(int argc, char **argv)
+{
int i;
mapindex_init(); //Needed here for the start-point reading.
@@ -4345,23 +4331,21 @@ int do_init(int argc, char **argv) {
// moved behind char_config_read in case we changed the filename [celest]
char_log("The char-server starting..." RETCODE);
- if ((naddr_ != 0) && (!login_ip || !char_ip)) {
- // The char server should know what IP address it is running on
- // - MouseJstr
- int localaddr = ntohl(addr_[0]);
- unsigned char *ptr = (unsigned char *) &localaddr;
- char buf[16];
- sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);;
- if (naddr_ != 1)
- ShowStatus("Multiple interfaces detected.. using %s as our IP address\n", buf);
+ if ((naddr_ != 0) && (!login_ip || !char_ip))
+ {
+ char ip_str[16];
+ ip2str(addr_[0], ip_str);
+
+ if (naddr_ > 1)
+ ShowStatus("Multiple interfaces detected.. using %s as our IP address\n", ip_str);
else
- ShowStatus("Defaulting to %s as our IP address\n", buf);
+ ShowStatus("Defaulting to %s as our IP address\n", ip_str);
if (!login_ip) {
- strcpy(login_ip_str, buf);
+ strcpy(login_ip_str, ip_str);
login_ip = inet_addr(login_ip_str);
}
if (!char_ip) {
- strcpy(char_ip_str, buf);
+ strcpy(char_ip_str, ip_str);
char_ip = inet_addr(char_ip_str);
}
}
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index 5cc0191e5..e68ea61dc 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -1,9 +1,6 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-// original code from athena
-// SQL conversion by Jioh L. Jung
-// TXT 1.105
#include <sys/types.h>
#ifdef _WIN32
@@ -74,8 +71,8 @@ int lowest_gm_level = 1;
char *SQL_CONF_NAME = "conf/inter_athena.conf";
struct mmo_map_server{
- long ip;
- short port;
+ uint32 ip;
+ uint16 port;
int users;
unsigned short map[MAX_MAP_PER_SERVER];
} server[MAX_MAP_SERVERS];
@@ -88,13 +85,13 @@ char passwd[24];
char server_name[20];
char wisp_server_name[NAME_LENGTH] = "Server";
char login_ip_str[128];
-in_addr_t login_ip = 0;
-int login_port = 6900;
+uint32 login_ip = 0;
+uint16 login_port = 6900;
char char_ip_str[128];
-in_addr_t char_ip = 0;
+uint32 char_ip = 0;
char bind_ip_str[128];
-in_addr_t bind_ip = 0;
-int char_port = 6121;
+uint32 bind_ip = INADDR_ANY;
+uint16 char_port = 6121;
int char_maintenance = 0;
int char_new;
int char_new_display;
@@ -111,10 +108,10 @@ int log_inter = 1; // loggin inter or not [devil]
// Advanced subnet check [LuzZza]
struct _subnet {
- long subnet;
- long mask;
- long char_ip;
- long map_ip;
+ uint32 subnet;
+ uint32 mask;
+ uint32 char_ip;
+ uint32 map_ip;
} subnet[16];
int subnet_count = 0;
@@ -127,7 +124,7 @@ static int max_account_id = DEFAULT_MAX_ACCOUNT_ID, max_char_id = DEFAULT_MAX_CH
static int online_check = 1; //If one, it won't let players connect when their account is already registered online and will send the relevant map server a kick user request. [Skotlex]
struct char_session_data{
- int account_id, login_id1, login_id2,sex;
+ int account_id, login_id1, login_id2, sex;
int found_char[MAX_CHARS];
char email[40]; // e-mail (default: a@a.com) by [Yor]
time_t connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
@@ -135,7 +132,10 @@ struct char_session_data{
#define AUTH_FIFO_SIZE 256
struct {
- int account_id, char_id, login_id1, login_id2, ip, char_pos, delflag,sex;
+ int account_id, char_id, login_id1, login_id2;
+ uint32 ip;
+ int delflag;
+ int sex;
time_t connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
} auth_fifo[AUTH_FIFO_SIZE];
int auth_fifo_pos = 0;
@@ -166,7 +166,7 @@ struct fame_list taekwon_fame_list[MAX_FAME_LIST];
unsigned int save_flag = 0;
// start point (you can reset point on conf file)
-struct point start_point = { 0, 53, 111};
+struct point start_point = { 0, 53, 111 };
bool char_gm_read = false;
struct gm_account *gm_account = NULL;
@@ -1867,7 +1867,7 @@ int parse_tologin(int fd) {
// hehe. no need to set user limit on SQL version. :P
// but char limitation is good way to maintain server. :D
- while(RFIFOREST(fd) >= 2 && !session[fd]->eof) {
+ while(RFIFOREST(fd) >= 2) {
// printf("parse_tologin : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
switch(RFIFOW(fd, 0)){
@@ -1967,10 +1967,8 @@ int parse_tologin(int fd) {
auth_fifo[i].login_id1 = RFIFOL(fd,6);
auth_fifo[i].login_id2 = RFIFOL(fd,10);
auth_fifo[i].delflag = 2; // 0: auth_fifo canceled/void, 2: auth_fifo received from login/map server in memory, 1: connection authentified
- auth_fifo[i].char_pos = 0;
auth_fifo[i].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
- auth_fifo[i].ip = RFIFOL(fd,14);
- //auth_fifo[i].map_auth = 0;
+ auth_fifo[i].ip = ntohl(RFIFOL(fd,14));
RFIFOSKIP(fd,18);
break;
@@ -2239,7 +2237,7 @@ int parse_tologin(int fd) {
case 0x2735:
{
unsigned char buf[2];
- in_addr_t new_ip = 0;
+ uint32 new_ip = 0;
RFIFOSKIP(fd,2);
WBUFW(buf,0) = 0x2b1e;
@@ -2253,10 +2251,10 @@ int parse_tologin(int fd) {
if (new_ip && new_ip != char_ip)
{ //Update ip.
char_ip = new_ip;
- ShowInfo("Updating IP for [%s].\n",char_ip_str);
+ ShowInfo("Updating IP for [%s].\n", char_ip_str);
WFIFOHEAD(fd,6);
WFIFOW(fd,0) = 0x2736;
- WFIFOL(fd,2) = char_ip;
+ WFIFOL(fd,2) = htonl(char_ip);
WFIFOSET(fd,6);
}
break;
@@ -2415,7 +2413,7 @@ void char_update_fame_list(int type, int index, int fame)
mapif_sendall(buf, 8);
}
-int search_mapserver(unsigned short map, long ip, short port);
+int search_mapserver(unsigned short map, uint32 ip, uint16 port);
//Loads a character's name and stores it in the buffer given (must be NAME_LENGTH in size)
//Returns 1 on found, 0 on not found (buffer is filled with Unknown char name)
@@ -2439,7 +2437,8 @@ int char_loadName(int char_id, char* name)
}
-int parse_frommap(int fd) {
+int parse_frommap(int fd)
+{
int i = 0, j = 0;
int id;
RFIFOHEAD(fd);
@@ -2461,8 +2460,8 @@ int parse_frommap(int fd) {
ShowStatus("Map-server %d (session #%d) has disconnected.\n", id, fd);
//Notify other map servers that this one is gone. [Skotlex]
WBUFW(buf,0) = 0x2b20;
- WBUFL(buf,4) = server[id].ip;
- WBUFW(buf,8) = server[id].port;
+ WBUFL(buf,4) = htonl(server[id].ip);
+ WBUFW(buf,8) = htons(server[id].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
if (server[id].map[i])
@@ -2487,12 +2486,11 @@ int parse_frommap(int fd) {
while(RFIFOREST(fd) >= 2) {
switch(RFIFOW(fd, 0)) {
- // map-server alive packet
- case 0x2718:
+ case 0x2718: // map-server alive packet
RFIFOSKIP(fd,2);
break;
- case 0x2af7:
+ case 0x2af7: // request from map-server to reload GM accounts. Transmission to login-server
RFIFOSKIP(fd,2);
if(char_gm_read) //Re-read gm accounts.
read_gm_account();
@@ -2504,14 +2502,10 @@ int parse_frommap(int fd) {
}
break;
- // mapserver -> map names recv.
- case 0x2afa:
+ case 0x2afa: // Receiving map names list from the map-server
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
- {
- unsigned char *p = (unsigned char *)&server[id].ip;
- unsigned char buf[16384];
- int x;
+
WFIFOHEAD(fd,3+NAME_LENGTH);
memset(server[id].map, 0, sizeof(server[id].map));
@@ -2522,7 +2516,7 @@ int parse_frommap(int fd) {
}
ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
- id, j, p[0], p[1], p[2], p[3], server[id].port);
+ id, j, CONVIP(server[id].ip), server[id].port);
ShowStatus("Map-server %d loading complete.\n", id);
if (max_account_id != DEFAULT_MAX_ACCOUNT_ID || max_char_id != DEFAULT_MAX_CHAR_ID)
@@ -2530,20 +2524,22 @@ int parse_frommap(int fd) {
WFIFOW(fd,0) = 0x2afb;
WFIFOB(fd,2) = 0;
- // name for wisp to player
- memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH);
+ memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH); // name for wisp to player
WFIFOSET(fd,3+NAME_LENGTH);
char_send_fame_list(fd); //Send fame list.
- if (j == 0)
- ShowWarning("Map-Server %d have NO maps.\n", id);
- else {
+ {
+ unsigned char buf[16384];
+ int x;
+ if (j == 0) {
+ ShowWarning("Map-server %d has NO maps.\n", id);
+ } else {
// Transmitting maps information to the other map-servers
WBUFW(buf,0) = 0x2b04;
WBUFW(buf,2) = j * 4 + 10;
- WBUFL(buf,4) = server[id].ip;
- WBUFW(buf,8) = server[id].port;
+ WBUFL(buf,4) = htonl(server[id].ip);
+ WBUFW(buf,8) = htons(server[id].port);
memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4);
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
@@ -2552,8 +2548,8 @@ int parse_frommap(int fd) {
if (server_fd[x] > 0 && x != id) {
WFIFOHEAD(fd, 10 +4*MAX_MAP_PER_SERVER);
WFIFOW(fd,0) = 0x2b04;
- WFIFOL(fd,4) = server[x].ip;
- WFIFOW(fd,8) = server[x].port;
+ WFIFOL(fd,4) = htonl(server[x].ip);
+ WFIFOW(fd,8) = htons(server[x].port);
j = 0;
for(i = 0; i < MAX_MAP_PER_SERVER; i++)
if (server[x].map[i])
@@ -2564,11 +2560,11 @@ int parse_frommap(int fd) {
}
}
}
+ }
RFIFOSKIP(fd,RFIFOW(fd,2));
- }
break;
- //Packet command is now used for sc_data request. [Skotlex]
- case 0x2afc:
+
+ case 0x2afc: //Packet command is now used for sc_data request. [Skotlex]
if (RFIFOREST(fd) < 10)
return 0;
{
@@ -2623,8 +2619,8 @@ int parse_frommap(int fd) {
#endif
break;
}
- //set MAP user count
- case 0x2afe:
+
+ case 0x2afe: //set MAP user count
if (RFIFOREST(fd) < 4)
return 0;
if (RFIFOW(fd,2) != server[id].users) {
@@ -2633,8 +2629,8 @@ int parse_frommap(int fd) {
}
RFIFOSKIP(fd, 4);
break;
- // set MAP user
- case 0x2aff:
+
+ case 0x2aff: //set MAP users
if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
{
@@ -2661,8 +2657,8 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
}
- // char saving
- case 0x2b01:
+
+ case 0x2b01: // Receive character data from map-server for saving
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
{
@@ -2689,44 +2685,42 @@ int parse_frommap(int fd) {
if (RFIFOB(fd,12))
{ //Flag? Set character offline after saving [Skotlex]
set_char_offline(cid, aid);
- WFIFOHEAD(fd, 10);
- WFIFOW(fd, 0) = 0x2b21; //Save ack only needed on final save.
- WFIFOL(fd, 2) = aid;
- WFIFOL(fd, 6) = cid;
- WFIFOSET(fd, 10);
+ WFIFOHEAD(fd,10);
+ WFIFOW(fd,0) = 0x2b21; //Save ack only needed on final save.
+ WFIFOL(fd,2) = aid;
+ WFIFOL(fd,6) = cid;
+ WFIFOSET(fd,10);
}
RFIFOSKIP(fd,size);
break;
}
- // req char selection
- case 0x2b02:
+
+ case 0x2b02: // req char selection
if (RFIFOREST(fd) < 18)
return 0;
if (auth_fifo_pos >= AUTH_FIFO_SIZE)
auth_fifo_pos = 0;
- auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd, 2);
+ auth_fifo[auth_fifo_pos].account_id = RFIFOL(fd,2);
auth_fifo[auth_fifo_pos].char_id = 0;
- auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd, 6);
+ auth_fifo[auth_fifo_pos].login_id1 = RFIFOL(fd,6);
auth_fifo[auth_fifo_pos].login_id2 = RFIFOL(fd,10);
auth_fifo[auth_fifo_pos].delflag = 2;
- auth_fifo[auth_fifo_pos].char_pos = 0;
auth_fifo[auth_fifo_pos].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
- auth_fifo[auth_fifo_pos].ip = RFIFOL(fd,14);
+ auth_fifo[auth_fifo_pos].ip = ntohl(RFIFOL(fd,14));
auth_fifo_pos++;
{
- WFIFOHEAD(fd, 7);
- WFIFOW(fd, 0) = 0x2b03;
- WFIFOL(fd, 2) = RFIFOL(fd, 2);
- WFIFOB(fd, 6) = 0;
- WFIFOSET(fd, 7);
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x2b03;
+ WFIFOL(fd,2) = RFIFOL(fd, 2);
+ WFIFOB(fd,6) = 0;
+ WFIFOSET(fd,7);
}
- RFIFOSKIP(fd, 18);
+ RFIFOSKIP(fd,18);
break;
- // request "change map server"
- case 0x2b05:
+ case 0x2b05: // request "change map server"
if (RFIFOREST(fd) < 35)
return 0;
{
@@ -2734,8 +2728,9 @@ int parse_frommap(int fd) {
int map_id, map_fd = -1;
struct online_char_data* data;
struct mmo_charstatus* char_data;
+
name = RFIFOW(fd,18);
- map_id = search_mapserver(name, RFIFOL(fd,24), RFIFOW(fd,28)); //Locate mapserver by ip and port.
+ 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];
//Char should just had been saved before this packet, so this should be safe. [Skotlex]
@@ -2754,7 +2749,7 @@ int parse_frommap(int fd) {
char_data->last_point.map = RFIFOW(fd,18);
char_data->last_point.x = RFIFOW(fd,20);
char_data->last_point.y = RFIFOW(fd,22);
- char_data->sex = RFIFOB(fd,30); // Buuyo^
+ char_data->sex = RFIFOB(fd,30);
WFIFOW(map_fd,0) = 0x2afd;
WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus);
@@ -2783,8 +2778,7 @@ int parse_frommap(int fd) {
}
break;
- // char name check
- case 0x2b08:
+ case 0x2b08: // char name check
if (RFIFOREST(fd) < 6)
return 0;
{
@@ -2799,11 +2793,8 @@ int parse_frommap(int fd) {
}
break;
- // I want become GM - fuck!
- case 0x2b0a:
- if(RFIFOREST(fd)<4)
- return 0;
- if(RFIFOREST(fd)<RFIFOW(fd,2))
+ case 0x2b0a: // request to become GM
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
/*
memcpy(WFIFOP(login_fd,2),RFIFOP(fd,2),RFIFOW(fd,2)-2);
@@ -2815,8 +2806,7 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd, RFIFOW(fd, 2));
break;
- // Map server send information to change an email of an account -> login-server
- case 0x2b0c:
+ case 0x2b0c: // Map server send information to change an email of an account -> login-server
if (RFIFOREST(fd) < 86)
return 0;
if (login_fd > 0) { // don't send request if no login-server
@@ -2828,8 +2818,7 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd, 86);
break;
- // Receiving from map-server a status change resquest. Transmission to login-server (by Yor)
- case 0x2b0e:
+ case 0x2b0e: // Request from map-server to change a char's status (all operations are transmitted to login-server)
if (RFIFOREST(fd) < 44)
return 0;
{
@@ -2944,8 +2933,7 @@ int parse_frommap(int fd) {
// case 0x2b0f: Not used anymore, available for future use
- // Update and send fame ranking list [DracoRPG]
- case 0x2b10:
+ case 0x2b10: // Update and send fame ranking list
if (RFIFOREST(fd) < 12)
return 0;
{
@@ -2953,7 +2941,7 @@ int parse_frommap(int fd) {
int fame = RFIFOL(fd, 6);
char type = RFIFOB(fd, 10);
char pos = RFIFOB(fd, 11);
- int size = 0;
+ int size;
struct fame_list *list = NULL;
RFIFOSKIP(fd,12);
@@ -2970,6 +2958,9 @@ int parse_frommap(int fd) {
size = fame_list_size_taekwon;
list = taekwon_fame_list;
break;
+ default:
+ size = 0;
+ break;
}
if(!size) break; //No list.
if(pos)
@@ -2992,7 +2983,7 @@ int parse_frommap(int fd) {
// Find the position where the player has to be inserted
for(i = 0; i < size && fame < list[i].fame; i++);
- if(i>=size) break; //Out of ranking.
+ if(i >= size) break; //Out of ranking.
// When found someone with less or as much fame, insert just above
memmove(list+i+1, list+i, (size-i-1) * sizeof(struct fame_list));
list[i].id = cid;
@@ -3001,11 +2992,9 @@ int parse_frommap(int fd) {
char_loadName(list[i].id, list[i].name);
char_send_fame_list(-1);
}
-
break;
- // Receive rates [Wizputer]
- case 0x2b16:
+ case 0x2b16: // Receive rates [Wizputer]
if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,8))
return 0;
{
@@ -3025,29 +3014,26 @@ int parse_frommap(int fd) {
break;
}
- // Character disconnected set online 0 [Wizputer]
- case 0x2b17:
- if (RFIFOREST(fd) < 6 )
+ case 0x2b17: // Character disconnected set online 0 [Wizputer]
+ if (RFIFOREST(fd) < 6)
return 0;
- //printf("Setting %d char offline\n",RFIFOL(fd,2));
set_char_offline(RFIFOL(fd,2),RFIFOL(fd,6));
RFIFOSKIP(fd,10);
break;
- // Reset all chars to offline [Wizputer]
- case 0x2b18:
+
+ case 0x2b18: // Reset all chars to offline [Wizputer]
set_all_offline(id);
RFIFOSKIP(fd,2);
break;
- // Character set online [Wizputer]
- case 0x2b19:
- if (RFIFOREST(fd) < 6 )
+
+ case 0x2b19: // Character set online [Wizputer]
+ if (RFIFOREST(fd) < 6)
return 0;
set_char_online(id, RFIFOL(fd,2),RFIFOL(fd,6));
RFIFOSKIP(fd,10);
break;
- // Build and send fame ranking lists [DracoRPG]
- case 0x2b1a:
+ case 0x2b1a: // Build and send fame ranking lists [DracoRPG]
if (RFIFOREST(fd) < 2)
return 0;
char_read_fame_list();
@@ -3055,8 +3041,7 @@ int parse_frommap(int fd) {
RFIFOSKIP(fd,2);
break;
- //Request saving sc_data of a player. [Skotlex]
- case 0x2b1c:
+ case 0x2b1c: //Request saving sc_data of a player. [Skotlex]
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
{
@@ -3090,12 +3075,10 @@ int parse_frommap(int fd) {
break;
}
- case 0x2736:
+ case 0x2736: // ip address update
if (RFIFOREST(fd) < 6) return 0;
- ShowInfo("Updated IP address of Server #%d to %d.%d.%d.%d.\n",id,
- (int)RFIFOB(fd,2),(int)RFIFOB(fd,3),
- (int)RFIFOB(fd,4),(int)RFIFOB(fd,5));
- server[id].ip = RFIFOL(fd, 2);
+ server[id].ip = ntohl(RFIFOL(fd, 2));
+ ShowInfo("Updated IP address of map-server #%d to %d.%d.%d.%d.\n", id, CONVIP(server[id].ip));
RFIFOSKIP(fd,6);
break;
@@ -3116,19 +3099,17 @@ int parse_frommap(int fd) {
return 0;
}
-int search_mapserver(unsigned short map, long ip, short port) {
+int search_mapserver(unsigned short map, uint32 ip, uint16 port)
+{
int i, j;
- if (!map)
- return -1;
-
for(i = 0; i < MAX_MAP_SERVERS; i++)
if (server_fd[i] > 0)
for (j = 0; server[i].map[j]; j++)
if (server[i].map[j] == map) {
- if (ip > 0 && server[i].ip != ip)
+ if (ip != (uint32)-1 && server[i].ip != ip)
continue;
- if (port > 0 && server[i].port != port)
+ if (port != (uint16)-1 && server[i].port != port)
continue;
return i;
}
@@ -3142,48 +3123,43 @@ int char_mapif_init(int fd) {
//--------------------------------------------
// Test to know if an IP come from LAN or WAN.
-// Rewrote: Adnvanced subnet check [LuzZza]
//--------------------------------------------
-int lan_subnetcheck(long *p) {
-
+int lan_subnetcheck(uint32 ip)
+{
int i;
- unsigned char *sbn, *msk, *src = (unsigned char *)p;
- for(i=0; i<subnet_count; i++) {
+ for(i = 0; i < subnet_count; i++) {
- if((subnet[i].subnet & subnet[i].mask) == (*p & subnet[i].mask)) {
-
- sbn = (unsigned char *)&subnet[i].subnet;
- msk = (unsigned char *)&subnet[i].mask;
+ if((subnet[i].subnet & subnet[i].mask) == (ip & subnet[i].mask)) {
ShowInfo("Subnet check [%u.%u.%u.%u]: Matches "CL_CYAN"%u.%u.%u.%u/%u.%u.%u.%u"CL_RESET"\n",
- src[0], src[1], src[2], src[3], sbn[0], sbn[1], sbn[2], sbn[3], msk[0], msk[1], msk[2], msk[3]);
+ CONVIP(ip), CONVIP(subnet[i].subnet), CONVIP(subnet[i].mask));
return subnet[i].map_ip;
}
}
- ShowInfo("Subnet check [%u.%u.%u.%u]: "CL_CYAN"WAN"CL_RESET"\n", src[0], src[1], src[2], src[3]);
+ ShowInfo("Subnet check [%u.%u.%u.%u]: "CL_CYAN"WAN"CL_RESET"\n", CONVIP(ip));
return 0;
}
-int parse_char(int fd) {
-
+int parse_char(int fd)
+{
int i, ch = 0;
char email[40];
unsigned char buf[64];
unsigned short cmd;
int map_fd;
struct char_session_data *sd;
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
- long subnet_map_ip;
+ uint32 ipl = session[fd]->client_addr;
+ uint32 subnet_map_ip;
RFIFOHEAD(fd);
sd = (struct char_session_data*)session[fd]->session_data;
if(login_fd < 0)
session[fd]->eof = 1;
- if(session[fd]->eof) {
+ if(session[fd]->eof) { // disconnect any player (already connected to char-server or coming back from map-server) if login-server is diconnected.
if (fd == login_fd)
login_fd = -1;
if (sd != NULL)
@@ -3198,7 +3174,7 @@ int parse_char(int fd) {
return 0;
}
- while(RFIFOREST(fd) >= 2 && !session[fd]->eof) {
+ while(RFIFOREST(fd) >= 2) {
cmd = RFIFOW(fd,0);
// crc32のスキップ用
if( sd==NULL && // 未ログインor管理パケット
@@ -3239,27 +3215,26 @@ int parse_char(int fd) {
CREATE(session[fd]->session_data, struct char_session_data, 1);
sd = (struct char_session_data*)session[fd]->session_data;
sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
- sd->account_id = RFIFOL(fd, 2);
- sd->login_id1 = RFIFOL(fd, 6);
- sd->login_id2 = RFIFOL(fd, 10);
- sd->sex = RFIFOB(fd, 16);
-
- WFIFOL(fd, 0) = RFIFOL(fd, 2);
- WFIFOSET(fd, 4);
-
- for(i = 0;
- i < AUTH_FIFO_SIZE && !(
+ sd->account_id = RFIFOL(fd,2);
+ sd->login_id1 = RFIFOL(fd,6);
+ sd->login_id2 = RFIFOL(fd,10);
+ sd->sex = RFIFOB(fd,16);
+ // send back account_id
+ WFIFOL(fd,0) = RFIFOL(fd,2);
+ WFIFOSET(fd,4);
+ // search authentification
+ for(i = 0; i < AUTH_FIFO_SIZE && !(
auth_fifo[i].account_id == sd->account_id &&
auth_fifo[i].login_id1 == sd->login_id1 &&
auth_fifo[i].login_id2 == sd->login_id2 && // relate to the versions higher than 18
- auth_fifo[i].ip == session[fd]->client_addr.sin_addr.s_addr &&
+ auth_fifo[i].ip == session[fd]->client_addr &&
auth_fifo[i].delflag == 2)
; i++);
if (i < AUTH_FIFO_SIZE) {
auth_fifo[i].delflag = 1;
char_auth_ok(fd, sd);
- } else {
+ } else { // authentication not found
if (login_fd > 0) { // don't send request if no login-server
WFIFOHEAD(login_fd,19);
WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
@@ -3267,7 +3242,7 @@ int parse_char(int fd) {
WFIFOL(login_fd,6) = sd->login_id1;
WFIFOL(login_fd,10) = sd->login_id2;
WFIFOB(login_fd,14) = sd->sex;
- WFIFOL(login_fd,15) = session[fd]->client_addr.sin_addr.s_addr;
+ WFIFOL(login_fd,15) = htonl(session[fd]->client_addr);
WFIFOSET(login_fd,19);
} else { // if no login-server, we must refuse connection
WFIFOHEAD(fd,3);
@@ -3315,7 +3290,8 @@ int parse_char(int fd) {
}
}
ShowInfo("Selected char: (Account %d: %d - %s)" RETCODE, sd->account_id, RFIFOB(fd, 2), char_dat.name);
-
+
+ // searching map server
i = search_mapserver(char_dat.last_point.map, -1, -1);
// if map is not found, we check major cities
@@ -3362,45 +3338,50 @@ int parse_char(int fd) {
ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(char_dat.last_point.map), mapindex_id2name(j));
char_dat.last_point.map = j;
}
- { //Send player to map.
+ {
+ //Send player to map.
char map_name[MAP_NAME_LENGTH];
- snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(char_dat.last_point.map));
+ snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(char_dat.last_point.map));
+
WFIFOHEAD(fd,28);
- WFIFOW(fd, 0) =0x71;
- WFIFOL(fd, 2) =char_dat.char_id;
+ WFIFOW(fd,0) = 0x71;
+ WFIFOL(fd,2) = char_dat.char_id;
memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH);
// Advanced subnet check [LuzZza]
- if((subnet_map_ip = lan_subnetcheck((long *)p)))
- WFIFOL(fd,22) = subnet_map_ip;
+ if(subnet_map_ip = lan_subnetcheck(ipl))
+ WFIFOL(fd,22) = htonl(subnet_map_ip);
else
- WFIFOL(fd,22) = server[i].ip;
+ WFIFOL(fd,22) = htonl(server[i].ip);
- WFIFOW(fd,26) = server[i].port;
+ WFIFOW(fd,26) = server[i].port; // /!\ must be sent in intel host byte order /!\ (client bug)
WFIFOSET(fd,28);
}
- if (auth_fifo_pos >= AUTH_FIFO_SIZE) {
+ if (auth_fifo_pos >= AUTH_FIFO_SIZE)
auth_fifo_pos = 0;
- }
auth_fifo[auth_fifo_pos].account_id = sd->account_id;
auth_fifo[auth_fifo_pos].char_id = char_dat.char_id;
auth_fifo[auth_fifo_pos].login_id1 = sd->login_id1;
auth_fifo[auth_fifo_pos].login_id2 = sd->login_id2;
auth_fifo[auth_fifo_pos].delflag = 0;
- auth_fifo[auth_fifo_pos].char_pos = 0;
auth_fifo[auth_fifo_pos].sex = sd->sex;
auth_fifo[auth_fifo_pos].connect_until_time = sd->connect_until_time;
- auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
+ 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)
{
+ WFIFOHEAD(fd, 3);
ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i);
server_fd[i] = -1;
memset(&server[i], 0, sizeof(struct mmo_map_server));
+ //Send server closed.
+ WFIFOW(fd,0) = 0x81;
+ WFIFOB(fd,2) = 1; // 01 = Server closed
+ WFIFOSET(fd,3);
break;
}
- { //Send auth ok to map server
+ { //Send auth ok to map server
WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus));
WFIFOW(map_fd,0) = 0x2afd;
WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus);
@@ -3422,10 +3403,9 @@ int parse_char(int fd) {
if(char_new == 0) //turn character creation on/off [Kevin]
i = -2;
else
- i = make_new_char_sql(fd, RFIFOP(fd, 2));
+ i = make_new_char_sql(fd, RFIFOP(fd,2));
- //'Charname already exists' (-1), 'Char creation denied' (-2)
- //And 'You are underaged' (-3) (XD) [Sirius]
+ //'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3)
if (i < 0)
{
WFIFOHEAD(fd, 3);
@@ -3439,15 +3419,15 @@ int parse_char(int fd) {
RFIFOSKIP(fd, 37);
break;
}
- { //Send data.
+ { //Send to player.
int len;
WFIFOHEAD(fd, 110);
- WFIFOW(fd, 0) = 0x6d;
+ WFIFOW(fd,0) = 0x6d;
mmo_char_fromsql_short(i, &char_dat); //Only the short data is needed.
len = 2 + mmo_char_tobuf(WFIFOP(fd,2), &char_dat);
- WFIFOSET(fd, len);
+ WFIFOSET(fd,len);
- RFIFOSKIP(fd, 37);
+ RFIFOSKIP(fd,37);
}
//to do
for(ch = 0; ch < MAX_CHARS; ch++) {
@@ -3457,7 +3437,8 @@ int parse_char(int fd) {
}
}
break;
- case 0x68: /* delete char */
+
+ case 0x68: // delete char
FIFOSD_CHECK(46);
{
int cid = RFIFOL(fd,2);
@@ -3466,14 +3447,14 @@ int parse_char(int fd) {
memcpy(email, RFIFOP(fd,6), 40);
RFIFOSKIP(fd, 46);
- /* Check if e-mail is correct */
+ // Check if e-mail is correct
if(strcmpi(email, sd->email) && //email does not matches and
(
strcmp("a@a.com", sd->email) || //it is not default email, or
(strcmp("a@a.com", email) && strcmp("", email)) //email sent does not matches default
)) { //Fail
WFIFOW(fd, 0) = 0x70;
- WFIFOB(fd, 2) = 0;
+ WFIFOB(fd, 2) = 0; // 00 = Incorrect Email address
WFIFOSET(fd, 3);
break;
}
@@ -3486,12 +3467,10 @@ int parse_char(int fd) {
break;
}
}
- /* Such a character does not exist in the account */
- /* If so, you are so screwed. */
- if (i == MAX_CHARS) {
- WFIFOW(fd, 0) = 0x70;
- WFIFOB(fd, 2) = 0;
- WFIFOSET(fd, 3);
+ if (i == MAX_CHARS) { // Such a character does not exist in the account
+ WFIFOW(fd,0) = 0x70;
+ WFIFOB(fd,2) = 0;
+ WFIFOSET(fd,3);
break;
}
@@ -3532,40 +3511,42 @@ int parse_char(int fd) {
}
}
/* Char successfully deleted.*/
- WFIFOW(fd, 0) = 0x6f;
- WFIFOSET(fd, 2);
+ WFIFOW(fd,0) = 0x6f;
+ WFIFOSET(fd,2);
break;
}
+
case 0x2af8: // login as map-server
if (RFIFOREST(fd) < 60)
return 0;
{
- char *l_userid = RFIFOP(fd,2);
- char *l_password = RFIFOP(fd,26);
+ char *l_user = RFIFOP(fd,2);
+ char *l_pass = RFIFOP(fd,26);
WFIFOHEAD(fd, 4+5*GM_num);
-
- l_userid[23] = '\0';
- l_password[23] = '\0';
- WFIFOW(fd, 0) = 0x2af9;
+ l_user[23] = '\0';
+ l_pass[23] = '\0';
+ WFIFOW(fd,0) = 0x2af9;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
if (server_fd[i] <= 0)
break;
}
if (i == MAX_MAP_SERVERS ||
- strcmp(l_userid, userid) ||
- strcmp(l_password, passwd)) {
+ strcmp(l_user, userid) ||
+ strcmp(l_pass, passwd)) {
WFIFOB(fd,2) = 3;
- WFIFOSET(fd, 3);
+ WFIFOSET(fd,3);
+ RFIFOSKIP(fd,60);
} else {
int len;
WFIFOB(fd,2) = 0;
- WFIFOSET(fd, 3);
+ WFIFOSET(fd,3);
session[fd]->func_parse = parse_frommap;
server_fd[i] = fd;
- server[i].ip = RFIFOL(fd, 54);
- server[i].port = RFIFOW(fd, 58);
+ server[i].ip = ntohl(RFIFOL(fd, 54));
+ server[i].port = ntohs(RFIFOW(fd, 58));
server[i].users = 0;
memset(server[i].map, 0, sizeof(server[i].map));
+ RFIFOSKIP(fd,60);
realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
char_mapif_init(fd);
// send gm acccounts level to map-servers
@@ -3579,29 +3560,28 @@ int parse_char(int fd) {
WFIFOW(fd,2) = len;
WFIFOSET(fd,len);
}
- RFIFOSKIP(fd,60);
break;
}
+
case 0x187: // Alive?
- if (RFIFOREST(fd) < 6) {
+ if (RFIFOREST(fd) < 6)
return 0;
- }
RFIFOSKIP(fd, 6);
break;
case 0x7530: // Athena info get
{
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_INTER | ATHENA_SERVER_CHAR;
- WFIFOW(fd, 8) = ATHENA_MOD_VERSION;
- WFIFOSET(fd, 10);
- RFIFOSKIP(fd, 2);
+ 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_INTER | ATHENA_SERVER_CHAR;
+ WFIFOW(fd,8) = ATHENA_MOD_VERSION;
+ WFIFOSET(fd,10);
+ RFIFOSKIP(fd,2);
return 0;
}
case 0x7532: // disconnect(default also disconnect)
@@ -3611,7 +3591,6 @@ int parse_char(int fd) {
}
}
RFIFOFLUSH(fd);
-
return 0;
}
@@ -3648,21 +3627,12 @@ int parse_console(char* buf)
// MAP send all
int mapif_sendall(unsigned char *buf, unsigned int len) {
int i, c;
- int fd;
c = 0;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
- if ((fd = server_fd[i]) > 0) { //0 Should not be a valid server_fd [Skotlex]
+ int fd;
+ if ((fd = server_fd[i]) > 0) {
WFIFOHEAD(fd,len);
-#if 0 //This seems to have been fixed long long ago.
- if (session[fd] == NULL)
- { //Could this be the crash's source? [Skotlex]
- ShowError("mapif_sendall: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", fd, i);
- server_fd[i] = -1;
- memset(&server[i], 0, sizeof(struct mmo_map_server));
- continue;
- }
-#endif
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
c++;
@@ -3674,10 +3644,10 @@ int mapif_sendall(unsigned char *buf, unsigned int len) {
int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
int i, c;
- int fd;
c = 0;
- for(i=0, c=0;i<MAX_MAP_SERVERS;i++){
+ for(i = 0; i < MAX_MAP_SERVERS; i++) {
+ int fd;
if ((fd = server_fd[i]) > 0 && fd != sfd) {
WFIFOHEAD(fd, len);
memcpy(WFIFOP(fd,0), buf, len);
@@ -3773,15 +3743,15 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) {
memcpy(WFIFOP(login_fd,2), userid, 24);
memcpy(WFIFOP(login_fd,26), passwd, 24);
WFIFOL(login_fd,50) = 0;
- WFIFOL(login_fd,54) = char_ip;
- WFIFOL(login_fd,58) = char_port;
+ WFIFOL(login_fd,54) = htonl(char_ip);
+ WFIFOL(login_fd,58) = htons(char_port);
memcpy(WFIFOP(login_fd,60), server_name, 20);
WFIFOW(login_fd,80) = 0;
WFIFOW(login_fd,82) = char_maintenance;
WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin]
WFIFOSET(login_fd,86);
}
- return 0;
+ return 1;
}
//------------------------------------------------
@@ -3849,9 +3819,9 @@ int char_lan_config_read(const char *lancfgName) {
if(strcmpi(w1, "subnet") == 0) {
- subnet[subnet_count].mask = inet_addr(w2);
- subnet[subnet_count].char_ip = inet_addr(w3);
- subnet[subnet_count].map_ip = inet_addr(w4);
+ subnet[subnet_count].mask = ntohl(inet_addr(w2));
+ subnet[subnet_count].char_ip = ntohl(inet_addr(w3));
+ subnet[subnet_count].map_ip = ntohl(inet_addr(w4));
subnet[subnet_count].subnet = subnet[subnet_count].char_ip&subnet[subnet_count].mask;
if (subnet[subnet_count].subnet != (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);
@@ -3867,57 +3837,8 @@ int char_lan_config_read(const char *lancfgName) {
fclose(fp);
return 0;
}
-
-void do_final(void) {
- ShowInfo("Doing final stage...\n");
- //inter_save();
- do_final_itemdb();
- //check SQL save progress.
- //wait until save char complete
-
- set_all_offline(-1);
- set_all_offline_sql();
-
- inter_final();
-
- flush_fifos();
-
- mapindex_final();
-
- sprintf(tmp_sql,"DELETE FROM `ragsrvinfo");
- if (mysql_query(&mysql_handle, tmp_sql))
- {
- ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
- ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
- }
-
- if(gm_account) {
- aFree(gm_account);
- gm_account = 0;
- }
-
- if (login_fd > 0)
- do_close(login_fd);
- if (char_fd > 0)
- do_close(char_fd);
- char_db_->destroy(char_db_, NULL);
- online_char_db->destroy(online_char_db, NULL);
-
- mysql_close(&mysql_handle);
- if(char_gm_read)
- mysql_close(&lmysql_handle);
-
- ShowInfo("ok! all done...\n");
-}
-
-//------------------------------
-// Function called when the server
-// has received a crash signal.
-//------------------------------
-void do_abort(void) {
-}
-
#endif //TXT_SQL_CONVERT
+
void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
char line[1024], w1[1024], w2[1024];
FILE *fp;
@@ -4020,25 +3941,25 @@ void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
int char_config_read(const char *cfgName) {
char line[1024], w1[1024], w2[1024];
- FILE *fp;
+ FILE* fp = fopen(cfgName, "r");
- if ((fp = fopen(cfgName, "r")) == NULL) {
+ if (fp == NULL) {
ShowFatalError("Configuration file not found: %s.\n", cfgName);
exit(1);
}
- ShowInfo("Reading file %s...\n", cfgName);
+ ShowInfo("Reading configuration file %s...\n", cfgName);
while(fgets(line, sizeof(line)-1, fp)) {
if (line[0] == '/' && line[1] == '/')
continue;
line[sizeof(line)-1] = '\0';
- if (sscanf(line,"%[^:]: %[^\r\n]", w1, w2) != 2)
+ if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2)
continue;
- remove_control_chars((unsigned char *) w1);
- remove_control_chars((unsigned char *) w2);
- if(strcmpi(w1,"timestamp_format")==0) {
+ remove_control_chars((unsigned char *)w1);
+ remove_control_chars((unsigned char *)w2);
+ if(strcmpi(w1,"timestamp_format") == 0) {
strncpy(timestamp_format, w2, 20);
} else if(strcmpi(w1,"console_silent")==0){
ShowInfo("Console Silent Setting: %d\n", atoi(w2));
@@ -4066,7 +3987,7 @@ int char_config_read(const char *cfgName) {
ShowStatus("Login server IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str));
}
} else if (strcmpi(w1, "login_port") == 0) {
- login_port=atoi(w2);
+ login_port = atoi(w2);
} else if (strcmpi(w1, "char_ip") == 0) {
char ip_str[16];
char_ip = host2ip(w2);
@@ -4108,7 +4029,7 @@ int char_config_read(const char *cfgName) {
} else if (strcmpi(w1, "start_point") == 0) {
char map[MAP_NAME_LENGTH];
int x, y;
- if (sscanf(w2,"%16[^,],%d,%d", map, &x, &y) < 3)
+ if (sscanf(w2, "%16[^,],%d,%d", map, &x, &y) < 3)
continue;
if (strstr(map, ".gat") != NULL) { // Verify at least if '.gat' is in the map name
start_point.map = mapindex_name2id(map);
@@ -4129,11 +4050,11 @@ int char_config_read(const char *cfgName) {
start_armor = atoi(w2);
if (start_armor < 0)
start_armor = 0;
- } else if(strcmpi(w1,"log_char")==0){ //log char or not [devil]
+ } else if(strcmpi(w1,"log_char")==0) { //log char or not [devil]
log_char = atoi(w2);
} else if (strcmpi(w1, "unknown_char_name") == 0) {
strcpy(unknown_char_name, w2);
- unknown_char_name[NAME_LENGTH-1] = 0;
+ unknown_char_name[NAME_LENGTH-1] = '\0';
} else if (strcmpi(w1, "name_ignoring_case") == 0) {
name_ignoring_case = config_switch(w2);
} else if (strcmpi(w1, "char_name_option") == 0) {
@@ -4174,10 +4095,58 @@ int char_config_read(const char *cfgName) {
fclose(fp);
ShowInfo("Done reading %s.\n", cfgName);
-
return 0;
}
+void do_final(void) {
+ ShowInfo("Doing final stage...\n");
+ //inter_save();
+ do_final_itemdb();
+ //check SQL save progress.
+ //wait until save char complete
+
+ set_all_offline(-1);
+ set_all_offline_sql();
+
+ inter_final();
+
+ flush_fifos();
+
+ mapindex_final();
+
+ sprintf(tmp_sql,"DELETE FROM `ragsrvinfo");
+ if (mysql_query(&mysql_handle, tmp_sql))
+ {
+ ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
+ ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+ }
+
+ if(gm_account) {
+ aFree(gm_account);
+ gm_account = 0;
+ }
+
+ if (login_fd > 0)
+ do_close(login_fd);
+ if (char_fd > 0)
+ do_close(char_fd);
+ char_db_->destroy(char_db_, NULL);
+ online_char_db->destroy(online_char_db, NULL);
+
+ mysql_close(&mysql_handle);
+ if(char_gm_read)
+ mysql_close(&lmysql_handle);
+
+ ShowInfo("ok! all done...\n");
+}
+
+//------------------------------
+// Function called when the server
+// has received a crash signal.
+//------------------------------
+void do_abort(void) {
+}
+
void set_server_type(void)
{
SERVER_TYPE = ATHENA_SERVER_CHAR;
@@ -4200,7 +4169,8 @@ static int online_data_cleanup(int tid, unsigned int tick, int id, int data)
return 0;
}
-int do_init(int argc, char **argv){
+int do_init(int argc, char **argv)
+{
int i;
for(i = 0; i < MAX_MAP_SERVERS; i++) {
@@ -4240,29 +4210,27 @@ int do_init(int argc, char **argv){
// ShowDebug("set terminate function -> do_final().....\n");
- if ((naddr_ != 0) && (!login_ip || !char_ip)) {
- // The char server should know what IP address it is running on
- // - MouseJstr
- int localaddr = ntohl(addr_[0]);
- unsigned char *ptr = (unsigned char *) &localaddr;
- char buf[16];
- sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);
- if (naddr_ != 1)
- ShowStatus("Multiple interfaces detected.. using %s as our IP address\n", buf);
- else
- ShowStatus("Defaulting to %s as our IP address\n", buf);
- if (!login_ip) {
- strcpy(login_ip_str, buf);
- login_ip = inet_addr(login_ip_str);
- }
- if (!char_ip) {
- strcpy(char_ip_str, buf);
- char_ip = inet_addr(char_ip_str);
- }
- }
+ if ((naddr_ != 0) && (!login_ip || !char_ip))
+ {
+ char ip_str[16];
+ ip2str(addr_[0], ip_str);
+
+ if (naddr_ > 1)
+ ShowStatus("Multiple interfaces detected.. using %s as our IP address\n", ip_str);
+ else
+ ShowStatus("Defaulting to %s as our IP address\n", ip_str);
+ if (!login_ip) {
+ strcpy(login_ip_str, ip_str);
+ login_ip = inet_addr(login_ip_str);
+ }
+ if (!char_ip) {
+ strcpy(char_ip_str, ip_str);
+ char_ip = inet_addr(char_ip_str);
+ }
+ }
ShowInfo("open port %d.....\n",char_port);
- char_fd = make_listen_bind(bind_ip?bind_ip:INADDR_ANY,char_port);
+ char_fd = make_listen_bind(bind_ip, char_port);
add_timer_func_list(check_connect_login_server, "check_connect_login_server");
add_timer_func_list(send_users_tologin, "send_users_tologin");
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 03c3d7484..f07876115 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -215,8 +215,8 @@ struct mmo_charstatus {
short str,agi,vit,int_,dex,luk;
unsigned char char_num,sex;
- unsigned long mapip;
- unsigned int mapport;
+ uint32 mapip;
+ uint16 mapport;
struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
struct item inventory[MAX_INVENTORY],cart[MAX_CART];
diff --git a/src/common/socket.c b/src/common/socket.c
index f7b5ebc2f..b2c9810b4 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -242,7 +242,7 @@ int connect_client(int listen_fd)
len = sizeof(client_address);
- fd = accept(listen_fd,(struct sockaddr*)&client_address,&len);
+ fd = accept(listen_fd, (struct sockaddr*)&client_address, &len);
if ( fd == INVALID_SOCKET ) {
ShowError("accept failed (code %i)!\n", s_errno);
return -1;
@@ -258,7 +258,7 @@ int connect_client(int listen_fd)
set_nonblocking(fd, 1);
#ifndef MINICORE
- if( ip_rules && !connect_check(*(uint32*)(&client_address.sin_addr)) ){
+ if( ip_rules && !connect_check(ntohl(client_address.sin_addr.s_addr)) ) {
do_close(fd);
return -1;
}
@@ -270,13 +270,13 @@ int connect_client(int listen_fd)
fd_max = fd + 1;
create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
- session[fd]->client_addr = client_address;
+ session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr);
session[fd]->rdata_tick = last_tick;
return fd;
}
-int make_listen_bind(long ip,int port)
+int make_listen_bind(uint32 ip, uint16 port)
{
struct sockaddr_in server_address;
int fd;
@@ -293,8 +293,8 @@ int make_listen_bind(long ip,int port)
set_nonblocking(fd, 1);
server_address.sin_family = AF_INET;
- server_address.sin_addr.s_addr = ip;
- server_address.sin_port = htons((unsigned short)port);
+ server_address.sin_addr.s_addr = htonl(ip);
+ server_address.sin_port = htons(port);
result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
if( result == SOCKET_ERROR ) {
@@ -320,7 +320,7 @@ int make_listen_bind(long ip,int port)
return fd;
}
-int make_connection(long ip, int port)
+int make_connection(uint32 ip, uint16 port)
{
struct sockaddr_in server_address;
int fd;
@@ -335,12 +335,11 @@ int make_connection(long ip, int port)
setsocketopts(fd);
- server_address.sin_family = AF_INET;
- server_address.sin_addr.s_addr = ip;
- server_address.sin_port = htons((unsigned short)port);
+ server_address.sin_family = AF_INET;
+ server_address.sin_addr.s_addr = htonl(ip);
+ server_address.sin_port = htons(port);
- ShowStatus("Connecting to %d.%d.%d.%d:%i\n",
- (ip)&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,(ip>>24)&0xFF,port);
+ ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port);
result = connect(fd, (struct sockaddr *)(&server_address), sizeof(struct sockaddr_in));
if( result == SOCKET_ERROR ) {
@@ -389,7 +388,7 @@ int delete_session(int fd)
return 0;
}
-int realloc_fifo(int fd,unsigned int rfifo_size,unsigned int wfifo_size)
+int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
{
if( !session_isValid(fd) )
return 0;
@@ -421,7 +420,7 @@ int realloc_writefifo(int fd, size_t addition)
else if( session[fd]->max_wdata >= FIFOSIZE_SERVERLINK) {
//Inter-server adjust. [Skotlex]
if ((session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata)
- newsize = session[fd]->max_wdata/2;
+ newsize = session[fd]->max_wdata / 2;
else
return 0; //No change
} else if( session[fd]->max_wdata > wfifo_size && (session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata )
@@ -437,7 +436,7 @@ int realloc_writefifo(int fd, size_t addition)
return 0;
}
-int RFIFOSKIP(int fd,int len)
+int RFIFOSKIP(int fd, int len)
{
struct socket_data *s;
@@ -468,11 +467,10 @@ int WFIFOSET(int fd, int len)
// we have written len bytes to the buffer already before calling WFIFOSET
if(s->wdata_size+len > s->max_wdata)
{ // actually there was a buffer overflow already
- unsigned char *sin_addr = (unsigned char *)&s->client_addr.sin_addr;
- ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n", fd,
- sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3], len, s->wdata_size, s->max_wdata);
- ShowDebug("Likely command that caused it: 0x%x\n",
- (*(unsigned short*)(s->wdata + s->wdata_size)));
+ uint32 ip = s->client_addr;
+ ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n",
+ fd, CONVIP(ip), len, s->wdata_size, s->max_wdata);
+ ShowDebug("Likely command that caused it: 0x%x\n", (*(unsigned short*)(s->wdata + s->wdata_size)));
// no other chance, make a better fifo model
exit(1);
}
@@ -645,15 +643,13 @@ static int access_order = ACO_DENY_ALLOW;
static int access_allownum = 0;
static int access_denynum = 0;
static int access_debug = 0;
-static int ddos_count = 10;
-static int ddos_interval = 3*1000;
-static int ddos_autoreset = 10*60*1000;
+static int ddos_count = 10;
+static int ddos_interval = 3*1000;
+static int ddos_autoreset = 10*60*1000;
/// Connection history, an array of linked lists.
/// The array's index for any ip is ip&0xFFFF
static ConnectHistory* connect_history[0x10000];
-#define CONVIP(ip) ip&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,ip>>24
-
static int connect_check_(uint32 ip);
/// Verifies if the IP can connect. (with debug info)
@@ -816,7 +812,7 @@ int access_ipmask(const char* str, AccessControl* acc)
unsigned int m[4];
int n;
- if( strcmp(str,"all") == 0 ){
+ if( strcmp(str,"all") == 0 ) {
ip = 0;
mask = 0;
} else {
@@ -856,7 +852,7 @@ int access_ipmask(const char* str, AccessControl* acc)
#endif
//////////////////////////////
-int socket_config_read(const char *cfgName)
+int socket_config_read(const char* cfgName)
{
char line[1024],w1[1024],w2[1024];
FILE *fp;
@@ -960,7 +956,7 @@ void do_close(int fd)
/// Retrieve local ips in host byte order.
/// Uses loopback is no address is found.
-int socket_getips(uint32 *ips, int max)
+int socket_getips(uint32* ips, int max)
{
int num = 0;
@@ -986,7 +982,7 @@ int socket_getips(uint32 *ips, int max)
{
hent = gethostbyname(fullhost);
if( hent == NULL ){
- ShowError("socket_getips: Cannot resolve our own hostname to a IP address\n");
+ ShowError("socket_getips: Cannot resolve our own hostname to an IP address\n");
return 0;
}
a = (u_long**)hent->h_addr_list;
@@ -1099,16 +1095,18 @@ int session_isActive(int fd)
return ( session_isValid(fd) && !session[fd]->eof );
}
-
-in_addr_t host2ip(const char* hostname)
+// Resolves hostname into a numeric ip.
+uint32 host2ip(const char* hostname)
{
struct hostent* h = gethostbyname(hostname);
- return (h != NULL) ? *(in_addr_t*)h->h_addr : 0;
+ return (h != NULL) ? ntohl(*(uint32*)h->h_addr) : 0;
}
-const char* ip2str(in_addr_t ip, char ip_str[16])
+// Converts a numeric ip into a dot-formatted string.
+// Result is placed either into a user-provided buffer or a static system buffer.
+const char* ip2str(uint32 ip, char ip_str[16])
{
- in_addr_t addr = ntohl(ip);
- sprintf(ip_str, "%d.%d.%d.%d", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF);
- return ip_str;
+ struct in_addr addr;
+ addr.s_addr = htonl(ip);
+ return (ip_str == NULL) ? inet_ntoa(addr) : strncpy(ip_str, inet_ntoa(addr), 16);
}
diff --git a/src/common/socket.h b/src/common/socket.h
index b7b8ce839..ba984eb3a 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -81,7 +81,7 @@ struct socket_data {
size_t rdata_size, wdata_size;
size_t rdata_pos;
time_t rdata_tick; // time of last receive (for detecting timeouts)
- struct sockaddr_in client_addr; // remote client address (zero for s2s connections)
+ uint32 client_addr; // remote client address (zero for s2s connections)
void* session_data;
RecvFunc func_recv;
SendFunc func_send;
@@ -106,12 +106,12 @@ extern int session_isActive(int fd);
// Function prototype declaration
-int make_listen_bind(long,int);
-int make_connection(long,int);
-int realloc_fifo(int fd,unsigned int rfifo_size,unsigned int wfifo_size);
+int make_listen_bind(uint32 ip, uint16 port);
+int make_connection(uint32 ip, uint16 port);
+int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size);
int realloc_writefifo(int fd, size_t addition);
-int WFIFOSET(int fd,int len);
-int RFIFOSKIP(int fd,int len);
+int WFIFOSET(int fd, int len);
+int RFIFOSKIP(int fd, int len);
int do_sendrecv(int next);
int do_parsepacket(void);
@@ -126,9 +126,9 @@ extern void set_nonblocking(int fd, int yes);
void set_defaultparse(ParseFunc defaultparse);
// hostname/ip conversion functions
-in_addr_t host2ip(const char* hostname);
-const char* ip2str(in_addr_t ip, char ip_str[16]);
-
+uint32 host2ip(const char* hostname);
+const char* ip2str(uint32 ip, char ip_str[16]);
+#define CONVIP(ip) (ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,(ip>>0)&0xFF
int socket_getips(uint32* ips, int max);
diff --git a/src/common/strlib.c b/src/common/strlib.c
index 9d79e2745..327b2daf1 100644
--- a/src/common/strlib.c
+++ b/src/common/strlib.c
@@ -11,12 +11,15 @@
#include "../common/utils.h"
#include "../common/malloc.h"
-//-----------------------------------------------
-// string lib.
-char* jstrescape (char* pt) {
+
+#define J_MAX_MALLOC_SIZE 65535
+
+// escapes a string in-place (' -> \' , \ -> \\ , % -> _)
+char* jstrescape (char* pt)
+{
//copy from here
char *ptr;
- int i =0, j=0;
+ int i = 0, j = 0;
//copy string to temporary
CREATE(ptr, char, J_MAX_MALLOC_SIZE);
@@ -41,10 +44,12 @@ char* jstrescape (char* pt) {
}
pt[j++] = '\0';
aFree(ptr);
- return &pt[0];
+ return pt;
}
-char* jstrescapecpy (char* pt, const char* spt) {
+// escapes a string into a provided buffer
+char* jstrescapecpy (char* pt, const char* spt)
+{
//copy from here
//WARNING: Target string pt should be able to hold strlen(spt)*2, as each time
//a escape character is found, the target's final length increases! [Skotlex]
@@ -75,7 +80,10 @@ char* jstrescapecpy (char* pt, const char* spt) {
pt[j++] = '\0';
return &pt[0];
}
-int jmemescapecpy (char* pt,char* spt, int size) {
+
+// escapes exactly 'size' bytes of a string into a provided buffer
+int jmemescapecpy (char* pt, const char* spt, int size)
+{
//copy from here
int i =0, j=0;
@@ -100,11 +108,9 @@ int jmemescapecpy (char* pt,char* spt, int size) {
return j;
}
-//-----------------------------------------------------
// Function to suppress control characters in a string.
-//-----------------------------------------------------
-//int remove_control_chars(char *str) {
-int remove_control_chars(unsigned char *str) {
+int remove_control_chars(char* str)
+{
int i;
int change = 0;
@@ -119,11 +125,11 @@ int remove_control_chars(unsigned char *str) {
}
//Trims a string, also removes illegal characters such as \t and reduces continous spaces to a single one. by [Foruken]
-char *trim(char *str, const char *delim)
+char* trim(char* str, const char* delim)
{
- char *strp = strtok(str,delim);
+ char* strp = strtok(str,delim);
char buf[1024];
- char *bufp = buf;
+ char* bufp = buf;
memset(buf,0,sizeof buf);
while(strp) {
@@ -143,7 +149,7 @@ char *trim(char *str, const char *delim)
//stristr: Case insensitive version of strstr, code taken from
//http://www.daniweb.com/code/snippet313.html, Dave Sinkula
//
-const char *stristr(const char *haystack, const char *needle)
+const char* stristr(const char* haystack, const char* needle)
{
if ( !*needle )
{
@@ -153,9 +159,7 @@ const char *stristr(const char *haystack, const char *needle)
{
if ( TOUPPER(*haystack) == TOUPPER(*needle) )
{
- /*
- * Matched starting char -- loop through remaining chars.
- */
+ // matched starting char -- loop through remaining chars
const char *h, *n;
for ( h = haystack, n = needle; *h && *n; ++h, ++n )
{
@@ -164,9 +168,9 @@ const char *stristr(const char *haystack, const char *needle)
break;
}
}
- if ( !*n ) /* matched all of 'needle' to null termination */
+ if ( !*n ) // matched all of 'needle' to null termination
{
- return haystack; /* return the start of the match */
+ return haystack; // return the start of the match
}
}
}
@@ -174,7 +178,7 @@ const char *stristr(const char *haystack, const char *needle)
}
#ifdef __WIN32
-char *_strtok_r(char *s1, const char *s2, char **lasts)
+char* _strtok_r(char *s1, const char *s2, char **lasts)
{
char *ret;
diff --git a/src/common/strlib.h b/src/common/strlib.h
index f9a6e41a3..332e823b9 100644
--- a/src/common/strlib.h
+++ b/src/common/strlib.h
@@ -4,25 +4,20 @@
#ifndef _STRLIB_H_
#define _STRLIB_H_
-#define J_MAX_MALLOC_SIZE 65535
-// String function library.
-// code by Jioh L. Jung (ziozzang@4wish.net)
-// This code is under license "BSD"
char* jstrescape (char* pt);
char* jstrescapecpy (char* pt, const char* spt);
-int jmemescapecpy (char* pt,char* spt, int size);
+int jmemescapecpy (char* pt, const char* spt, int size);
+
+int remove_control_chars(char *);
+char *trim(char *str, const char *delim);
+const char *stristr(const char *haystack, const char *needle);
#ifdef __WIN32
#define HAVE_STRTOK_R
#define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr))
-char *_strtok_r(char *s1, const char *s2, char **lasts);
+char* _strtok_r(char* s1, const char* s2, char** lasts);
#endif
-// custom functions
-int remove_control_chars(unsigned char *);
-char *trim(char *str, const char *delim);
-const char *stristr(const char *haystack, const char *needle);
-
#if !defined(WIN32) || (defined(_MSC_VER) && _MSC_VER < 1400)
size_t strnlen (const char* string, size_t maxlen);
#endif
diff --git a/src/common/utils.c b/src/common/utils.c
index c06e57083..2f5cf8705 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -20,28 +20,28 @@
#include "../common/showmsg.h"
#include "../common/cbasetypes.h"
-void dump(unsigned char *buffer, int num)
+void dump(unsigned char* buffer, int num)
{
- int icnt,jcnt;
+ int icnt, jcnt;
printf(" Hex ASCII\n");
printf(" ----------------------------------------------- ----------------");
- for (icnt=0;icnt<num;icnt+=16) {
- printf("\n%p ",&buffer[icnt]);
- for (jcnt=icnt;jcnt<icnt+16;++jcnt) {
+ for (icnt = 0; icnt < num; icnt += 16) {
+ printf("\n%p ", &buffer[icnt]);
+ for (jcnt = icnt; jcnt < icnt + 16; ++jcnt) {
if (jcnt < num) {
- printf("%02hX ",buffer[jcnt]);
+ printf("%02hX ", buffer[jcnt]);
} else
printf(" ");
}
printf(" | ");
- for (jcnt=icnt;jcnt<icnt+16;++jcnt) {
+ for (jcnt = icnt; jcnt < icnt + 16; ++jcnt) {
if (jcnt < num) {
if (buffer[jcnt] > 31 && buffer[jcnt] < 127)
- printf("%c",buffer[jcnt]);
+ printf("%c", buffer[jcnt]);
else
printf(".");
} else
@@ -266,30 +266,20 @@ void findfile(const char *p, const char *pat, void (func)(const char*))
unsigned char GetByte(unsigned long val, size_t num)
{
- switch(num)
- {
- case 0:
- return (unsigned char)((val & 0x000000FF) );
- case 1:
- return (unsigned char)((val & 0x0000FF00)>>0x08);
- case 2:
- return (unsigned char)((val & 0x00FF0000)>>0x10);
- case 3:
- return (unsigned char)((val & 0xFF000000)>>0x18);
- default:
- return 0; //better throw something here
+ switch(num) {
+ case 0: return (unsigned char)((val & 0x000000FF) );
+ case 1: return (unsigned char)((val & 0x0000FF00)>>0x08);
+ case 2: return (unsigned char)((val & 0x00FF0000)>>0x10);
+ case 3: return (unsigned char)((val & 0xFF000000)>>0x18);
+ default: return 0; //better throw something here
}
}
unsigned short GetWord(unsigned long val, size_t num)
{
- switch(num)
- {
- case 0:
- return (unsigned short)((val & 0x0000FFFF) );
- case 1:
- return (unsigned short)((val & 0xFFFF0000)>>0x10);
- default:
- return 0; //better throw something here
+ switch(num) {
+ case 0: return (unsigned short)((val & 0x0000FFFF) );
+ case 1: return (unsigned short)((val & 0xFFFF0000)>>0x10);
+ default: return 0; //better throw something here
}
}
unsigned short MakeWord(unsigned char byte0, unsigned char byte1)
diff --git a/src/login/login.c b/src/login/login.c
index 639b61afb..7b6e96f40 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -39,15 +39,15 @@
int account_id_count = START_ACCOUNT_NUM;
int server_num;
int new_account_flag = 0;
-in_addr_t login_ip = INADDR_ANY;
+uint32 login_ip = INADDR_ANY;
int login_port = 6900;
// Advanced subnet check [LuzZza]
struct _subnet {
- long subnet;
- long mask;
- long char_ip;
- long map_ip;
+ uint32 subnet;
+ uint32 mask;
+ uint32 char_ip;
+ uint32 map_ip;
} subnet[16];
int subnet_count = 0;
@@ -116,7 +116,9 @@ struct login_session_data {
#define AUTH_FIFO_SIZE 256
struct {
int account_id, login_id1, login_id2;
- int ip, sex, delflag;
+ uint32 ip;
+ char sex;
+ bool delflag;
} auth_fifo[AUTH_FIFO_SIZE];
int auth_fifo_pos = 0;
@@ -379,36 +381,36 @@ int read_gm_account(void) {
// Test of the IP mask
// (ip: IP to be tested, str: mask x.x.x.x/# or x.x.x.x/y.y.y.y)
//--------------------------------------------------------------
-int check_ipmask(unsigned int ip, const unsigned char *str) {
- unsigned int mask = 0, i = 0, m, ip2, a0, a1, a2, a3;
+int check_ipmask(uint32 ip, const unsigned char *str)
+{
+ unsigned int i = 0, m = 0;
+ unsigned int ip2, mask = 0;
unsigned char *p = (unsigned char *)&ip2, *p2 = (unsigned char *)&mask;
- if (sscanf((const char*)str, "%d.%d.%d.%d/%n", &a0, &a1, &a2, &a3, &i) != 4 || i == 0)
+ // scan ip address
+ if (sscanf((const char*)str, "%d.%d.%d.%d/%n", &p[3], &p[2], &p[1], &p[0], &i) != 4 || i == 0)
return 0;
- p[0] = a0; p[1] = a1; p[2] = a2; p[3] = a3;
- if (sscanf((const char*)str+i, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) == 4) {
- p2[0] = a0; p2[1] = a1; p2[2] = a2; p2[3] = a3;
- mask = ntohl(mask);
+ // scan mask
+ if (sscanf((const char*)str+i, "%d.%d.%d.%d", &p2[3], &p2[2], &p2[1], &p2[0]) == 4) {
+ ;
} else if (sscanf((const char*)(str+i), "%d", &m) == 1 && m >= 0 && m <= 32) {
for(i = 0; i < m && i < 32; i++)
- mask = (mask >> 1) | 0x80000000;
+ mask |= (1 << i);
} else {
ShowError("check_ipmask: invalid mask [%s].\n", str);
return 0;
}
-// printf("Tested IP: %08x, network: %08x, network mask: %08x\n",
-// (unsigned int)ntohl(ip), (unsigned int)ntohl(ip2), (unsigned int)mask);
- return ((ntohl(ip) & mask) == (ntohl(ip2) & mask));
+ return ((ip & mask) == (ip2 & mask));
}
//---------------------
// Access control by IP
//---------------------
-int check_ip(unsigned int ip) {
+int check_ip(uint32 ip)
+{
int i;
- unsigned char *p = (unsigned char *)&ip;
char buf[20];
char * access_ip;
enum { ACF_DEF, ACF_ALLOW, ACF_DENY } flag = ACF_DEF;
@@ -425,7 +427,7 @@ int check_ip(unsigned int ip) {
// If we have an answer, there is no guarantee to have a 100% correct value.
// And, the waiting time (to check) can be long (over 1 minute to a timeout). That can block the software.
// So, DNS notation isn't authorised for ip checking.
- sprintf(buf, "%d.%d.%d.%d.", p[0], p[1], p[2], p[3]);
+ sprintf(buf, "%d.%d.%d.%d.", CONVIP(ip));
for(i = 0; i < access_allownum; i++) {
access_ip = access_allow + i * ACO_STRSIZE;
@@ -455,9 +457,9 @@ int check_ip(unsigned int ip) {
//--------------------------------
// Access control by IP for ladmin
//--------------------------------
-int check_ladminip(unsigned int ip) {
+int check_ladminip(uint32 ip)
+{
int i;
- unsigned char *p = (unsigned char *)&ip;
char buf[20];
char * access_ip;
@@ -473,7 +475,7 @@ int check_ladminip(unsigned int ip) {
// If we have an answer, there is no guarantee to have a 100% correct value.
// And, the waiting time (to check) can be long (over 1 minute to a timeout). That can block the software.
// So, DNS notation isn't authorised for ip checking.
- sprintf(buf, "%d.%d.%d.%d.", p[0], p[1], p[2], p[3]);
+ sprintf(buf, "%d.%d.%d.%d.", CONVIP(ip));
for(i = 0; i < access_ladmin_allownum; i++) {
access_ip = access_ladmin_allow + i * ACO_STRSIZE;
@@ -488,7 +490,8 @@ int check_ladminip(unsigned int ip) {
//---------------------------------------------------
// E-mail check: return 0 (not correct) or 1 (valid).
//---------------------------------------------------
-int e_mail_check(char *email) {
+int e_mail_check(char *email)
+{
char ch;
char* last_arobas;
@@ -562,12 +565,10 @@ int mmo_auth_tostr(char *str, struct auth_dat *p) {
int i;
char *str_p = str;
- str_p += sprintf(str_p, "%d\t%s\t%s\t%s\t%c\t%d\t%d\t"
- "%s\t%s\t%ld\t%s\t%s\t%ld\t",
+ str_p += sprintf(str_p, "%d\t%s\t%s\t%s\t%c\t%d\t%d\t%s\t%s\t%ld\t%s\t%s\t%ld\t",
p->account_id, p->userid, p->pass, p->lastlogin,
- (p->sex == 2) ? 'S' : (p->sex ? 'M' : 'F'),
- p->logincount, p->state,
- p->email, p->error_message,
+ p->sex == 2 ? 'S' : p->sex == 1 ? 'M' : 'F',
+ p->logincount, p->state, p->email, p->error_message,
(long)p->connect_until_time, p->last_ip, p->memo, (long)p->ban_until_time);
for(i = 0; i < p->account_reg2_num; i++)
@@ -998,12 +999,13 @@ int check_auth_sync(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, unsigned char *buf, unsigned int len) {
+int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
+{
int i, c, fd;
for(i = 0, c = 0; i < MAX_SERVERS; i++) {
if ((fd = server_fd[i]) >= 0 && fd != sfd) {
- WFIFOHEAD(fd, len);
+ WFIFOHEAD(fd, len);
if (WFIFOSPACE(fd) < len) //Increase buffer size.
realloc_writefifo(fd, len);
memcpy(WFIFOP(fd,0), buf, len);
@@ -1011,13 +1013,15 @@ int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
c++;
}
}
+
return c;
}
//-----------------------------------------------------
// Send GM accounts to all char-server
//-----------------------------------------------------
-void send_GM_accounts(void) {
+void send_GM_accounts(void)
+{
unsigned int i;
unsigned char buf[32767];
int len;
@@ -1035,6 +1039,7 @@ void send_GM_accounts(void) {
break;
}
}
+
WBUFW(buf,2) = len;
charif_sendallwos(-1, buf, len);
@@ -1069,7 +1074,8 @@ int check_GM_file(int tid, unsigned int tick, int id, int data) {
//-------------------------------------
// Account creation (with e-mail check)
//-------------------------------------
-int mmo_auth_new(struct mmo_account* account, char sex, char* email) {
+int mmo_auth_new(struct mmo_account* account, char sex, char* email)
+{
time_t timestamp, timestamp_temp;
struct tm *tmtime;
int i = auth_num;
@@ -1085,28 +1091,14 @@ int mmo_auth_new(struct mmo_account* account, char sex, char* email) {
account_id_count++;
auth_dat[i].account_id = account_id_count++;
-
- strncpy(auth_dat[i].userid, account->userid, NAME_LENGTH);
- auth_dat[i].userid[23] = '\0';
-
- strncpy(auth_dat[i].pass, account->passwd, NAME_LENGTH);
- auth_dat[i].pass[23] = '\0';
-
+ strncpy(auth_dat[i].userid, account->userid, NAME_LENGTH); auth_dat[i].userid[23] = '\0';
+ strncpy(auth_dat[i].pass, account->passwd, NAME_LENGTH); auth_dat[i].pass[23] = '\0';
memcpy(auth_dat[i].lastlogin, "-", 2);
-
auth_dat[i].sex = (sex == 'M' || sex == 'm');
-
auth_dat[i].logincount = 0;
-
auth_dat[i].state = 0;
-
- if (e_mail_check(email) == 0)
- strncpy(auth_dat[i].email, "a@a.com", 40);
- else
- strncpy(auth_dat[i].email, email, 40);
-
+ strncpy(auth_dat[i].email, e_mail_check(email) ? email : "a@a.com", 40);
strncpy(auth_dat[i].error_message, "-", 20);
-
auth_dat[i].ban_until_time = 0;
if (start_limited_time < 0)
@@ -1123,9 +1115,7 @@ int mmo_auth_new(struct mmo_account* account, char sex, char* email) {
}
strncpy(auth_dat[i].last_ip, "-", 16);
-
strncpy(auth_dat[i].memo, "-", 255);
-
auth_dat[i].account_reg2_num = 0;
auth_num++;
@@ -1151,8 +1141,8 @@ int mmo_auth(struct mmo_account* account, int fd)
char user_password[256];
char ip[16];
- unsigned char *sin_addr = (unsigned char *)&session[fd]->client_addr.sin_addr;
- sprintf(ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
+ uint8* sin_addr = (uint8*)&session[fd]->client_addr;
+ sprintf(ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
// DNS Blacklist check
if(use_dnsbl)
@@ -1162,7 +1152,7 @@ int mmo_auth(struct mmo_account* account, int fd)
char *dnsbl_serv;
bool matched = false;
- sprintf(r_ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
+ sprintf(r_ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
for (dnsbl_serv = strtok(dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,","))
{
@@ -1312,16 +1302,16 @@ int mmo_auth(struct mmo_account* account, int fd)
}
if (online_check) {
- unsigned char buf[8];
struct online_login_data* data = idb_get(online_db,auth_dat[i].account_id);
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);
WBUFW(buf,0) = 0x2734;
WBUFL(buf,2) = auth_dat[i].account_id;
charif_sendallwos(-1, buf, 6);
if (data->waiting_disconnect == -1)
- data->waiting_disconnect = add_timer(gettick()+30000, waiting_disconnect_timer,auth_dat[i].account_id, 0);
+ data->waiting_disconnect = add_timer(gettick()+30000, waiting_disconnect_timer, auth_dat[i].account_id, 0);
return 3; // Rejected
}
}
@@ -1394,7 +1384,8 @@ int mmo_auth(struct mmo_account* account, int fd)
return -1; // account OK
}
-static int online_db_setoffline(DBKey key, void* data, va_list ap) {
+static int online_db_setoffline(DBKey key, void* data, va_list ap)
+{
struct online_login_data *p = (struct online_login_data *)data;
int server = va_arg(ap, int);
if (server == -1) {
@@ -1412,26 +1403,26 @@ static int online_db_setoffline(DBKey key, void* data, va_list ap) {
//--------------------------------
// Packet parsing for char-servers
//--------------------------------
-int parse_fromchar(int fd) {
+int parse_fromchar(int fd)
+{
unsigned int i;
int j, id;
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
+ uint32 ipl = session[fd]->client_addr;
char ip[16];
- int acc;
RFIFOHEAD(fd);
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ ip2str(ipl, ip);
for(id = 0; id < MAX_SERVERS; id++)
if (server_fd[id] == fd)
break;
+
if (id == MAX_SERVERS)
session[fd]->eof = 1;
if(session[fd]->eof) {
if (id < MAX_SERVERS) {
ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
- login_log("Char-server '%s' has disconnected (ip: %s)." RETCODE,
- server[id].name, ip);
+ login_log("Char-server '%s' has disconnected (ip: %s)." RETCODE, server[id].name, ip);
server_fd[id] = -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.
@@ -1446,8 +1437,8 @@ int parse_fromchar(int fd) {
ShowDebug("parse_fromchar: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));
switch (RFIFOW(fd,0)) {
- // request from map-server via char-server to reload GM accounts (by Yor).
- case 0x2709:
+
+ 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)." RETCODE, server[id].name, ip);
read_gm_account();
// send GM accounts to all char-servers
@@ -1455,10 +1446,10 @@ int parse_fromchar(int fd) {
RFIFOSKIP(fd,2);
break;
- case 0x2712: // request from char-server to authentify an account
+ case 0x2712: // request from char-server to authenticate an account
if (RFIFOREST(fd) < 19)
return 0;
- {
+ {
int account_id;
account_id = RFIFOL(fd,2); // speed up
for(i = 0; i < AUTH_FIFO_SIZE; i++) {
@@ -1466,8 +1457,9 @@ int parse_fromchar(int fd) {
auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
auth_fifo[i].sex == RFIFOB(fd,14) &&
- auth_fifo[i].ip == RFIFOL(fd,15) &&
- !auth_fifo[i].delflag) {
+ auth_fifo[i].ip == ntohl(RFIFOL(fd,15)) &&
+ !auth_fifo[i].delflag)
+ {
unsigned int k;
time_t connect_until_time = 0;
char email[40] = "";
@@ -1475,7 +1467,6 @@ int parse_fromchar(int fd) {
auth_fifo[i].delflag = 1;
login_log("Char-server '%s': authentification of the account %d accepted (ip: %s)." RETCODE,
server[id].name, account_id, ip);
-// printf("%d\n", i);
for(k = 0; k < auth_num; k++) {
if (auth_dat[k].account_id == account_id) {
strcpy(email, auth_dat[k].email);
@@ -1504,7 +1495,7 @@ int parse_fromchar(int fd) {
// It is unnecessary to send validity date of the account
WFIFOSET(fd,51);
}
- }
+ }
RFIFOSKIP(fd,19);
break;
@@ -1521,44 +1512,37 @@ int parse_fromchar(int fd) {
RFIFOSKIP(fd,6);
break;
- // we receive a e-mail creation of an account with a default e-mail (no answer)
- case 0x2715:
+ case 0x2715: // request from char server to change e-email from default "a@a.com"
if (RFIFOREST(fd) < 46)
return 0;
{
char email[40];
- acc = RFIFOL(fd,2); // speed up
- memcpy(email, RFIFOP(fd,6), 40);
- email[39] = '\0';
+ int acc = RFIFOL(fd,2);
+ memcpy(email, RFIFOP(fd,6), 40); email[39] = '\0';
remove_control_chars((unsigned char *)email);
- //printf("parse_fromchar: an e-mail creation of an account with a default e-mail: server '%s', account: %d, e-mail: '%s'.\n", server[id].name, acc, RFIFOP(fd,6));
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)" RETCODE,
- server[id].name, acc, ip);
+ 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)" RETCODE, 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)." RETCODE,
- server[id].name, acc, email, ip);
+ 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)." RETCODE, server[id].name, acc, email, ip);
// Save
mmo_auth_sync();
break;
}
}
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)." RETCODE,
- server[id].name, acc, ip);
+ 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)." RETCODE, server[id].name, acc, ip);
}
}
RFIFOSKIP(fd,46);
break;
- // We receive an e-mail/limited time request, because a player comes back from a map-server to the char-server
- case 0x2716:
+ 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)
return 0;
- //printf("parse_fromchar: E-mail/limited time request from '%s' server (concerned account: %d)\n", server[id].name, RFIFOL(fd,2));
+
for(i = 0; i < auth_num; i++) {
if (auth_dat[i].account_id == RFIFOL(fd,2)) {
login_log("Char-server '%s': e-mail of the account %d found (ip: %s)." RETCODE,
@@ -1577,13 +1561,13 @@ int parse_fromchar(int fd) {
RFIFOSKIP(fd,6);
break;
- case 0x2720: // To become GM request
+ case 0x2720: // Request to become a GM
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
{
unsigned char buf[10];
FILE *fp;
- acc = RFIFOL(fd,4);
+ 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;
@@ -1636,9 +1620,9 @@ int parse_fromchar(int fd) {
case 0x2722: // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
if (RFIFOREST(fd) < 86)
return 0;
- {
+ {
char actual_email[40], new_email[40];
- acc = RFIFOL(fd,2);
+ int acc = RFIFOL(fd,2);
memcpy(actual_email, RFIFOP(fd,6), 40);
actual_email[39] = '\0';
remove_control_chars((unsigned char *)actual_email);
@@ -1677,52 +1661,50 @@ int parse_fromchar(int fd) {
RFIFOSKIP(fd, 86);
break;
- // Receiving of map-server via char-server a status change resquest (by Yor)
- case 0x2724:
+ case 0x2724: // Receiving of map-server via char-server a status change resquest
if (RFIFOREST(fd) < 10)
return 0;
- {
- int acc, statut;
- acc = RFIFOL(fd,2);
- statut = RFIFOL(fd,6);
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == acc) {
- if (auth_dat[i].state != statut) {
- login_log("Char-server '%s': Status change (account: %d, new status %d, ip: %s)." RETCODE,
- 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)." RETCODE,
- server[id].name, acc, statut, ip);
- break;
+ {
+ int acc, statut;
+ acc = RFIFOL(fd,2);
+ statut = RFIFOL(fd,6);
+ for(i = 0; i < auth_num && auth_dat[i].account_id != acc; i++);
+
+ if (i == auth_num) {
+ login_log("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s)." RETCODE,
+ 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)." RETCODE,
+ 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)
}
- }
- if (i == auth_num) {
- login_log("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s)." RETCODE,
+ 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)." RETCODE,
server[id].name, acc, statut, ip);
- }
- RFIFOSKIP(fd,10);
}
+
+ RFIFOSKIP(fd,10);
return 0;
+ }
- case 0x2725: // Receiving of map-server via char-server a ban resquest (by Yor)
+ case 0x2725: // Receiving of map-server via char-server a ban resquest
if (RFIFOREST(fd) < 18)
return 0;
- {
- acc = RFIFOL(fd,2);
+ {
+ int acc = RFIFOL(fd,2);
for(i = 0; i < auth_num; i++) {
if (auth_dat[i].account_id == acc) {
time_t timestamp;
@@ -1779,17 +1761,16 @@ int parse_fromchar(int fd) {
login_log("Char-server '%s': Error of ban request (account: %d not found, ip: %s)." RETCODE,
server[id].name, acc, ip);
RFIFOSKIP(fd,18);
- }
- return 0;
+ return 0;
+ }
- case 0x2727: // Change of sex (sex is reversed)
+ case 0x2727: // Change of sex (sex is reversed)
if (RFIFOREST(fd) < 6)
return 0;
- {
+ {
int sex;
- acc = RFIFOL(fd,2);
+ int acc = RFIFOL(fd,2);
for(i = 0; i < auth_num; i++) {
-// printf("%d,", auth_dat[i].account_id);
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)." RETCODE,
@@ -1820,15 +1801,15 @@ int parse_fromchar(int fd) {
login_log("Char-server '%s': Error of sex change (account: %d not found, sex would be reversed, ip: %s)." RETCODE,
server[id].name, acc, ip);
RFIFOSKIP(fd,6);
- }
- return 0;
+ return 0;
+ }
case 0x2728: // We receive account_reg2 from a char-server, and we send them to other map-servers.
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
{
int p;
- acc = RFIFOL(fd,4);
+ int acc = RFIFOL(fd,4);
for(i = 0; i < auth_num; i++) {
if (auth_dat[i].account_id == acc) {
//unsigned char buf[rfifow(fd,2)+1];
@@ -1868,10 +1849,11 @@ int parse_fromchar(int fd) {
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
- case 0x272a: // Receiving of map-server via char-server a unban resquest (by Yor)
+ case 0x272a: // Receiving of map-server via char-server a unban resquest
if (RFIFOREST(fd) < 6)
return 0;
{
+ int acc;
acc = RFIFOL(fd,2);
for(i = 0; i < auth_num; i++) {
if (auth_dat[i].account_id == acc) {
@@ -1962,10 +1944,8 @@ int parse_fromchar(int fd) {
case 0x2736: // WAN IP update from char-server
if (RFIFOREST(fd) < 6)
return 0;
- ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id,
- (int)RFIFOB(fd,2),(int)RFIFOB(fd,3),
- (int)RFIFOB(fd,4),(int)RFIFOB(fd,5));
- server[id].ip = RFIFOL(fd,2);
+ server[id].ip = ntohl(RFIFOL(fd,2));
+ ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
RFIFOSKIP(fd,6);
break;
@@ -1975,37 +1955,6 @@ int parse_fromchar(int fd) {
RFIFOSKIP(fd,2);
break;
- case 0x3000: //change sex for chrif_changesex()
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
- unsigned int sex;
- acc = RFIFOL(fd,4);
- sex = RFIFOB(fd,8);
- if (sex != 0 && sex != 1)
- sex = 0;
- for(i = 0; i < auth_num; i++) {
- if (auth_dat[i].account_id == acc) {
- unsigned char buf[16];
- login_log("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s)." RETCODE,
- server[id].name, acc, (sex == 2) ? 'S' : (sex ? 'M' : 'F'), ip);
- auth_fifo[i].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
- auth_dat[i].sex = sex;
- WBUFW(buf,0) = 0x2723;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = sex;
- charif_sendallwos(-1, buf, 7);
- break;
- }
- }
- if (i == auth_num) {
- login_log("Char-server '%s': Error of Sex change (account: %d not found, suggested sex %c, ip: %s)." RETCODE,
- server[id].name, acc, (sex == 2) ? 'S' : (sex ? 'M' : 'F'), ip);
- }
- RFIFOSKIP(fd,RFIFOW(fd,2));
- }
- return 0;
-
default:
{
FILE *logfp;
@@ -2047,9 +1996,8 @@ int parse_fromchar(int fd) {
fclose(logfp);
}
}
- ShowWarning("parse_fromchar: Unknown packet 0x%x (from a char-server)! -> disconnection.\n", RFIFOW(fd,0));
+ ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", RFIFOW(fd,0));
session[fd]->eof = 1;
- ShowStatus("Char-server has been disconnected (unknown packet).\n");
return 0;
}
}
@@ -2060,14 +2008,15 @@ int parse_fromchar(int fd) {
//---------------------------------------
// Packet parsing for administation login
//---------------------------------------
-int parse_admin(int fd) {
+int parse_admin(int fd)
+{
unsigned int i, j;
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
+ uint32 ipl = session[fd]->client_addr;
char* account_name;
char ip[16];
RFIFOHEAD(fd);
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ ip2str(ipl, ip);
if (session[fd]->eof) {
do_close(fd);
@@ -2108,8 +2057,6 @@ int parse_admin(int fd) {
return 0;
{
int st, ed, len;
- //int id[auth_num];
- //int *id=(int *)aCalloc(auth_num, sizeof(int));
CREATE_BUFFER(id, int, auth_num);
st = RFIFOL(fd,2);
ed = RFIFOL(fd,6);
@@ -2336,8 +2283,8 @@ int parse_admin(int fd) {
server_num = 0;
for(i = 0; i < MAX_SERVERS; i++) {
if (server_fd[i] >= 0) {
- WFIFOL(fd,4+server_num*32) = server[i].ip;
- WFIFOW(fd,4+server_num*32+4) = server[i].port;
+ 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;
@@ -3027,36 +2974,34 @@ int parse_admin(int fd) {
//--------------------------------------------
// Test to know if an IP come from LAN or WAN.
//--------------------------------------------
-int lan_subnetcheck(long *p) {
-
+int lan_subnetcheck(uint32 ip)
+{
int i;
-
- for(i=0; i<subnet_count; i++) {
- if(subnet[i].subnet == (*p & subnet[i].mask)) {
+
+ for(i = 0; i < subnet_count; i++) {
+ if(subnet[i].subnet == (ip & subnet[i].mask)) {
return subnet[i].char_ip;
}
}
-
+
return 0;
}
//----------------------------------------------------------------------------------------
// Default packet parsing (normal players or administation/char-server connexion requests)
//----------------------------------------------------------------------------------------
-int parse_login(int fd) {
-
+int parse_login(int fd)
+{
struct mmo_account account;
int result, j;
unsigned int i;
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
+ uint32 ipl = session[fd]->client_addr;
char ip[16];
- long subnet_char_ip;
-
RFIFOHEAD(fd);
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ ip2str(ipl, ip);
- memset(&account, 0, sizeof(account));
+ memset(&account, 0, sizeof(account));
if (session[fd]->eof) {
do_close(fd);
@@ -3094,6 +3039,17 @@ int parse_login(int fd) {
{
int packet_len = RFIFOREST(fd);
+ //Perform ip-ban check
+ if (!check_ip(ipl)) {
+ login_log("Connection refused: IP isn't authorised (deny/allow, ip: %s)." RETCODE, ip);
+ WFIFOHEAD(fd, 23);
+ WFIFOW(fd,0) = 0x6a;
+ WFIFOB(fd,2) = 3; // 3 = Rejected from Server
+ WFIFOSET(fd,23);
+ RFIFOSKIP(fd,packet_len);
+ break;
+ }
+
switch(RFIFOW(fd, 0)){
case 0x64:
if(packet_len < 55)
@@ -3109,9 +3065,9 @@ int parse_login(int fd) {
break;
}
- account.version = RFIFOL(fd, 2); //for exe version check [Sirius]
+ account.version = RFIFOL(fd, 2);
if (!account.version) account.version = 1; //Force some version...
- memcpy(account.userid,RFIFOP(fd,6),NAME_LENGTH);
+ memcpy(account.userid,RFIFOP(fd, 6),NAME_LENGTH);
account.userid[23] = '\0';
remove_control_chars((unsigned char *)account.userid);
if (RFIFOW(fd,0) != 0x01dd) {
@@ -3132,18 +3088,8 @@ int parse_login(int fd) {
account.passwdenc = 0;
#endif
- if (!check_ip(session[fd]->client_addr.sin_addr.s_addr)) {
- login_log("Connection refused: IP isn't authorised (deny/allow, ip: %s)." RETCODE, ip);
- WFIFOHEAD(fd, 23);
- WFIFOW(fd,0) = 0x6a;
- WFIFOB(fd,2) = 3; // 3 = Rejected from Server
- WFIFOSET(fd,23);
- RFIFOSKIP(fd,packet_len);
- break;
- }
-
result = mmo_auth(&account, fd);
- if (result == -1) {
+ if (result == -1) { // auth success
int gm_level = isGM(account.account_id);
if (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)." RETCODE,
@@ -3157,16 +3103,15 @@ int parse_login(int fd) {
ShowInfo("Connection of the GM (level:%d) account '%s' accepted.\n", gm_level, account.userid);
else
ShowInfo("Connection of the account '%s' accepted.\n", account.userid);
+
server_num = 0;
WFIFOHEAD(fd, 47+32*MAX_SERVERS);
for(i = 0; i < MAX_SERVERS; i++) {
if (server_fd[i] >= 0) {
- // Andvanced subnet check [LuzZza]
- if((subnet_char_ip = lan_subnetcheck((long*)p)))
- WFIFOL(fd,47+server_num*32) = subnet_char_ip;
- else
- WFIFOL(fd,47+server_num*32) = server[i].ip;
- WFIFOW(fd,47+server_num*32+4) = server[i].port;
+ // Advanced subnet check [LuzZza]
+ uint32 subnet_char_ip = lan_subnetcheck(ipl);
+ WFIFOL(fd,47+server_num*32) = (subnet_char_ip) ? htonl(subnet_char_ip) : htonl(server[i].ip);
+ WFIFOW(fd,47+server_num*32+4) = server[i].port; // /!\ must be sent in intel host byte order /!\ (client bug)
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;
@@ -3174,8 +3119,7 @@ int parse_login(int fd) {
server_num++;
}
}
- // if at least 1 char-server
- if (server_num > 0) {
+ if (server_num > 0) { // if at least 1 char-server
WFIFOW(fd,0) = 0x69;
WFIFOW(fd,2) = 47+32*server_num;
WFIFOL(fd,4) = account.login_id1;
@@ -3192,10 +3136,9 @@ int parse_login(int fd) {
auth_fifo[auth_fifo_pos].login_id2 = account.login_id2;
auth_fifo[auth_fifo_pos].sex = account.sex;
auth_fifo[auth_fifo_pos].delflag = 0;
- auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
+ auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr;
auth_fifo_pos++;
- // if no char-server, don't send void list of servers, just disconnect the player with proper message
- } else {
+ } else { // if no char-server, don't send void list of servers, just disconnect the player with proper message
login_log("Connection refused: there is no char-server online (account: %s, ip: %s)." RETCODE,
account.userid, ip);
WFIFOW(fd,0) = 0x81;
@@ -3203,29 +3146,25 @@ int parse_login(int fd) {
WFIFOSET(fd,3);
}
}
- } else {
- WFIFOHEAD(fd, 23);
+ } else { // auth failed
+ WFIFOHEAD(fd, 23);
memset(WFIFOP(fd,0), '\0', 23);
WFIFOW(fd,0) = 0x6a;
WFIFOB(fd,2) = result;
if (result == 6) { // 6 = Your are Prohibited to log in until %s
+ char tmpstr[20];
+ time_t ban_until_time;
i = search_account_index(account.userid);
- if (i != -1) {
- if (auth_dat[i].ban_until_time != 0) { // if account is banned, we send ban timestamp
- char tmpstr[256];
- strftime(tmpstr, 20, date_format, localtime(&auth_dat[i].ban_until_time));
- tmpstr[19] = '\0';
- memcpy(WFIFOP(fd,3), tmpstr, 20);
- } else { // we send error message
- memcpy(WFIFOP(fd,3), auth_dat[i].error_message, 20);
- }
- }
+ ban_until_time = (i) ? auth_dat[i].ban_until_time : 0;
+ strftime(tmpstr, 20, date_format, localtime(&ban_until_time)); tmpstr[19] = '\0';
+ strncpy(WFIFOP(fd,3), tmpstr, 20); // ban timestamp goes here
}
WFIFOSET(fd,23);
}
RFIFOSKIP(fd,packet_len);
break;
}
+
case 0x01db: // Sending request of the coding key
case 0x791a: // Sending request of the coding key (administration packet)
{
@@ -3246,8 +3185,9 @@ int parse_login(int fd) {
ld->md5keylen = rand() % 4 + 12;
for(i = 0; i < ld->md5keylen; i++)
ld->md5key[i] = rand() % 255 + 1;
+
RFIFOSKIP(fd,2);
- WFIFOHEAD(fd, 4 + ld->md5keylen);
+ WFIFOHEAD(fd, 4 + ld->md5keylen);
WFIFOW(fd,0) = 0x01dc;
WFIFOW(fd,2) = 4 + ld->md5keylen;
memcpy(WFIFOP(fd,4), ld->md5key, ld->md5keylen);
@@ -3259,29 +3199,29 @@ int parse_login(int fd) {
if (RFIFOREST(fd) < 86)
return 0;
{
- int GM_value, len;
+ int len;
char* server_name;
+ uint32 server_ip;
+ uint16 server_port;
+
WFIFOHEAD(fd, 3);
- memcpy(account.userid,RFIFOP(fd,2),NAME_LENGTH);
- account.userid[23] = '\0';
- remove_control_chars((unsigned char *)account.userid);
- memcpy(account.passwd, RFIFOP(fd,26), NAME_LENGTH);
- account.passwd[23] = '\0';
- remove_control_chars((unsigned char *)account.passwd);
+ memcpy(account.userid,RFIFOP(fd,2),NAME_LENGTH); account.userid[23] = '\0'; remove_control_chars((unsigned char *)account.userid);
+ memcpy(account.passwd, RFIFOP(fd,26), NAME_LENGTH); account.passwd[23] = '\0'; remove_control_chars((unsigned char *)account.passwd);
account.passwdenc = 0;
- server_name = (char*)RFIFOP(fd,60);
- server_name[20] = '\0';
- remove_control_chars((unsigned char *)server_name);
+ server_name = (char*)RFIFOP(fd,60); server_name[20] = '\0'; remove_control_chars((unsigned char *)server_name);
+ server_ip = ntohl(RFIFOL(fd, 54));
+ server_port = ntohs(RFIFOW(fd, 58));
login_log("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (ip: %s)" RETCODE,
- server_name, RFIFOB(fd,54), RFIFOB(fd,55), RFIFOB(fd,56), RFIFOB(fd,57), RFIFOW(fd,58), ip);
+ server_name, CONVIP(server_ip), server_port, ip);
+
result = mmo_auth(&account, fd);
if (result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server_fd[account.account_id] == -1) {
login_log("Connection of the char-server '%s' accepted (account: %s, pass: %s, ip: %s)" RETCODE,
server_name, account.userid, account.passwd, ip);
ShowStatus("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 = RFIFOL(fd,54);
- server[account.account_id].port = RFIFOW(fd,58);
+ server[account.account_id].ip = ntohl(RFIFOL(fd,54));
+ server[account.account_id].port = ntohs(RFIFOW(fd,58));
memcpy(server[account.account_id].name, server_name, 20);
server[account.account_id].users = 0;
server[account.account_id].maintenance = RFIFOW(fd,82);
@@ -3292,18 +3232,24 @@ int parse_login(int fd) {
WFIFOSET(fd,3);
session[fd]->func_parse = parse_fromchar;
realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+
+ //TODO: why not use send_GM_accounts(fd)?
// send GM account to char-server
len = 4;
WFIFOW(fd,0) = 0x2732;
- for(i = 0; i < auth_num; i++)
+ for(i = 0; i < auth_num; i++) {
// send only existing accounts. We can not create a GM account when server is online.
+ int GM_value;
if ((GM_value = isGM(auth_dat[i].account_id)) > 0) {
WFIFOL(fd,len) = auth_dat[i].account_id;
WFIFOB(fd,len+4) = (unsigned char)GM_value;
len += 5;
}
+ }
WFIFOW(fd,2) = len;
WFIFOSET(fd,len);
+ // /TODO
+
} else {
if (server_fd[account.account_id] != -1) {
ShowNotice("Connection of the char-server '%s' REFUSED - already connected (account: %ld-%s, pass: %s, ip: %s)\n",
@@ -3315,7 +3261,7 @@ int parse_login(int fd) {
login_log("Connexion of the char-server '%s' REFUSED (account: %s, pass: %s, ip: %s)" RETCODE,
server_name, account.userid, account.passwd, ip);
}
- WFIFOHEAD(fd, 3);
+ WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2711;
WFIFOB(fd,2) = 3;
WFIFOSET(fd,3);
@@ -3324,7 +3270,7 @@ int parse_login(int fd) {
RFIFOSKIP(fd,86);
return 0;
- case 0x7530: // Request of the server version
+ case 0x7530: // Server version information request
login_log("Sending of the server version (ip: %s)" RETCODE, ip);
WFIFOHEAD(fd, 10);
WFIFOW(fd,0) = 0x7531;
@@ -3349,7 +3295,7 @@ int parse_login(int fd) {
return 0;
WFIFOW(fd,0) = 0x7919;
WFIFOB(fd,2) = 1;
- if (!check_ladminip(session[fd]->client_addr.sin_addr.s_addr)) {
+ if (!check_ladminip(session[fd]->client_addr)) {
login_log("'ladmin'-login: Connection in administration mode refused: IP isn't authorised (ladmin_allow, ip: %s)." RETCODE, ip);
} else {
struct login_session_data *ld = (struct login_session_data*)session[fd]->session_data;
@@ -3437,7 +3383,7 @@ int parse_login(int fd) {
fclose(logfp);
}
}
- login_log("End of connection, unknown packet (ip: %s)" RETCODE, ip);
+ login_log("Abnormal end of connection (ip: %s): Unknown packet 0x%x " RETCODE, ip, RFIFOW(fd,0));
session[fd]->eof = 1;
return 0;
}
@@ -3449,7 +3395,7 @@ int parse_login(int fd) {
//-----------------------
// Console Command Parser [Wizputer]
//-----------------------
-int parse_console(char *buf)
+int parse_console(char*buf)
{
char command[256];
@@ -3545,9 +3491,9 @@ int login_lan_config_read(const char *lancfgName)
if(strcmpi(w1, "subnet") == 0) {
- subnet[subnet_count].mask = inet_addr(w2);
- subnet[subnet_count].char_ip = inet_addr(w3);
- subnet[subnet_count].map_ip = inet_addr(w4);
+ subnet[subnet_count].mask = ntohl(inet_addr(w2));
+ subnet[subnet_count].char_ip = ntohl(inet_addr(w3));
+ subnet[subnet_count].map_ip = ntohl(inet_addr(w4));
subnet[subnet_count].subnet = subnet[subnet_count].char_ip&subnet[subnet_count].mask;
if (subnet[subnet_count].subnet != (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);
@@ -3566,7 +3512,7 @@ int login_lan_config_read(const char *lancfgName)
//-----------------------------------
// Reading main configuration file
-//-----------------------------------
+//-----------------------------------
int login_config_read(const char* cfgName)
{
char line[1024], w1[1024], w2[1024];
@@ -3587,177 +3533,178 @@ int login_config_read(const char* cfgName)
if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) < 2)
continue;
- //TODO: unindent
- remove_control_chars((unsigned char *)w1);
- remove_control_chars((unsigned char *)w2);
-
- if(strcmpi(w1,"timestamp_format") == 0) {
- strncpy(timestamp_format, w2, 20);
- } else if(strcmpi(w1,"stdout_with_ansisequence")==0){
- stdout_with_ansisequence = config_switch(w2);
- } else if(strcmpi(w1,"console_silent")==0){
- ShowInfo("Console Silent Setting: %d\n", atoi(w2));
- msg_silent = atoi(w2);
- } else if (strcmpi(w1, "admin_state") == 0) {
- admin_state = config_switch(w2);
- } else if (strcmpi(w1, "admin_pass") == 0) {
- memset(admin_pass, 0, sizeof(admin_pass));
- strncpy(admin_pass, w2, sizeof(admin_pass));
- admin_pass[sizeof(admin_pass)-1] = '\0';
- } else if (strcmpi(w1, "ladminallowip") == 0) {
- if (strcmpi(w2, "clear") == 0) {
+ remove_control_chars((unsigned char *)w1);
+ remove_control_chars((unsigned char *)w2);
+
+ if(strcmpi(w1,"timestamp_format") == 0) {
+ strncpy(timestamp_format, w2, 20);
+ } else if(strcmpi(w1,"stdout_with_ansisequence")==0){
+ stdout_with_ansisequence = config_switch(w2);
+ } else if(strcmpi(w1,"console_silent")==0){
+ ShowInfo("Console Silent Setting: %d\n", atoi(w2));
+ msg_silent = atoi(w2);
+ }
+ else if (strcmpi(w1, "admin_state") == 0) {
+ admin_state = config_switch(w2);
+ } else if (strcmpi(w1, "admin_pass") == 0) {
+ memset(admin_pass, 0, sizeof(admin_pass));
+ strncpy(admin_pass, w2, sizeof(admin_pass));
+ admin_pass[sizeof(admin_pass)-1] = '\0';
+ } else if (strcmpi(w1, "ladminallowip") == 0) {
+ if (strcmpi(w2, "clear") == 0) {
+ if (access_ladmin_allow)
+ aFree(access_ladmin_allow);
+ access_ladmin_allow = NULL;
+ access_ladmin_allownum = 0;
+ } else {
+ if (strcmpi(w2, "all") == 0) {
+ // reset all previous values
if (access_ladmin_allow)
aFree(access_ladmin_allow);
- access_ladmin_allow = NULL;
- access_ladmin_allownum = 0;
- } else {
- if (strcmpi(w2, "all") == 0) {
- // reset all previous values
- if (access_ladmin_allow)
- aFree(access_ladmin_allow);
- // set to all
+ // set to all
+ access_ladmin_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
+ access_ladmin_allownum = 1;
+ access_ladmin_allow[0] = '\0';
+ } else if (w2[0] && !(access_ladmin_allownum == 1 && access_ladmin_allow[0] == '\0')) { // don't add IP if already 'all'
+ if (access_ladmin_allow)
+ access_ladmin_allow = (char*)aRealloc(access_ladmin_allow, (access_ladmin_allownum+1) * ACO_STRSIZE);
+ else
access_ladmin_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
- access_ladmin_allownum = 1;
- access_ladmin_allow[0] = '\0';
- } else if (w2[0] && !(access_ladmin_allownum == 1 && access_ladmin_allow[0] == '\0')) { // don't add IP if already 'all'
- if (access_ladmin_allow)
- access_ladmin_allow = (char*)aRealloc(access_ladmin_allow, (access_ladmin_allownum+1) * ACO_STRSIZE);
- else
- access_ladmin_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
- strncpy(access_ladmin_allow + (access_ladmin_allownum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
- access_ladmin_allow[access_ladmin_allownum * ACO_STRSIZE - 1] = '\0';
- }
+ strncpy(access_ladmin_allow + (access_ladmin_allownum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
+ access_ladmin_allow[access_ladmin_allownum * ACO_STRSIZE - 1] = '\0';
}
- } else if (strcmpi(w1, "gm_pass") == 0) {
- memset(gm_pass, 0, sizeof(gm_pass));
- strncpy(gm_pass, w2, sizeof(gm_pass));
- gm_pass[sizeof(gm_pass)-1] = '\0';
- } else if (strcmpi(w1, "level_new_gm") == 0) {
- level_new_gm = atoi(w2);
- } else if (strcmpi(w1, "new_account") == 0) {
- new_account_flag = config_switch(w2);
- } else if (strcmpi(w1, "bind_ip") == 0) {
- char ip_str[16];
- login_ip = host2ip(w2);
- if (login_ip)
- ShowStatus("Login server binding IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str));
- } else if (strcmpi(w1, "login_port") == 0) {
- login_port = atoi(w2);
- } else if (strcmpi(w1, "account_filename") == 0) {
- memset(account_filename, 0, sizeof(account_filename));
- strncpy(account_filename, w2, sizeof(account_filename));
- account_filename[sizeof(account_filename)-1] = '\0';
- } else if (strcmpi(w1, "gm_account_filename") == 0) {
- memset(GM_account_filename, 0, sizeof(GM_account_filename));
- strncpy(GM_account_filename, w2, sizeof(GM_account_filename));
- GM_account_filename[sizeof(GM_account_filename)-1] = '\0';
- } else if (strcmpi(w1, "gm_account_filename_check_timer") == 0) {
- gm_account_filename_check_timer = atoi(w2);
- } else if (strcmpi(w1, "use_MD5_passwords") == 0) {
- use_md5_passwds = 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, "log_login") == 0) {
- log_login = config_switch(w2);
- } 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, "display_parse_login") == 0) {
- display_parse_login = config_switch(w2);
- } else if (strcmpi(w1, "display_parse_admin") == 0) {
- display_parse_admin = config_switch(w2);
- } else if (strcmpi(w1, "display_parse_fromchar") == 0) {
- display_parse_fromchar = config_switch(w2); // 0: no, 1: yes (without packet 0x2714), 2: all packets
- } else if (!strcmpi(w1, "date_format")) {
- strncpy(date_format, w2, sizeof(date_format));
- } else if (strcmpi(w1, "min_level_to_connect") == 0) {
- min_level_to_connect = atoi(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) {
- access_order = atoi(w2);
- if (strcmpi(w2, "deny,allow") == 0 ||
- strcmpi(w2, "deny, allow") == 0) access_order = ACO_DENY_ALLOW;
- if (strcmpi(w2, "allow,deny") == 0 ||
- strcmpi(w2, "allow, deny") == 0) access_order = ACO_ALLOW_DENY;
- if (strcmpi(w2, "mutual-failture") == 0 ||
- strcmpi(w2, "mutual-failure") == 0) access_order = ACO_MUTUAL_FAILTURE;
- } else if (strcmpi(w1, "allow") == 0) {
- if (strcmpi(w2, "clear") == 0) {
+ }
+ } else if (strcmpi(w1, "gm_pass") == 0) {
+ memset(gm_pass, 0, sizeof(gm_pass));
+ strncpy(gm_pass, w2, sizeof(gm_pass));
+ gm_pass[sizeof(gm_pass)-1] = '\0';
+ } else if (strcmpi(w1, "level_new_gm") == 0) {
+ level_new_gm = atoi(w2);
+ }
+ else if (strcmpi(w1, "bind_ip") == 0) {
+ char ip_str[16];
+ login_ip = host2ip(w2);
+ if (login_ip)
+ ShowStatus("Login server binding IP address : %s -> %s\n", w2, ip2str(login_ip, ip_str));
+ } else if (strcmpi(w1, "login_port") == 0) {
+ login_port = atoi(w2);
+ } else if (strcmpi(w1, "account_filename") == 0) {
+ memset(account_filename, 0, sizeof(account_filename));
+ strncpy(account_filename, w2, sizeof(account_filename));
+ account_filename[sizeof(account_filename)-1] = '\0';
+ } else if (strcmpi(w1, "gm_account_filename") == 0) {
+ memset(GM_account_filename, 0, sizeof(GM_account_filename));
+ strncpy(GM_account_filename, w2, sizeof(GM_account_filename));
+ GM_account_filename[sizeof(GM_account_filename)-1] = '\0';
+ } else if (strcmpi(w1, "gm_account_filename_check_timer") == 0) {
+ gm_account_filename_check_timer = atoi(w2);
+ } else if (strcmpi(w1, "log_login") == 0) {
+ log_login = 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, "display_parse_login") == 0) {
+ display_parse_login = config_switch(w2);
+ } else if (strcmpi(w1, "display_parse_admin") == 0) {
+ display_parse_admin = config_switch(w2);
+ } else if (strcmpi(w1, "display_parse_fromchar") == 0) {
+ display_parse_fromchar = config_switch(w2); // 0: no, 1: yes (without packet 0x2714), 2: all packets
+ } 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) {
+ access_order = atoi(w2);
+ if (strcmpi(w2, "deny,allow") == 0 ||
+ strcmpi(w2, "deny, allow") == 0) access_order = ACO_DENY_ALLOW;
+ if (strcmpi(w2, "allow,deny") == 0 ||
+ strcmpi(w2, "allow, deny") == 0) access_order = ACO_ALLOW_DENY;
+ if (strcmpi(w2, "mutual-failture") == 0 ||
+ strcmpi(w2, "mutual-failure") == 0) access_order = ACO_MUTUAL_FAILTURE;
+ } else if (strcmpi(w1, "allow") == 0) {
+ if (strcmpi(w2, "clear") == 0) {
+ if (access_allow)
+ aFree(access_allow);
+ access_allow = NULL;
+ access_allownum = 0;
+ } else {
+ if (strcmpi(w2, "all") == 0) {
+ // reset all previous values
if (access_allow)
aFree(access_allow);
- access_allow = NULL;
- access_allownum = 0;
- } else {
- if (strcmpi(w2, "all") == 0) {
- // reset all previous values
- if (access_allow)
- aFree(access_allow);
- // set to all
+ // set to all
+ access_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
+ access_allownum = 1;
+ access_allow[0] = '\0';
+ } else if (w2[0] && !(access_allownum == 1 && access_allow[0] == '\0')) { // don't add IP if already 'all'
+ if (access_allow)
+ access_allow = (char*)aRealloc(access_allow, (access_allownum+1) * ACO_STRSIZE);
+ else
access_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
- access_allownum = 1;
- access_allow[0] = '\0';
- } else if (w2[0] && !(access_allownum == 1 && access_allow[0] == '\0')) { // don't add IP if already 'all'
- if (access_allow)
- access_allow = (char*)aRealloc(access_allow, (access_allownum+1) * ACO_STRSIZE);
- else
- access_allow = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
- strncpy(access_allow + (access_allownum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
- access_allow[access_allownum * ACO_STRSIZE - 1] = '\0';
- }
+ strncpy(access_allow + (access_allownum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
+ access_allow[access_allownum * ACO_STRSIZE - 1] = '\0';
}
- } else if (strcmpi(w1, "deny") == 0) {
- if (strcmpi(w2, "clear") == 0) {
+ }
+ } else if (strcmpi(w1, "deny") == 0) {
+ if (strcmpi(w2, "clear") == 0) {
+ if (access_deny)
+ aFree(access_deny);
+ access_deny = NULL;
+ access_denynum = 0;
+ } else {
+ if (strcmpi(w2, "all") == 0) {
+ // reset all previous values
if (access_deny)
aFree(access_deny);
- access_deny = NULL;
- access_denynum = 0;
- } else {
- if (strcmpi(w2, "all") == 0) {
- // reset all previous values
- if (access_deny)
- aFree(access_deny);
- // set to all
+ // set to all
+ access_deny = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
+ access_denynum = 1;
+ access_deny[0] = '\0';
+ } else if (w2[0] && !(access_denynum == 1 && access_deny[0] == '\0')) { // don't add IP if already 'all'
+ if (access_deny)
+ access_deny = (char*)aRealloc(access_deny, (access_denynum+1) * ACO_STRSIZE);
+ else
access_deny = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
- access_denynum = 1;
- access_deny[0] = '\0';
- } else if (w2[0] && !(access_denynum == 1 && access_deny[0] == '\0')) { // don't add IP if already 'all'
- if (access_deny)
- access_deny = (char*)aRealloc(access_deny, (access_denynum+1) * ACO_STRSIZE);
- else
- access_deny = (char*)aCalloc(ACO_STRSIZE, sizeof(char));
- strncpy(access_deny + (access_denynum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
- access_deny[access_denynum * ACO_STRSIZE - 1] = '\0';
- }
+ strncpy(access_deny + (access_denynum++) * ACO_STRSIZE, w2, ACO_STRSIZE);
+ access_deny[access_denynum * ACO_STRSIZE - 1] = '\0';
}
- } else if(strcmpi(w1, "check_client_version") == 0) {
- check_client_version = config_switch(w2);
- } else if(strcmpi(w1, "client_version_to_connect") == 0) {
- client_version_to_connect = atoi(w2);
- } else if (strcmpi(w1, "console") == 0) {
- console = config_switch(w2);
- } else if (strcmpi(w1, "allowed_regs") == 0) { //account flood protection system
- allowed_regs = atoi(w2);
- } else if (strcmpi(w1, "time_allowed") == 0) {
- time_allowed = atoi(w2);
- } else if (strcmpi(w1, "online_check") == 0) {
- online_check = config_switch(w2);
- } else if(strcmpi(w1,"use_dnsbl")==0) {
- use_dnsbl=config_switch(w2);
- } else if(strcmpi(w1,"dnsbl_servers")==0) {
- strcpy(dnsbl_servs,w2);
- } else if(strcmpi(w1,"ip_sync_interval")==0) {
- ip_sync_interval = 1000*60*atoi(w2); //w2 comes in minutes.
- } else if (strcmpi(w1, "import") == 0) {
- login_config_read(w2);
}
+ } else if (strcmpi(w1, "new_account") == 0) {
+ new_account_flag = config_switch(w2);
+ } else if(strcmpi(w1, "check_client_version") == 0) {
+ check_client_version = config_switch(w2);
+ } else if(strcmpi(w1, "client_version_to_connect") == 0) {
+ client_version_to_connect = atoi(w2);
+ } else if (strcmpi(w1, "use_MD5_passwords") == 0) {
+ use_md5_passwds = config_switch(w2);
+ } else if (strcmpi(w1, "min_level_to_connect") == 0) {
+ min_level_to_connect = atoi(w2);
+ } else if (!strcmpi(w1, "date_format")) {
+ strncpy(date_format, w2, sizeof(date_format));
+ } else if (strcmpi(w1, "console") == 0) {
+ console = config_switch(w2);
+ } else if (strcmpi(w1, "allowed_regs") == 0) { //account flood protection system
+ allowed_regs = atoi(w2);
+ } else if (strcmpi(w1, "time_allowed") == 0) {
+ time_allowed = atoi(w2);
+ } else if (strcmpi(w1, "online_check") == 0) {
+ online_check = config_switch(w2);
+ } else if(strcmpi(w1,"use_dnsbl")==0) {
+ use_dnsbl=config_switch(w2);
+ } else if(strcmpi(w1,"dnsbl_servers")==0) {
+ strcpy(dnsbl_servs,w2);
+ } else if(strcmpi(w1,"ip_sync_interval")==0) {
+ ip_sync_interval = 1000*60*atoi(w2); //w2 comes in minutes.
+ } else if (strcmpi(w1, "import") == 0) {
+ login_config_read(w2);
+ }
}
fclose(fp);
ShowInfo("Finished reading %s.\n", cfgName);
diff --git a/src/login_sql/login.c b/src/login_sql/login.c
index fe92c3a96..cc50e560a 100644
--- a/src/login_sql/login.c
+++ b/src/login_sql/login.c
@@ -40,7 +40,7 @@
struct Login_Config {
- in_addr_t login_ip; // the address to bind to
+ uint32 login_ip; // the address to bind to
unsigned short login_port; // the port to bind to
bool log_login; // whether to log login server actions or not
char date_format[32]; // date format used in messages
@@ -71,17 +71,17 @@ struct mmo_char_server server[MAX_SERVERS]; // char server data
// Advanced subnet check [LuzZza]
struct _subnet {
- long subnet;
- long mask;
- long char_ip;
- long map_ip;
+ uint32 subnet;
+ uint32 mask;
+ uint32 char_ip;
+ uint32 map_ip;
} subnet[16];
int subnet_count = 0;
struct gm_account* gm_account_db = NULL;
-int GM_num = 0; // number of gm accounts
+unsigned int GM_num = 0; // number of gm accounts
//Account registration flood protection [Kevin]
int allowed_regs = 1;
@@ -118,7 +118,9 @@ char login_db_level[256] = "level";
#define AUTH_FIFO_SIZE 256
struct {
int account_id,login_id1,login_id2;
- int ip,sex,delflag;
+ uint32 ip;
+ char sex;
+ bool delflag;
} auth_fifo[AUTH_FIFO_SIZE];
int auth_fifo_pos = 0;
@@ -235,12 +237,13 @@ void read_gm_account(void)
//-----------------------------------------------------
void send_GM_accounts(int fd)
{
- int i;
+ unsigned int i;
unsigned char buf[32767];
int len;
if(!login_config.login_gm_read)
return;
+
len = 4;
WBUFW(buf,0) = 0x2732;
for(i = 0; i < GM_num; i++)
@@ -254,16 +257,17 @@ void send_GM_accounts(int fd)
break;
}
}
- WBUFW(buf,2) = len;
- if (fd == -1)
- charif_sendallwos(-1, buf, len);
- else
- {
- WFIFOHEAD(fd, len);
- memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd, len);
- }
- return;
+
+ WBUFW(buf,2) = len;
+ if (fd == -1)
+ charif_sendallwos(-1, buf, len);
+ else
+ {
+ WFIFOHEAD(fd, len);
+ memcpy(WFIFOP(fd,0), buf, len);
+ WFIFOSET(fd, len);
+ }
+ return;
}
//---------------------------------------------------
@@ -497,20 +501,20 @@ int mmo_auth_new(struct mmo_account* account, char sex)
return 0;
}
-// Send to char
+//--------------------------------------------------------------------
+// Packet send to all char-servers, except one (wos: without our self)
+//--------------------------------------------------------------------
int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
{
- int i, c;
- int fd;
+ int i, c, fd;
- c = 0;
- for(i = 0; i < MAX_SERVERS; i++) {
+ for(i = 0, c = 0; i < MAX_SERVERS; i++) {
if ((fd = server_fd[i]) > 0 && fd != sfd) {
- WFIFOHEAD(fd,len);
+ WFIFOHEAD(fd, len);
if (WFIFOSPACE(fd) < len) //Increase buffer size.
realloc_writefifo(fd, len);
memcpy(WFIFOP(fd,0), buf, len);
- WFIFOSET(fd,len);
+ WFIFOSET(fd, len);
c++;
}
}
@@ -532,8 +536,9 @@ int mmo_auth(struct mmo_account* account, int fd)
char md5str[64], md5bin[32];
char ip[16];
- unsigned char* sin_addr = (unsigned char *)&session[fd]->client_addr.sin_addr.s_addr;
- sprintf(ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
+ uint32 ipl = session[fd]->client_addr;
+ uint8* sin_addr = (uint8*)&ipl;
+ sprintf(ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
// DNS Blacklist check
if(login_config.use_dnsbl)
@@ -543,7 +548,7 @@ int mmo_auth(struct mmo_account* account, int fd)
char *dnsbl_serv;
bool matched = false;
- sprintf(r_ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
+ sprintf(r_ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
for (dnsbl_serv = strtok(login_config.dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,","))
{
@@ -720,9 +725,9 @@ int mmo_auth(struct mmo_account* account, int fd)
if (login_config.online_check) {
struct online_login_data* data = idb_get(online_db,account->account_id);
- unsigned char buf[8];
if (data && data->char_server > -1) {
//Request char servers to kick this account out. [Skotlex]
+ unsigned char buf[8];
ShowNotice("User [%s] is already online - Rejected.\n",account->userid);
WBUFW(buf,0) = 0x2734;
WBUFL(buf,2) = account->account_id;
@@ -764,19 +769,18 @@ static int online_db_setoffline(DBKey key, void* data, va_list ap)
return 0;
}
-//-----------------------------------------------------
-// char-server packet parse
-//-----------------------------------------------------
+//--------------------------------
+// Packet parsing for char-servers
+//--------------------------------
int parse_fromchar(int fd)
{
int i, id;
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
- unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
+ uint32 ipl = session[fd]->client_addr;
char ip[16];
RFIFOHEAD(fd);
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ ip2str(ipl, ip);
for(id = 0; id < MAX_SERVERS; id++)
if (server_fd[id] == fd)
@@ -802,14 +806,14 @@ int parse_fromchar(int fd)
return 0;
}
- while(RFIFOREST(fd) >= 2) {
-// printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
+ while (RFIFOREST(fd) >= 2) {
switch (RFIFOW(fd,0)) {
- case 0x2709:
+
+ case 0x2709: // request from map-server via char-server to reload GM accounts
if (login_config.log_login)
{
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`log`) VALUES (NOW(), '%u', '%s', 'GM reload request')", loginlog_db, (unsigned int)ntohl(ipl),server[id].name);
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`log`) VALUES (NOW(), '%u', '%s', 'GM reload request')", loginlog_db, ipl, server[id].name);
if (mysql_query(&mysql_handle, tmpsql)) {
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -821,7 +825,7 @@ int parse_fromchar(int fd)
RFIFOSKIP(fd,2);
break;
- case 0x2712:
+ case 0x2712: // request from char-server to authenticate an account
if (RFIFOREST(fd) < 19)
return 0;
{
@@ -833,7 +837,7 @@ int parse_fromchar(int fd)
auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
auth_fifo[i].sex == RFIFOB(fd,14) &&
- auth_fifo[i].ip == RFIFOL(fd,15) &&
+ auth_fifo[i].ip == ntohl(RFIFOL(fd,15)) &&
!auth_fifo[i].delflag)
{
auth_fifo[i].delflag = 1;
@@ -869,9 +873,10 @@ int parse_fromchar(int fd)
WFIFOB(fd,6) = 1;
WFIFOSET(fd,51);
}
+ }
RFIFOSKIP(fd,19);
break;
- }
+
case 0x2714:
if (RFIFOREST(fd) < 6)
@@ -897,8 +902,7 @@ int parse_fromchar(int fd)
RFIFOSKIP(fd,6);
break;
- // We receive an e-mail/limited time request, because a player comes back from a map-server to the char-server
- case 0x2716:
+ 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)
return 0;
{
@@ -929,10 +933,8 @@ int parse_fromchar(int fd)
RFIFOSKIP(fd,6);
break;
- case 0x2720: // GM
- if (RFIFOREST(fd) < 4)
- return 0;
- if (RFIFOREST(fd) < RFIFOW(fd,2))
+ case 0x2720: // Request to become a GM (TXT only!)
+ if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
//oldacc = RFIFOL(fd,4);
ShowWarning("change GM isn't supported in this login server version.\n");
@@ -995,7 +997,7 @@ int parse_fromchar(int fd)
break;
}
- case 0x2724: // Receiving of map-server via char-server a status change resquest (by Yor)
+ case 0x2724: // Receiving of map-server via char-server a status change resquest
if (RFIFOREST(fd) < 10)
return 0;
{
@@ -1029,7 +1031,7 @@ int parse_fromchar(int fd)
break;
}
- case 0x2725: // Receiving of map-server via char-server a ban resquest (by Yor)
+ case 0x2725: // Receiving of map-server via char-server a ban resquest
if (RFIFOREST(fd) < 18)
return 0;
{
@@ -1084,7 +1086,7 @@ int parse_fromchar(int fd)
break;
}
- case 0x2727:
+ case 0x2727: // Change of sex (sex is reversed)
if (RFIFOREST(fd) < 6)
return 0;
{
@@ -1168,10 +1170,9 @@ int parse_fromchar(int fd)
if (buf) aFree(buf);
}
RFIFOSKIP(fd,RFIFOW(fd,2));
- //printf("login: save account_reg (from char)\n");
break;
- case 0x272a: // Receiving of map-server via char-server a unban resquest (by Yor)
+ case 0x272a: // Receiving of map-server via char-server a unban resquest
if (RFIFOREST(fd) < 6)
return 0;
{
@@ -1209,6 +1210,7 @@ int parse_fromchar(int fd)
remove_online_user(RFIFOL(fd,2));
RFIFOSKIP(fd,6);
break;
+
case 0x272d: // Receive list of all online accounts. [Skotlex]
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
@@ -1270,10 +1272,8 @@ int parse_fromchar(int fd)
case 0x2736: // WAN IP update from char-server
if (RFIFOREST(fd) < 6)
return 0;
- ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id,
- (int)RFIFOB(fd,2),(int)RFIFOB(fd,3),
- (int)RFIFOB(fd,4),(int)RFIFOB(fd,5));
- server[id].ip = RFIFOL(fd,2);
+ server[id].ip = ntohl(RFIFOL(fd,2));
+ ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
RFIFOSKIP(fd,6);
break;
@@ -1284,7 +1284,7 @@ int parse_fromchar(int fd)
break;
default:
- ShowError("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
+ ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", RFIFOW(fd,0));
session[fd]->eof = 1;
return 0;
}
@@ -1297,12 +1297,12 @@ int parse_fromchar(int fd)
//--------------------------------------------
// Test to know if an IP come from LAN or WAN.
//--------------------------------------------
-int lan_subnetcheck(long p)
+int lan_subnetcheck(uint32 ip)
{
int i;
- for(i=0; i<subnet_count; i++) {
- if(subnet[i].subnet == (p & subnet[i].mask)) {
+ for(i = 0; i < subnet_count; i++) {
+ if(subnet[i].subnet == (ip & subnet[i].mask)) {
return subnet[i].char_ip;
}
}
@@ -1310,14 +1310,11 @@ int lan_subnetcheck(long p)
return 0;
}
-int login_ip_ban_check(unsigned char *p, unsigned long ipl)
+int login_ip_ban_check(uint32 ip)
{
- //ip ban
- //p[0], p[1], p[2], p[3]
- //request DB connection
- //check
+ char* p = (char*)&ip;
sprintf(tmpsql, "SELECT count(*) FROM `ipbanlist` WHERE `list` = '%d.*.*.*' OR `list` = '%d.%d.*.*' OR `list` = '%d.%d.%d.*' OR `list` = '%d.%d.%d.%d'",
- p[0], p[0], p[1], p[0], p[1], p[2], p[0], p[1], p[2], p[3]);
+ p[3], p[3], p[2], p[3], p[2], p[1], p[3], p[2], p[1], p[0]);
if (mysql_query(&mysql_handle, tmpsql)) {
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -1338,11 +1335,11 @@ int login_ip_ban_check(unsigned char *p, unsigned long ipl)
}
// ip ban ok.
- ShowInfo("Packet from banned ip : %d.%d.%d.%d\n" RETCODE, p[0], p[1], p[2], p[3]);
+ ShowInfo("Packet from banned ip : %d.%d.%d.%d\n" RETCODE, CONVIP(ip));
if (login_config.log_login)
{
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', 'unknown','-3', 'ip banned')", loginlog_db, (unsigned int)ntohl(ipl));
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', 'unknown','-3', 'ip banned')", loginlog_db, ip);
// query
if(mysql_query(&mysql_handle, tmpsql)) {
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
@@ -1360,16 +1357,13 @@ int parse_login(int fd)
{
char t_uid[100];
struct mmo_account account;
- long subnet_char_ip;
- int packet_len;
int result, i;
- unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
- unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
+ uint32 ipl = session[fd]->client_addr;
char ip[16];
RFIFOHEAD(fd);
- sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ ip2str(ipl, ip);
memset(&account, 0, sizeof(account));
@@ -1381,9 +1375,9 @@ int parse_login(int fd)
return 0;
}
- while(RFIFOREST(fd)>=2 && !session[fd]->eof){
+ while(RFIFOREST(fd) >= 2) {
- switch(RFIFOW(fd,0)){
+ switch(RFIFOW(fd,0)) {
case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
if (RFIFOREST(fd) < 26)
return 0;
@@ -1399,18 +1393,22 @@ int parse_login(int fd)
case 0x277: // New login packet
case 0x64: // request client login
case 0x01dd: // request client login with encrypt
+ {
+ int packet_len = RFIFOREST(fd);
- packet_len = RFIFOREST(fd);
-
- //Perform ip-ban check ONLY on login packets
- if (login_config.ipban && login_ip_ban_check(p,ipl))
+ //Perform ip-ban check
+ if (login_config.ipban && login_ip_ban_check(ipl))
{
+ WFIFOHEAD(fd, 23);
+ WFIFOW(fd,0) = 0x6a;
+ WFIFOB(fd,2) = 3; // 3 = Rejected from Server
+ WFIFOSET(fd,23);
RFIFOSKIP(fd,packet_len);
session[fd]->eof = 1;
break;
}
- switch(RFIFOW(fd,0)){
+ switch(RFIFOW(fd, 0)){
case 0x64:
if(packet_len < 55)
return 0;
@@ -1432,7 +1430,6 @@ int parse_login(int fd)
memcpy(account.passwd,RFIFOP(fd, 30),NAME_LENGTH);
account.passwd[23] = '\0';
-// ShowDebug("client connection request %s from %d.%d.%d.%d\n", RFIFOP(fd, 6), p[0], p[1], p[2], p[3]);
#ifdef PASSWORDENC
account.passwdenc= (RFIFOW(fd,0)!=0x01dd)?0:PASSWORDENC;
#else
@@ -1441,7 +1438,7 @@ int parse_login(int fd)
result=mmo_auth(&account, fd);
jstrescapecpy(t_uid,account.userid);
- if(result==-1){
+ if(result==-1) { // auth success
if (login_config.min_level_to_connect > account.level) {
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
@@ -1449,8 +1446,8 @@ int parse_login(int fd)
WFIFOSET(fd,3);
} else {
WFIFOHEAD(fd,47+32*MAX_SERVERS);
- if (p[0] != 127 && login_config.log_login) {
- sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, (unsigned int)ntohl(ipl), t_uid);
+ if (login_config.log_login) {
+ sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, ipl, t_uid);
//query
if(mysql_query(&mysql_handle, tmpsql)) {
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
@@ -1461,15 +1458,14 @@ int parse_login(int fd)
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);
- server_num=0;
+
+ server_num = 0;
for(i = 0; i < MAX_SERVERS; i++) {
if (server_fd[i] >= 0) {
// Advanced subnet check [LuzZza]
- if((subnet_char_ip = lan_subnetcheck(ipl)))
- WFIFOL(fd,47+server_num*32) = subnet_char_ip;
- else
- WFIFOL(fd,47+server_num*32) = server[i].ip;
- WFIFOW(fd,47+server_num*32+4) = server[i].port;
+ uint32 subnet_char_ip = lan_subnetcheck(ipl);
+ WFIFOL(fd,47+server_num*32) = (subnet_char_ip) ? htonl(subnet_char_ip) : htonl(server[i].ip);
+ WFIFOW(fd,47+server_num*32+4) = server[i].port; // /!\ must be sent in intel host byte order /!\ (client bug)
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;
@@ -1477,34 +1473,33 @@ int parse_login(int fd)
server_num++;
}
}
- // if at least 1 char-server
- if (server_num > 0) {
- WFIFOW(fd,0)=0x69;
- WFIFOW(fd,2)=47+32*server_num;
- WFIFOL(fd,4)=account.login_id1;
- WFIFOL(fd,8)=account.account_id;
- WFIFOL(fd,12)=account.login_id2;
- WFIFOL(fd,16)=0;
- //memcpy(WFIFOP(fd,20),account.lastlogin,24);
- WFIFOB(fd,46)=account.sex;
+ if (server_num > 0) { // if at least 1 char-server
+ WFIFOW(fd,0) = 0x69;
+ WFIFOW(fd,2) = 47+32*server_num;
+ WFIFOL(fd,4) = account.login_id1;
+ WFIFOL(fd,8) = account.account_id;
+ 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)
+ WFIFOB(fd,46) = account.sex;
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;
- auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
- auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
- auth_fifo[auth_fifo_pos].sex=account.sex;
- auth_fifo[auth_fifo_pos].delflag=0;
- auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
+ if (auth_fifo_pos >= AUTH_FIFO_SIZE)
+ auth_fifo_pos = 0;
+ auth_fifo[auth_fifo_pos].account_id = account.account_id;
+ auth_fifo[auth_fifo_pos].login_id1 = account.login_id1;
+ auth_fifo[auth_fifo_pos].login_id2 = account.login_id2;
+ auth_fifo[auth_fifo_pos].sex = account.sex;
+ auth_fifo[auth_fifo_pos].delflag = 0;
+ auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr;
auth_fifo_pos++;
- } else {
+ } else { // if no char-server, don't send void list of servers, just disconnect the player with proper message
WFIFOW(fd,0) = 0x81;
WFIFOB(fd,2) = 1; // 01 = Server closed
WFIFOSET(fd,3);
}
}
- } else {
- WFIFOHEAD(fd,23);
+ } else { // auth failed
+ WFIFOHEAD(fd, 23);
if (login_config.log_login)
{
const char* error;
@@ -1536,7 +1531,7 @@ int parse_login(int fd)
default : error = "Unknown Error."; break;
}
- sprintf(tmpsql, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s', '%d','login failed : %s')", loginlog_db, (unsigned int)ntohl(ipl), t_uid, result, error);
+ sprintf(tmpsql, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s', '%d','login failed : %s')", loginlog_db, ipl, t_uid, result, error);
//query
if(mysql_query(&mysql_handle, tmpsql)) {
@@ -1547,7 +1542,7 @@ int parse_login(int fd)
if ((result == 1) && login_config.dynamic_pass_failure_ban && login_config.log_login) { // failed password
sprintf(tmpsql,"SELECT count(*) FROM `%s` WHERE `ip` = '%u' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
- loginlog_db,(unsigned int)ntohl(ipl), login_config.dynamic_pass_failure_ban_interval); //how many times filed account? in one ip.
+ loginlog_db, ipl, login_config.dynamic_pass_failure_ban_interval); //how many times filed account? in one ip.
if(mysql_query(&mysql_handle, tmpsql)) {
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -1557,7 +1552,8 @@ int parse_login(int fd)
sql_row = sql_res?mysql_fetch_row(sql_res):NULL; //row fetching
if (sql_row && (unsigned int)atoi(sql_row[0]) >= login_config.dynamic_pass_failure_ban_limit ) {
- sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", p[0], p[1], p[2], login_config.dynamic_pass_failure_ban_duration, t_uid);
+ uint8* p = (uint8*)&ipl;
+ sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", (uint8)p[3], (uint8)p[2], (uint8)p[1], login_config.dynamic_pass_failure_ban_duration, t_uid);
if(mysql_query(&mysql_handle, tmpsql)) {
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -1566,7 +1562,8 @@ int parse_login(int fd)
if(sql_res) mysql_free_result(sql_res);
}
else if (result == -2){ //dynamic banned - add ip to ban list.
- sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL 1 MONTH ,'Dynamic banned user id : %s')", p[0], p[1], p[2], t_uid);
+ uint8* p = (uint8*)&ipl;
+ sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL 1 MONTH ,'Dynamic banned user id : %s')", (uint8)p[3], (uint8)p[2], (uint8)p[1], t_uid);
if(mysql_query(&mysql_handle, tmpsql)) {
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -1583,21 +1580,24 @@ int parse_login(int fd)
}
sql_res = mysql_store_result(&mysql_handle) ;
sql_row = sql_res?mysql_fetch_row(sql_res):NULL;
+
//cannot connect login failed
- memset(WFIFOP(fd,0),'\0',23);
- WFIFOW(fd,0)=0x6a;
- WFIFOB(fd,2)=result;
+ memset(WFIFOP(fd,0), '\0', 23);
+ WFIFOW(fd,0) = 0x6a;
+ WFIFOB(fd,2) = result;
if (result == 6) { // 6 = Your are Prohibited to log in until %s
char tmpstr[20];
time_t ban_until_time = (sql_row) ? atol(sql_row[0]) : 0;
- strftime(tmpstr, 20, login_config.date_format, localtime(&ban_until_time));
- tmpstr[19] = '\0';
+ strftime(tmpstr, 20, login_config.date_format, localtime(&ban_until_time)); tmpstr[19] = '\0';
strncpy(WFIFOP(fd,3), tmpstr, 20); // ban timestamp goes here
}
WFIFOSET(fd,23);
+
+ if (sql_res) mysql_free_result(sql_res);
}
RFIFOSKIP(fd,packet_len);
break;
+ }
case 0x01db: // request password key
if (session[fd]->session_data) {
@@ -1606,41 +1606,39 @@ int parse_login(int fd)
return 0;
}
{
- WFIFOHEAD(fd,4+md5keylen);
- WFIFOW(fd,0)=0x01dc;
- WFIFOW(fd,2)=4+md5keylen;
- memcpy(WFIFOP(fd,4),md5key,md5keylen);
- WFIFOSET(fd,WFIFOW(fd,2));
RFIFOSKIP(fd,2);
+ WFIFOHEAD(fd, 4 + md5keylen);
+ WFIFOW(fd,0) = 0x01dc;
+ WFIFOW(fd,2) = 4 + md5keylen;
+ memcpy(WFIFOP(fd,4), md5key, md5keylen);
+ WFIFOSET(fd,WFIFOW(fd,2));
}
break;
- case 0x2710: // request Char-server connection
- if(RFIFOREST(fd)<86)
+ case 0x2710: // Connection request of a char-server
+ if (RFIFOREST(fd) < 86)
return 0;
{
char* server_name;
+ uint32 server_ip;
+ uint16 server_port;
+
WFIFOHEAD(fd, 3);
- memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH);
- account.userid[23] = '\0';
- memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH);
- account.passwd[23] = '\0';
+ memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH); account.userid[23] = '\0';
+ memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH); account.passwd[23] = '\0';
account.passwdenc = 0;
- server_name = (char*)RFIFOP(fd,60);
- server_name[20] = '\0';
- ShowInfo("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
- server_name, RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
- p[0], p[1], p[2], p[3]);
- jstrescapecpy(t_uid,server_name);
+ server_name = (char*)RFIFOP(fd,60); server_name[20] = '\0';
+ 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 (ip: %s)\n",
+ server_name, CONVIP(server_ip), server_port, ip);
+ jstrescapecpy(t_uid, server_name);
if (login_config.log_login)
{
char t_login[50];
jstrescapecpy(t_login,account.userid);
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')",
- loginlog_db, (unsigned int)ntohl(ipl),
- t_login, t_uid, t_uid,
- RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57),
- RFIFOW(fd, 58));
+ loginlog_db, ipl, t_login, t_uid, t_uid, CONVIP(server_ip), server_port);
//query
if(mysql_query(&mysql_handle, tmpsql)) {
@@ -1648,19 +1646,18 @@ int parse_login(int fd)
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
}
}
- result = mmo_auth(&account, fd);
- //printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
- if(result == -1 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]==-1){
+ result = mmo_auth(&account, fd);
+ if (result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server_fd[account.account_id] == -1) {
ShowStatus("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=RFIFOL(fd,54);
- server[account.account_id].port=RFIFOW(fd,58);
- memcpy(server[account.account_id].name,server_name,20);
- 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].ip = ntohl(RFIFOL(fd,54));
+ server[account.account_id].port = ntohs(RFIFOW(fd,58));
+ memcpy(server[account.account_id].name, server_name, 20);
+ 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;
sprintf(tmpsql,"DELETE FROM `sstatus` WHERE `index`='%d'", account.account_id);
//query
if(mysql_query(&mysql_handle, tmpsql)) {
@@ -1675,42 +1672,43 @@ int parse_login(int fd)
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
}
- WFIFOW(fd,0)=0x2711;
- WFIFOB(fd,2)=0;
+ WFIFOW(fd,0) = 0x2711;
+ WFIFOB(fd,2) = 0;
WFIFOSET(fd,3);
- session[fd]->func_parse=parse_fromchar;
- realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
+ session[fd]->func_parse = parse_fromchar;
+ realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
// send GM account to char-server
send_GM_accounts(fd);
} else {
- WFIFOW(fd, 0) =0x2711;
- WFIFOB(fd, 2)=3;
- WFIFOSET(fd, 3);
+ WFIFOW(fd,0) = 0x2711;
+ WFIFOB(fd,2) = 3;
+ WFIFOSET(fd,3);
}
}
- RFIFOSKIP(fd, 86);
+ RFIFOSKIP(fd,86);
return 0;
case 0x7530: // request Athena information
{
+ ShowInfo ("Athena version check...\n");
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;
+ 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);
- ShowInfo ("Athena version check...\n");
break;
}
- case 0x7532:
+ case 0x7532: // Request to end connection
ShowStatus ("End of connection (ip: %s)" RETCODE, ip);
session[fd]->eof = 1;
break;
+
default:
ShowStatus ("Abnormal end of connection (ip: %s): Unknown packet 0x%x " RETCODE, ip, RFIFOW(fd,0));
session[fd]->eof = 1;
@@ -1782,7 +1780,6 @@ int config_switch(const char *str)
return atoi(str);
}
-
//----------------------------------
// Reading Lan Support configuration
//----------------------------------
@@ -1805,7 +1802,7 @@ int login_lan_config_read(const char *lancfgName)
if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
continue;
- line[sizeof(line)-1] = '\0';
+ line[sizeof(line)-1] = '\0';
if(sscanf(line,"%[^:]: %[^:]:%[^:]:%[^\r\n]", w1, w2, w3, w4) != 4) {
ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);
@@ -1819,9 +1816,9 @@ int login_lan_config_read(const char *lancfgName)
if(strcmpi(w1, "subnet") == 0) {
- subnet[subnet_count].mask = inet_addr(w2);
- subnet[subnet_count].char_ip = inet_addr(w3);
- subnet[subnet_count].map_ip = inet_addr(w4);
+ subnet[subnet_count].mask = ntohl(inet_addr(w2));
+ subnet[subnet_count].char_ip = ntohl(inet_addr(w3));
+ subnet[subnet_count].map_ip = ntohl(inet_addr(w4));
subnet[subnet_count].subnet = subnet[subnet_count].char_ip&subnet[subnet_count].mask;
if (subnet[subnet_count].subnet != (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);
@@ -1851,9 +1848,9 @@ int ip_ban_flush(int tid, unsigned int tick, int id, int data)
return 0;
}
-//-----------------------------------------------------
+//-----------------------------------
// Reading main configuration file
-//-----------------------------------------------------
+//-----------------------------------
int login_config_read(const char* cfgName)
{
char line[1024], w1[1024], w2[1024];
@@ -1867,11 +1864,12 @@ int login_config_read(const char* cfgName)
{
if (line[0] == '/' && line[1] == '/')
continue;
+
if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) < 2)
continue;
- remove_control_chars((unsigned char *) w1);
- remove_control_chars((unsigned char *) w2);
+ remove_control_chars((unsigned char *)w1);
+ remove_control_chars((unsigned char *)w2);
if(!strcmpi(w1,"timestamp_format")) {
strncpy(timestamp_format, w2, 20);
@@ -1890,6 +1888,9 @@ int login_config_read(const char* cfgName)
login_config.login_port = (unsigned short)atoi(w2);
ShowStatus("set login_port : %s\n",w2);
}
+ else if (!strcmpi(w1, "log_login"))
+ login_config.log_login = config_switch(w2);
+
else if (!strcmpi(w1,"ipban"))
login_config.ipban = config_switch(w2);
else if (!strcmpi(w1,"dynamic_pass_failure_ban"))
@@ -1923,8 +1924,6 @@ int login_config_read(const char* cfgName)
time_allowed = atoi(w2);
else if (!strcmpi(w1, "online_check"))
login_config.online_check = config_switch(w2);
- else if (!strcmpi(w1, "log_login"))
- login_config.log_login = config_switch(w2);
else if (!strcmpi(w1,"use_dnsbl"))
login_config.use_dnsbl = config_switch(w2);
else if (!strcmpi(w1,"dnsbl_servers"))
diff --git a/src/login_sql/login.h b/src/login_sql/login.h
index 0115126ef..110c6a876 100644
--- a/src/login_sql/login.h
+++ b/src/login_sql/login.h
@@ -42,8 +42,8 @@ struct mmo_account {
struct mmo_char_server {
char name[20];
- long ip;
- short port;
+ uint32 ip;
+ uint16 port;
int users;
int maintenance;
int new_;
diff --git a/src/map/chrif.c b/src/map/chrif.c
index d432320d3..8596ad2f2 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -24,18 +24,14 @@
#include "status.h"
#include "mercenary.h"
-//Updated table (only doc^^) [Sirius]
-//Used Packets: U->2af8
-//Free Packets: F->2af8
-
struct dbt *auth_db;
-static const int packet_len_table[0x3d] = {
+static const int packet_len_table[0x3d] = { // U - used, F - free
60, 3,-1,27,10,-1, 6,-1, // 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff
6,-1,18, 7,-1,49,30,10, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07
6,30,-1,10,86, 7,44,34, // 2b08-2b0f: U->2b08, U->2b09, U->2b0a, U->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
0,-1,10, 6,11,-1, 0, 0, // 2b10-2b17: U->2b10, U->2b11, U->2b12, U->2b13, U->2b14, U->2b15, U->2b16, U->2b17
- -1,-1,-1,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
+ -1,-1,-1,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
-1,10, 8,-1,-1,-1,-1,-1, // 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, F->2b24, F->2b25, F->2b26, F->2b27
};
@@ -89,8 +85,8 @@ int chrif_connected = 0;
int char_fd = 0; //Using 0 instead of -1 is safer against crashes. [Skotlex]
int srvinfo;
static char char_ip_str[128];
-static in_addr_t char_ip= 0;
-static int char_port = 6121;
+static uint32 char_ip = 0;
+static uint16 char_port = 6121;
static char userid[NAME_LENGTH], passwd[NAME_LENGTH];
static int chrif_state = 0;
static int char_init_done = 0;
@@ -103,29 +99,20 @@ int other_mapserver_count=0; //Holds count of how many other map servers are onl
//This define should spare writing the check in every function. [Skotlex]
#define chrif_check(a) { if(!chrif_isconnect()) return a; }
-// 設定ファイル読み込み関係
-/*==========================================
- *
- *------------------------------------------
- */
+
+// sets char-server's user id
void chrif_setuserid(char *id)
{
memcpy(userid, id, NAME_LENGTH);
}
-/*==========================================
- *
- *------------------------------------------
- */
+// sets char-server's password
void chrif_setpasswd(char *pwd)
{
memcpy(passwd, pwd, NAME_LENGTH);
}
-/*==========================================
- *
- *------------------------------------------
- */
+// security check, prints warning if using default password
void chrif_checkdefaultlogin(void)
{
if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
@@ -139,11 +126,8 @@ void chrif_checkdefaultlogin(void)
}
}
-/*==========================================
- *
- *------------------------------------------
- */
-int chrif_setip(const char *ip)
+// sets char-server's ip address
+int chrif_setip(const char* ip)
{
char ip_str[16];
char_ip = host2ip(ip);
@@ -156,30 +140,23 @@ int chrif_setip(const char *ip)
return 1;
}
-/*==========================================
- *
- *------------------------------------------
- */
-void chrif_setport(int port)
+// sets char-server's port number
+void chrif_setport(uint16 port)
{
char_port = port;
}
-/*==========================================
- *
- *------------------------------------------
- */
+// says whether the char-server is connected or not
int chrif_isconnect(void)
{
return (char_fd > 0 && session[char_fd] != NULL && chrif_state == 2);
}
/*==========================================
- * Saves char.
- * Flag = 1: Character is quitting.
+ * Saves character data.
+ * Flag = 1: Character is quitting
* Flag = 2: Character is changing map-servers
- *------------------------------------------
- */
+ *------------------------------------------*/
int chrif_save(struct map_session_data *sd, int flag)
{
nullpo_retr(-1, sd);
@@ -226,10 +203,7 @@ int chrif_save(struct map_session_data *sd, int flag)
return 0;
}
-/*==========================================
- *
- *------------------------------------------
- */
+// connects to char-server (plaintext)
int chrif_connect(int fd)
{
ShowStatus("Logging in to char server...\n", char_fd);
@@ -238,17 +212,14 @@ int chrif_connect(int fd)
memcpy(WFIFOP(fd,2), userid, NAME_LENGTH);
memcpy(WFIFOP(fd,26), passwd, NAME_LENGTH);
WFIFOL(fd,50) = 0;
- WFIFOL(fd,54) = clif_getip_long();
- WFIFOW(fd,58) = clif_getport(); // [Valaris] thanks to fov
+ WFIFOL(fd,54) = htonl(clif_getip());
+ WFIFOW(fd,58) = htons(clif_getport());
WFIFOSET(fd,60);
return 0;
}
-/*==========================================
- * マップ送信
- *------------------------------------------
- */
+// sends maps to char-server
int chrif_sendmap(int fd)
{
int i;
@@ -263,36 +234,31 @@ int chrif_sendmap(int fd)
return 0;
}
-/*==========================================
- * マップ受信
- *------------------------------------------
- */
+// receive maps from some other map-server (relayed via char-server)
int chrif_recvmap(int fd)
{
- int i, j, ip, port;
- unsigned char *p = (unsigned char *)&ip;
+ int i, j;
+ uint32 ip;
+ uint16 port;
RFIFOHEAD(fd);
- ip = RFIFOL(fd,4);
- port = RFIFOW(fd,8);
+ ip = ntohl(RFIFOL(fd,4));
+ port = ntohs(RFIFOW(fd,8));
for(i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) {
map_setipport(RFIFOW(fd,i), ip, port);
-// if (battle_config.etc_log)
-// printf("recv map %d %s\n", j, RFIFOP(fd,i));
}
if (battle_config.etc_log)
- ShowStatus("recv map on %d.%d.%d.%d:%d (%d maps)\n", p[0], p[1], p[2], p[3], port, j);
+ ShowStatus("Received maps from %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
other_mapserver_count++;
return 0;
}
-/*==========================================
- * Delete maps of other servers, (if an other mapserver is going OFF)
- *------------------------------------------
- */
-int chrif_removemap(int fd){
- int i, j, ip, port;
- unsigned char *p = (unsigned char *)&ip;
+// remove specified maps (used when some other map-server disconnects)
+int chrif_removemap(int fd)
+{
+ int i, j;
+ uint32 ip;
+ uint16 port;
RFIFOHEAD(fd);
ip = RFIFOL(fd, 4);
@@ -304,11 +270,13 @@ int chrif_removemap(int fd){
other_mapserver_count--;
if(battle_config.etc_log)
- ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", p[0], p[1], p[2], p[3], port, j);
+ ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
return 0;
}
-int chrif_save_ack(int fd) {
+// received after a character has been "final saved" on the char-server
+int chrif_save_ack(int fd)
+{
struct map_session_data *sd;
RFIFOHEAD(fd);
sd = map_id2sd(RFIFOL(fd,2));
@@ -318,13 +286,10 @@ int chrif_save_ack(int fd) {
return 0;
}
-/*==========================================
- * マップ鯖間移動のためのデータ準備要求
- *------------------------------------------
- */
-int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y, int ip, short port)
+// request to move a character between mapservers
+int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y, uint32 ip, uint16 port)
{
- int s_ip;
+ uint32 s_ip;
nullpo_retr(-1, sd);
@@ -337,7 +302,7 @@ int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y,
}
if (sd->fd && sd->fd < fd_max && session[sd->fd])
- s_ip = session[sd->fd]->client_addr.sin_addr.s_addr;
+ s_ip = session[sd->fd]->client_addr;
else //Not connected? Can't retrieve IP
s_ip = 0;
@@ -350,19 +315,16 @@ int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y,
WFIFOW(char_fd,18) = map;
WFIFOW(char_fd,20) = x;
WFIFOW(char_fd,22) = y;
- WFIFOL(char_fd,24) = ip;
- WFIFOW(char_fd,28) = port;
+ WFIFOL(char_fd,24) = htonl(ip);
+ WFIFOW(char_fd,28) = htons(port);
WFIFOB(char_fd,30) = sd->status.sex;
- WFIFOL(char_fd,31) = s_ip;
+ WFIFOL(char_fd,31) = htonl(s_ip); // not used
WFIFOSET(char_fd,35);
return 0;
}
-/*==========================================
- * マップ鯖間移動ack
- *------------------------------------------
- */
+// map-server change request acknowledgement (positive or negative)
int chrif_changemapserverack(int fd)
{
struct map_session_data *sd;
@@ -380,7 +342,7 @@ int chrif_changemapserverack(int fd)
return 0;
}
sprintf(mapname, "%s.gat", mapindex_id2name(RFIFOW(fd,18)));
- clif_changemapserver(sd, mapname, RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28));
+ clif_changemapserver(sd, mapname, RFIFOW(fd,20), RFIFOW(fd,22), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28)));
//Player has been saved already, remove him from memory. [Skotlex]
map_quit(sd);
@@ -390,8 +352,7 @@ int chrif_changemapserverack(int fd)
/*==========================================
*
- *------------------------------------------
- */
+ *------------------------------------------*/
int chrif_connectack(int fd)
{
RFIFOHEAD(fd);
@@ -568,7 +529,7 @@ int auth_db_cleanup(int tid, unsigned int tick, int id, int data) {
*
*------------------------------------------
*/
-int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip)
+int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip)
{
nullpo_retr(-1, sd);
@@ -581,7 +542,7 @@ int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip)
WFIFOL(char_fd, 2) = sd->bl.id;
WFIFOL(char_fd, 6) = sd->login_id1;
WFIFOL(char_fd,10) = sd->login_id2;
- WFIFOL(char_fd,14) = s_ip;
+ WFIFOL(char_fd,14) = htonl(s_ip);
WFIFOSET(char_fd,18);
return 0;
@@ -693,7 +654,6 @@ int chrif_changesex(int id, int sex) {
WFIFOW(char_fd,2) = 9;
WFIFOL(char_fd,4) = id;
WFIFOB(char_fd,8) = sex;
-// ShowInfo("chrif : sent 0x3000(changesex)\n");
WFIFOSET(char_fd,9);
return 0;
}
@@ -1040,7 +1000,8 @@ int chrif_accountban(int fd)
//Disconnect the player out of the game, simple packet
//packet.w AID.L WHY.B 2+4+1 = 7byte
-int chrif_disconnectplayer(int fd){
+int chrif_disconnectplayer(int fd)
+{
struct map_session_data *sd;
RFIFOHEAD(fd);
@@ -1419,7 +1380,7 @@ int chrif_disconnect(int fd) {
void chrif_update_ip(int fd)
{
- unsigned long new_ip;
+ uint32 new_ip;
WFIFOHEAD(fd, 6);
new_ip = host2ip(char_ip_str);
if (new_ip && new_ip != char_ip)
@@ -1428,7 +1389,7 @@ void chrif_update_ip(int fd)
new_ip = clif_refresh_ip();
if (!new_ip) return; //No change
WFIFOW(fd, 0) = 0x2736;
- WFIFOL(fd, 2) = new_ip;
+ WFIFOL(fd, 2) = htonl(new_ip);
WFIFOSET(fd, 6);
}
@@ -1452,7 +1413,7 @@ int chrif_parse(int fd)
return 0;
}
- while (RFIFOREST(fd) >= 2 && !session[fd]->eof) { //Infinite loop on broken pipe fix. [Skotlex]
+ while (RFIFOREST(fd) >= 2) { //Infinite loop on broken pipe fix. [Skotlex]
RFIFOHEAD(fd);
cmd = RFIFOW(fd,0);
if (cmd < 0x2af8 || cmd >= 0x2af8 + (sizeof(packet_len_table) / sizeof(packet_len_table[0])) ||
diff --git a/src/map/chrif.h b/src/map/chrif.h
index 92a719929..adbf0ab2f 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -12,11 +12,11 @@ struct auth_node{
unsigned int node_created; //For node auto-deleting
};
-void chrif_setuserid(char*);
-void chrif_setpasswd(char*);
+void chrif_setuserid(char* id);
+void chrif_setpasswd(char* pwd);
void chrif_checkdefaultlogin(void);
-int chrif_setip(const char*);
-void chrif_setport(int);
+int chrif_setip(const char* ip);
+void chrif_setport(uint16 port);
int chrif_isconnect(void);
@@ -27,9 +27,9 @@ void chrif_authreq(struct map_session_data *);
void chrif_authok(int fd);
int chrif_scdata_request(int account_id, int char_id);
int chrif_save(struct map_session_data*, int flag);
-int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip);
+int chrif_charselectreq(struct map_session_data*sd, uint32 s_ip);
void check_fake_id(int fd, struct map_session_data *sd, int target_id);
-int chrif_changemapserver(struct map_session_data *sd,short map,int x,int y,int ip,short port);
+int chrif_changemapserver(struct map_session_data*sd, short map, int x, int y, uint32 ip, uint16 port);
int chrif_searchcharid(int char_id);
int chrif_changegm(int id,const char *pass,int len);
diff --git a/src/map/clif.c b/src/map/clif.c
index 366fdbec9..fdba61dba 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -96,9 +96,9 @@ struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
//Guarantees that the given string does not exceeds the allowed size, as well as making sure it's null terminated. [Skotlex\]
#define mes_len_check(mes, len, max) if (len > max) { mes[max-1] = '\0'; len = max; } else mes[len-1] = '\0';
static char map_ip_str[128];
-static in_addr_t map_ip;
-static in_addr_t bind_ip = INADDR_ANY;
-static int map_port = 5121;
+static uint32 map_ip;
+static uint32 bind_ip = INADDR_ANY;
+static uint16 map_port = 5121;
int map_fd;
//These two will be used to verify the incoming player's validity.
@@ -142,7 +142,7 @@ void clif_setbindip(const char* ip)
* map鯖のport設定
*------------------------------------------
*/
-void clif_setport(int port)
+void clif_setport(uint16 port)
{
map_port = port;
}
@@ -151,27 +151,21 @@ void clif_setport(int port)
* map鯖のip読み出し
*------------------------------------------
*/
-in_addr_t clif_getip(void)
+uint32 clif_getip(void)
{
return map_ip;
}
-//Returns the ip casted as a basic type, to avoid needing to include the socket/net related libs by calling modules.
-unsigned long clif_getip_long(void)
-{
- return (unsigned long)map_ip;
-}
-
//Refreshes map_server ip, returns the new ip if the ip changed, otherwise it returns 0.
-unsigned long clif_refresh_ip(void)
+uint32 clif_refresh_ip(void)
{
- in_addr_t new_ip;
+ uint32 new_ip;
new_ip = host2ip(map_ip_str);
if (new_ip && new_ip != map_ip) {
map_ip = new_ip;
- ShowInfo("Updating IP resolution of [%s].\n",map_ip_str);
- return (unsigned long)map_ip;
+ ShowInfo("Updating IP resolution of [%s].\n", map_ip_str);
+ return map_ip;
}
return 0;
}
@@ -180,7 +174,7 @@ unsigned long clif_refresh_ip(void)
* map鯖のport読み出し
*------------------------------------------
*/
-int clif_getport(void)
+uint16 clif_getport(void)
{
return map_port;
}
@@ -1625,10 +1619,10 @@ int clif_changemap(struct map_session_data *sd, short map, int x, int y) {
}
/*==========================================
- *
- *------------------------------------------
- */
-int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, int ip, int port) {
+ * Tells the client to connect to another map-server
+ *------------------------------------------*/
+int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, uint32 ip, uint16 port)
+{
int fd;
nullpo_retr(0, sd);
@@ -1641,8 +1635,8 @@ int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x
WFIFOB(fd,17) = 0; //Null terminator for mapname
WFIFOW(fd,18) = x;
WFIFOW(fd,20) = y;
- WFIFOL(fd,22) = ip;
- WFIFOW(fd,26) = port;
+ WFIFOL(fd,22) = htonl(ip);
+ WFIFOW(fd,26) = port; // /!\ must be sent in intel host byte order /!\ (client bug)
WFIFOSET(fd, packet_len(0x92));
return 0;
@@ -8862,7 +8856,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
/* Rovert's Prevent logout option - Fixed [Valaris] */
if (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
{ //Send to char-server for character selection.
- chrif_charselectreq(sd, session[fd]->client_addr.sin_addr.s_addr);
+ chrif_charselectreq(sd, session[fd]->client_addr);
} else {
WFIFOHEAD(fd,packet_len(0x18b));
WFIFOW(fd,0)=0x18b;
@@ -11746,7 +11740,8 @@ void clif_parse_debug(int fd,struct map_session_data *sd)
* socket.cのdo_parsepacketから呼び出される
*------------------------------------------
*/
-int clif_parse(int fd) {
+int clif_parse(int fd)
+{
int packet_len = 0, cmd, packet_ver, err, dump = 0;
TBL_PC *sd;
RFIFOHEAD(fd);
@@ -11772,8 +11767,8 @@ int clif_parse(int fd) {
map_quit(sd);
}
} else {
- unsigned char *ip = (unsigned char *) &session[fd]->client_addr.sin_addr;
- ShowInfo("Closed connection from '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", ip[0],ip[1],ip[2],ip[3]);
+ uint32 ip = session[fd]->client_addr;
+ ShowInfo("Closed connection from '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", CONVIP(ip));
}
do_close(fd);
return 0;
@@ -12321,8 +12316,8 @@ static int packetdb_readdb(void)
*
*------------------------------------------
*/
-int do_init_clif(void) {
-
+int do_init_clif(void)
+{
clif_config.packet_db_ver = -1; // the main packet version of the DB
memset(clif_config.connect_cmd, 0, sizeof(clif_config.connect_cmd)); //The default connect command will be determined after reading the packet_db [Skotlex]
diff --git a/src/map/clif.h b/src/map/clif.h
index c9e48c986..af5bcdd8d 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -52,11 +52,11 @@ extern struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
int clif_setip(const char* ip);
void clif_setbindip(const char* ip);
-void clif_setport(int);
+void clif_setport(uint16 port);
-unsigned long clif_getip_long(void);
-unsigned long clif_refresh_ip(void);
-int clif_getport(void);
+uint32 clif_getip(void);
+uint32 clif_refresh_ip(void);
+uint16 clif_getport(void);
int clif_countusers(void);
void clif_setwaitclose(int);
@@ -75,7 +75,7 @@ int clif_spawn(struct block_list*); //area
int clif_walkok(struct map_session_data*); // self
void clif_move(struct unit_data *ud); //area
int clif_changemap(struct map_session_data*,short,int,int); //self
-int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, int ip, int port); //self
+int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, uint32 ip, uint16 port); //self
int clif_blown(struct block_list *); // area
int clif_slide(struct block_list *,int,int); // area
int clif_fixpos(struct block_list *); // area
diff --git a/src/map/map.c b/src/map/map.c
index a28ac20c5..4c38c3754 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2077,9 +2077,9 @@ int map_mapindex2mapid(unsigned short mapindex) {
/*==========================================
* 他鯖map名からip,port?換
- *------------------------------------------
- */
-int map_mapname2ipport(unsigned short name,int *ip,int *port) {
+ *------------------------------------------*/
+int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port)
+{
struct map_data_other_server *mdos=NULL;
mdos = (struct map_data_other_server*)uidb_get(map_db,(unsigned int)name);
@@ -2349,16 +2349,17 @@ static void* create_map_data_other_server(DBKey key, va_list args) {
}
/*==========================================
* 他鯖管理のマップをdbに追加
- *------------------------------------------
- */
-int map_setipport(unsigned short mapindex,unsigned long ip,int port) {
+ *------------------------------------------*/
+
+int map_setipport(unsigned short mapindex, uint32 ip, uint16 port)
+{
struct map_data_other_server *mdos=NULL;
mdos=(struct map_data_other_server *)uidb_ensure(map_db,(unsigned int)mapindex, create_map_data_other_server);
if(mdos->gat) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex]
return 0;
- if(ip == clif_getip_long() && port == clif_getport()) {
+ if(ip == clif_getip() && port == clif_getport()) {
//That's odd, we received info that we are the ones with this map, but... we don't have it.
ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(mapindex));
exit(1);
@@ -2388,12 +2389,10 @@ int map_eraseallipport(void) {
/*==========================================
* 他鯖管理のマップをdbから削除
- *------------------------------------------
- */
-int map_eraseipport(unsigned short mapindex,unsigned long ip,int port)
+ *------------------------------------------*/
+int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port)
{
struct map_data_other_server *mdos;
-// unsigned char *p=(unsigned char *)&ip;
mdos = uidb_get(map_db,(unsigned int)mapindex);
if(!mdos || mdos->gat) //Map either does not exists or is a local map.
diff --git a/src/map/map.h b/src/map/map.h
index 2e433c619..96b2b79b8 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -1109,8 +1109,8 @@ struct map_data_other_server {
char name[MAP_NAME_LENGTH];
unsigned short index; //Index is the map index used by the mapindex* functions.
unsigned char *gat; // NULL固定にして判断
- unsigned long ip;
- unsigned int port;
+ uint32 ip;
+ uint16 port;
};
struct flooritem_data {
@@ -1339,9 +1339,9 @@ struct map_session_data * map_id2sd(int);
struct block_list * map_id2bl(int);
int map_mapindex2mapid(unsigned short mapindex);
int map_mapname2mapid(const char* name);
-int map_mapname2ipport(unsigned short,int*,int*);
-int map_setipport(unsigned short map,unsigned long ip,int port);
-int map_eraseipport(unsigned short map,unsigned long ip,int port);
+int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port);
+int map_setipport(unsigned short map, uint32 ip, uint16 port);
+int map_eraseipport(unsigned short map, uint32 ip, uint16 port);
int map_eraseallipport(void);
void map_addiddb(struct block_list *);
void map_deliddb(struct block_list *bl);
diff --git a/src/map/pc.c b/src/map/pc.c
index 7ba8a8b87..24088ff61 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -698,20 +698,20 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
sd->state.event_kill_mob = 1;
{ //Add IP field
- unsigned char *ip = (unsigned char *) &session[sd->fd]->client_addr.sin_addr;
+ uint32 ip = session[sd->fd]->client_addr;
if (pc_isGM(sd))
ShowInfo("GM '"CL_WHITE"%s"CL_RESET"' logged in."
" (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
" Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"',"
" GM Level '"CL_WHITE"%d"CL_RESET"').\n",
sd->status.name, sd->status.account_id, sd->status.char_id,
- sd->packet_ver, ip[0],ip[1],ip[2],ip[3], pc_isGM(sd));
+ sd->packet_ver, CONVIP(ip), pc_isGM(sd));
else
ShowInfo("'"CL_WHITE"%s"CL_RESET"' logged in."
" (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
" Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"').\n",
sd->status.name, sd->status.account_id, sd->status.char_id,
- sd->packet_ver, ip[0],ip[1],ip[2],ip[3]);
+ sd->packet_ver, CONVIP(ip));
}
// Send friends list
@@ -3371,10 +3371,11 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
sd->regen.state.gc = 0;
}
- if(m<0){
- if(sd->mapindex){
- int ip,port;
- if(map_mapname2ipport(mapindex,&ip,&port)==0){
+ if(m<0) {
+ if(sd->mapindex) {
+ uint32 ip;
+ uint16 port;
+ if(map_mapname2ipport(mapindex,&ip,&port)==0) {
unit_remove_map(&sd->bl,clrtype);
sd->mapindex = mapindex;
sd->bl.x=x;