瀏覽代碼

* 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://svn.code.sf.net/p/rathena/svn/trunk@10162 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 18 年之前
父節點
當前提交
8dc1b77f03
共有 19 個文件被更改,包括 983 次插入1178 次删除
  1. 11 0
      Changelog-Trunk.txt
  2. 188 203
      src/char/char.c
  3. 197 276
      src/char_sql/char.c
  4. 2 2
      src/common/mmo.h
  5. 34 36
      src/common/socket.c
  6. 9 9
      src/common/socket.h
  7. 25 21
      src/common/strlib.c
  8. 6 11
      src/common/strlib.h
  9. 18 28
      src/common/utils.c
  10. 200 254
      src/login/login.c
  11. 180 181
      src/login_sql/login.c
  12. 2 2
      src/login_sql/login.h
  13. 54 93
      src/map/chrif.c
  14. 6 6
      src/map/chrif.h
  15. 23 28
      src/map/clif.c
  16. 5 5
      src/map/clif.h
  17. 10 11
      src/map/map.c
  18. 5 5
      src/map/map.h
  19. 8 7
      src/map/pc.c

+ 11 - 0
Changelog-Trunk.txt

@@ -3,6 +3,17 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2007/04/06
+	* 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 [ultramage]
+	- 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!)
 2007/04/05
 	* Cleaned @whogm. It will display the name of all gms online. If their GM
 	  level is above your own, it will only display their name, otherwise level,

文件差異過大導致無法顯示
+ 188 - 203
src/char/char.c


文件差異過大導致無法顯示
+ 197 - 276
src/char_sql/char.c


+ 2 - 2
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];

+ 34 - 36
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);
 }

+ 9 - 9
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);
 

+ 25 - 21
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;
 

+ 6 - 11
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

+ 18 - 28
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)

文件差異過大導致無法顯示
+ 200 - 254
src/login/login.c


+ 180 - 181
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"))

+ 2 - 2
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_;

+ 54 - 93
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])) ||

+ 6 - 6
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);

+ 23 - 28
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]
 

+ 5 - 5
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

+ 10 - 11
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.

+ 5 - 5
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ŒÅ’è‚É‚µ‚Ä”»’f
-	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);

+ 8 - 7
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;

部分文件因文件數量過多而無法顯示