summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/clif.c111
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;