diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-04-05 18:49:57 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-04-05 18:49:57 +0000 |
commit | 88a5d0cdda513357496b9d53878618e1620f47e8 (patch) | |
tree | 4f3c2bedbac4b715ff783de5e1c8d1aefe4395af /src | |
parent | a7fd6bfe9bcce1862b554f5841d9ff1aedf473e3 (diff) | |
download | hercules-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.c | 426 | ||||
-rw-r--r-- | src/char_sql/char.c | 588 | ||||
-rw-r--r-- | src/common/mmo.h | 4 | ||||
-rw-r--r-- | src/common/socket.c | 70 | ||||
-rw-r--r-- | src/common/socket.h | 18 | ||||
-rw-r--r-- | src/common/strlib.c | 46 | ||||
-rw-r--r-- | src/common/strlib.h | 17 | ||||
-rw-r--r-- | src/common/utils.c | 46 | ||||
-rw-r--r-- | src/login/login.c | 773 | ||||
-rw-r--r-- | src/login_sql/login.c | 361 | ||||
-rw-r--r-- | src/login_sql/login.h | 4 | ||||
-rw-r--r-- | src/map/chrif.c | 147 | ||||
-rw-r--r-- | src/map/chrif.h | 12 | ||||
-rw-r--r-- | src/map/clif.c | 51 | ||||
-rw-r--r-- | src/map/clif.h | 10 | ||||
-rw-r--r-- | src/map/map.c | 21 | ||||
-rw-r--r-- | src/map/map.h | 10 | ||||
-rw-r--r-- | src/map/pc.c | 15 |
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; |