diff options
| author | Nakidai <nakidai@disroot.org> | 2026-02-12 21:19:11 +0300 |
|---|---|---|
| committer | Nakidai <nakidai@disroot.org> | 2026-02-12 21:19:11 +0300 |
| commit | e76511e37e906c73d61aa65ec27efd9f060bf1a3 (patch) | |
| tree | c5a4c38987c327f97ca386c81779d32a605ae0e9 | |
| parent | ec97c603288869efad52ed7235ae770f85a9d7e8 (diff) | |
| download | libreircd-e76511e37e906c73d61aa65ec27efd9f060bf1a3.tar.gz libreircd-e76511e37e906c73d61aa65ec27efd9f060bf1a3.zip | |
Add support for n channel flag
It's a flag that restricts a set of users able to write to a channel to those who joined. If not, reply 442 is sent upon PRIVMSG
| -rw-r--r-- | channel.c | 2 | ||||
| -rw-r--r-- | handle.c | 44 | ||||
| -rw-r--r-- | ircd.h | 1 |
3 files changed, 31 insertions, 16 deletions
diff --git a/channel.c b/channel.c index d04f3cc..2717e5e 100644 --- a/channel.c +++ b/channel.c @@ -105,7 +105,7 @@ channel_modes_parse(const struct Message *msg) return modes; } queue[queue_r++] = (set << 7) | *m; - break; case 's': + break; case 'n': case 's': modes[modes_c].mode = *m; modes[modes_c++].set = set; break; default: diff --git a/handle.c b/handle.c index 2190bcf..d32714c 100644 --- a/handle.c +++ b/handle.c @@ -166,6 +166,12 @@ mode_channel(struct Message *msg, struct Peer *peer) channel->peers[i].modes |= CHANNEL_OPER; else channel->peers[i].modes &= ~CHANNEL_OPER; + break; case 'n': + announce_change(1); + if (parsed->set) + channel->modes |= CHANNEL_NOFROMOUT; + else + channel->modes &= ~CHANNEL_NOFROMOUT; break; case 's': /* TODO: implement +s. For now it's just a some mode with no param */ announce_change(1); @@ -418,25 +424,33 @@ privmsg(struct Message *msg, struct Peer *peer) { case '#': { + struct Channel *ch; + for (i = 0; i < channels_c; ++i) if (!strcmp(channels[i].name, msg->params[0])) - { - writechanf( - peer, - &channels[i], - ":%s!%s@%s %s %s :%s", - peer->nick, - peer->user, - peer->host, - *msg->command == 'p' - ? "PRIVMSG" - : "NOTICE", - msg->params[0], - msg->params[1] - ); break; - } ensure(i != channels_c, reply(peer, 401, msg->params[0]), 0); + ch = &channels[i]; + + if (ch->modes & CHANNEL_NOFROMOUT) + { + for (i = 0; i < ch->peers_c; ++i) + if (!strcmp(ch->peers[i].p->nick, peer->nick)) + break; + ensure(i != ch->peers_c, reply(peer, 442, ch->name), 0); + } + + writechanf( + peer, + ch, + ":%s!%s@%s %s %s :%s", + peer->nick, + peer->user, + peer->host, + *msg->command == 'p' ? "PRIVMSG" : "NOTICE", + msg->params[0], + msg->params[1] + ); } break; default: { diff --git a/ircd.h b/ircd.h index 931948b..d4ed678 100644 --- a/ircd.h +++ b/ircd.h @@ -83,6 +83,7 @@ struct Channel enum ChannelMode { BIT(CHANNEL_SECRET), + BIT(CHANNEL_NOFROMOUT), } modes; }; |