aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTest_User <hax@andrewyu.org>2024-08-07 20:09:04 -0400
committerTest_User <hax@andrewyu.org>2024-08-07 20:09:19 -0400
commitc00f2cbfddbb42d2950210aa1966efa339ff28f5 (patch)
tree9dc12336437e678a2b8b82574c210a367bb8341f
parent6d1ddd0251b12c6c46e0fff3ad6575eae9d7e1a3 (diff)
downloadhaxircd-c00f2cbfddbb42d2950210aa1966efa339ff28f5.tar.gz
haxircd-c00f2cbfddbb42d2950210aa1966efa339ff28f5.zip
Add membership id handling for incoming inspircd 3/4 KICKs
-rw-r--r--protocols/inspircd3.c39
-rw-r--r--protocols/inspircd4.c39
2 files changed, 66 insertions, 12 deletions
diff --git a/protocols/inspircd3.c b/protocols/inspircd3.c
index e3dca1c..b7b4d73 100644
--- a/protocols/inspircd3.c
+++ b/protocols/inspircd3.c
@@ -1920,7 +1920,7 @@ int inspircd3_protocol_handle_part(struct string source, size_t argc, struct str
return 0;
}
-// [:source] KICK <channel> <user> [<reason>]
+// [:source] KICK <channel> <user> [<member id>] [<reason>]
int inspircd3_protocol_handle_kick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) {
if (argc < 2) {
WRITES(2, STRING("[InspIRCd v3] Invalid KICK received! (Missing parameters)\r\n"));
@@ -1945,11 +1945,38 @@ int inspircd3_protocol_handle_kick(struct string source, size_t argc, struct str
return 0;
}
- int rejoin;
- if (argc > 2)
- rejoin = kick_channel(config->sid, source, channel, user, argv[2]);
- else
- rejoin = kick_channel(config->sid, source, channel, user, STRING(""));
+ char uses_inspircd3;
+ if (!STRING_EQ(user->server, SID)) {
+ struct server_info *server = get_table_index(server_list, user->server);
+ uses_inspircd3 = (server->protocol == INSPIRCD3_PROTOCOL);
+ } else {
+ uses_inspircd3 = 0;
+ }
+
+ struct string reason;
+ if (argc >= 4) {
+ if (uses_inspircd3) {
+ char err;
+ size_t member_id = str_to_unsigned(argv[2], &err);
+ if (err) {
+ kill_user(SID, SID, user, STRING("Member ID limit exceeded. Please reconnect to reset it."));
+ return 0;
+ }
+
+ struct inspircd3_protocol_specific_user *prot_specific = user->protocol_specific[INSPIRCD3_PROTOCOL];
+ struct inspircd3_protocol_member_id *current_member_id = get_table_index(prot_specific->memberships, channel->name);
+ if (member_id < current_member_id->id)
+ return 0; // Kick was for an old membership, ignore it
+ }
+
+ reason = argv[3];
+ } else if (argc >= 3) {
+ reason = argv[2];
+ } else {
+ reason = STRING("");
+ }
+
+ int rejoin = kick_channel(config->sid, source, channel, user, reason);
if (rejoin) {
struct server_info *server = get_table_index(server_list, user->server);
diff --git a/protocols/inspircd4.c b/protocols/inspircd4.c
index f336506..c22b20b 100644
--- a/protocols/inspircd4.c
+++ b/protocols/inspircd4.c
@@ -1927,7 +1927,7 @@ int inspircd4_protocol_handle_part(struct string source, size_t argc, struct str
return 0;
}
-// [:source] KICK <channel> <user> [<reason>]
+// [:source] KICK <channel> <user> [<member id>] [<reason>]
int inspircd4_protocol_handle_kick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) {
if (argc < 2) {
WRITES(2, STRING("[InspIRCd v4] Invalid KICK received! (Missing parameters)\r\n"));
@@ -1952,11 +1952,38 @@ int inspircd4_protocol_handle_kick(struct string source, size_t argc, struct str
return 0;
}
- int rejoin;
- if (argc > 2)
- rejoin = kick_channel(config->sid, source, channel, user, argv[2]);
- else
- rejoin = kick_channel(config->sid, source, channel, user, STRING(""));
+ char uses_inspircd4;
+ if (!STRING_EQ(user->server, SID)) {
+ struct server_info *server = get_table_index(server_list, user->server);
+ uses_inspircd4 = (server->protocol == INSPIRCD4_PROTOCOL);
+ } else {
+ uses_inspircd4 = 0;
+ }
+
+ struct string reason;
+ if (argc >= 4) {
+ if (uses_inspircd4) {
+ char err;
+ size_t member_id = str_to_unsigned(argv[2], &err);
+ if (err) {
+ kill_user(SID, SID, user, STRING("Member ID limit exceeded. Please reconnect to reset it."));
+ return 0;
+ }
+
+ struct inspircd4_protocol_specific_user *prot_specific = user->protocol_specific[INSPIRCD4_PROTOCOL];
+ struct inspircd4_protocol_member_id *current_member_id = get_table_index(prot_specific->memberships, channel->name);
+ if (member_id < current_member_id->id)
+ return 0; // Kick was for an old membership, ignore it
+ }
+
+ reason = argv[3];
+ } else if (argc >= 3) {
+ reason = argv[2];
+ } else {
+ reason = STRING("");
+ }
+
+ int rejoin = kick_channel(config->sid, source, channel, user, reason);
if (rejoin) {
struct server_info *server = get_table_index(server_list, user->server);