diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/clif.c | 111 |
1 files changed, 80 insertions, 31 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index b6eb99d9e..230c1662c 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -8101,42 +8101,72 @@ void clif_feel_hate_reset(struct map_session_data *sd) // clif_guess_PacketVer // --------------------- // Parses a WantToConnection packet to try to identify which is the packet version used. [Skotlex] -static int clif_guess_PacketVer(int fd, int get_previous) -{ +// error codes: +// 0 - Success +// 1 - Unknown packet_ver +// 2 - Invalid account_id +// 3 - Invalid char_id +// 4 - Invalid login_id1 (reserved) +// 5 - Invalid client_tick (reserved) +// 6 - Invalid sex +// Only the first 'invalid' error that appears is used. +static int clif_guess_PacketVer(int fd, int get_previous, int *error) +{ + static int err = 1; static int packet_ver = -1; int cmd, packet_len, value; //Value is used to temporarily store account/char_id/sex RFIFOHEAD(fd); - - if (get_previous) //For quick reruns, since the normal code flow is to fetch this once to identify the packet version, then again in the wanttoconnect function. [Skotlex] + + if (get_previous) + {//For quick reruns, since the normal code flow is to fetch this once to identify the packet version, then again in the wanttoconnect function. [Skotlex] + if( error ) + *error = err; return packet_ver; + } - //By default, start searching on the default one. + //By default, start searching on the default one. + err = 1; packet_ver = clif_config.packet_db_ver; cmd = RFIFOW(fd,0); packet_len = RFIFOREST(fd); -#define IS_PACKET_VER \ -(\ - ( cmd == clif_config.connect_cmd[packet_ver] ) /* it's the wanttoconnection for this version. */ &&\ - ( packet_len == packet_db[packet_ver][cmd].len ) /* has the right size */ &&\ - ( (value=(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[0])) >= START_ACCOUNT_NUM && value <= max_account_id ) /* valid account ID */ &&\ - ( (value=(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[1])) > 0 && value <= max_char_id ) /* valid char ID */ &&\ - /* RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]) - don't care about login_id1 */\ - /* RFIFOL(fd, packet_db[packet_ver][cmd].pos[3]) - don't care about client_tick */\ - ( (value=(int)RFIFOB(fd, packet_db[packet_ver][cmd].pos[4])) == 0 || value == 1 ) /* valid sex */\ -) - - if (IS_PACKET_VER) - return clif_config.packet_db_ver; //Default packet version found. +#define SET_ERROR(n) \ + if( err == 1 )\ + err = n;\ +//define SET_ERROR + +#define CHECK_PACKET_VER() \ + if( cmd != clif_config.connect_cmd[packet_ver] || packet_len != packet_db[packet_ver][cmd].len )\ + ;/* not wanttoconnection or wrong length */\ + else if( (value=(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[0])) < START_ACCOUNT_NUM || value > max_account_id )\ + { SET_ERROR(2); }/* invalid account_id */\ + else if( (value=(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[1])) <= 0 || value > max_char_id )\ + { SET_ERROR(3); }/* invalid char_id */\ + /* RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]) - don't care about login_id1 */\ + /* RFIFOL(fd, packet_db[packet_ver][cmd].pos[3]) - don't care about client_tick */\ + else if( (value=(int)RFIFOB(fd, packet_db[packet_ver][cmd].pos[4])) != 0 && value != 1 )\ + { SET_ERROR(6); }/* invalid sex */\ + else\ + {\ + err = 0;\ + if( error )\ + *error = 0;\ + return packet_ver;\ + }\ +//define CHECK_PACKET_VER + + CHECK_PACKET_VER();//Default packet version found. for (packet_ver = MAX_PACKET_VER; packet_ver > 0; packet_ver--) { //Start guessing the version, giving priority to the newer ones. [Skotlex] - if (IS_PACKET_VER) - return packet_ver; //This is our best guess. + CHECK_PACKET_VER(); } + if( error ) + *error = err; packet_ver = -1; return -1; -#undef IS_PACKET_VER +#undef SET_ERROR +#undef CHECK_PACKET_VER } // ------------ @@ -8161,7 +8191,7 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd) return; } - packet_ver = clif_guess_PacketVer(fd, 1); + packet_ver = clif_guess_PacketVer(fd, 1, NULL); cmd = RFIFOW(fd,0); if (packet_ver <= 0) @@ -11729,7 +11759,7 @@ void clif_parse_debug(int fd,struct map_session_data *sd) *------------------------------------------ */ int clif_parse(int fd) { - int packet_len = 0, cmd, packet_ver, dump = 0; + int packet_len = 0, cmd, packet_ver, err, dump = 0; TBL_PC *sd; RFIFOHEAD(fd); @@ -11820,27 +11850,46 @@ int clif_parse(int fd) { if (sd) { packet_ver = sd->packet_ver; if (packet_ver < 0 || packet_ver > MAX_PACKET_VER) { // This should never happen unless we have some corrupted memory issues :X [Skotlex] - ShowWarning("clif_parse: Invalid packet_ver=%d (AID/CID: %d:%d), disconnecting session #%d.", packet_ver, sd->status.account_id, sd->status.char_id, fd); + ShowWarning("clif_parse: Disconnecting session #%d (AID:%d/CID:%d) for having invalid packet_ver=%d.", fd, sd->status.account_id, sd->status.char_id, packet_ver); session[fd]->eof = 1; return 0; } } else { // check authentification packet to know packet version - packet_ver = clif_guess_PacketVer(fd, 0); - // check if version is accepted - if (packet_ver < 5 || // reject really old client versions + err = clif_guess_PacketVer(fd, 0, &packet_ver); + if (err || // unknown packet version + packet_ver < 5 || // reject really old client versions (packet_ver <= 9 && (battle_config.packet_ver_flag & 1) == 0) || // older than 6sept04 (packet_ver > 9 && (battle_config.packet_ver_flag & 1<<(packet_ver-9)) == 0) || packet_ver > MAX_PACKET_VER) // no packet version support yet { - ShowInfo("clif_parse: Disconnecting session #%d for not having latest client version (has version %d).\n", fd, packet_ver); - WFIFOHEAD(fd, 23); + if( err ) + {// failed to identify + ShowInfo("clif_parse: Disconnecting session #%d with unknown packet version%s.\n", fd, ( + err == 1 ? "" : + err == 2 ? ", possibly for having an invalid account_id" : + err == 3 ? ", possibly for having an invalid char_id." : + /* Uncomment when checks are added in clif_guess_PacketVer. [FlavioJS] + err == 4 ? ", possibly for having an invalid login_id1." : + err == 5 ? ", possibly for having an invalid client_tick." : + */ + err == 6 ? ", possibly for having an invalid sex." : + ". ERROR invalid error code")); + err = 3; // 3 = Rejected from Server + } + else + {// version not accepted + ShowInfo("clif_parse: Disconnecting session #%d for not having latest client version (has version %d).\n", fd, packet_ver); + err = 5; // 05 = Game's EXE is not the latest version + } + WFIFOHEAD(fd,packet_len_table[0x6a]); WFIFOW(fd,0) = 0x6a; - WFIFOB(fd,2) = 5; // 05 = Game's EXE is not the latest version - WFIFOSET(fd,23); + WFIFOB(fd,2) = err; + WFIFOSET(fd,packet_len_table[0x6a]); packet_len = RFIFOREST(fd); RFIFOSKIP(fd, packet_len); clif_setwaitclose(fd); + //## TODO check if it still doesn't send and why. [FlavioJS] if (session[fd]->func_send) //socket.c doesn't wants to send the data when left on it's own... [Skotlex] session[fd]->func_send(fd); return 0; |