diff options
| author | Nakidai <nakidai@disroot.org> | 2026-02-14 00:05:36 +0300 |
|---|---|---|
| committer | Nakidai <nakidai@disroot.org> | 2026-02-14 00:20:38 +0300 |
| commit | 834c85d80914007e31657d12d2f22a9cb2cd8624 (patch) | |
| tree | 283ed0dacb635b97f93c21c8b0b94b6116ca29a3 /handle.c | |
| parent | 15151c88a7eb381fb5b46daaf521fc609d40539c (diff) | |
| download | libreircd-834c85d80914007e31657d12d2f22a9cb2cd8624.tar.gz libreircd-834c85d80914007e31657d12d2f22a9cb2cd8624.zip | |
Add support for voice and +m channel mode
So now voices in code are not that useless. Also, code was fixed for their printing as it is valid for a user to be both an oper and voiced
Diffstat (limited to 'handle.c')
| -rw-r--r-- | handle.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/handle.c b/handle.c index 684c2ee..1253cdf 100644 --- a/handle.c +++ b/handle.c @@ -182,6 +182,18 @@ mode_channel(struct Message *msg, struct Peer *peer) parsed = channel_modes_parse(msg); for (; parsed->param || parsed->mode; ++parsed) switch (parsed->mode) { + break; case 'm': + announce_change(1); + if (parsed->set) + channel->modes |= CHANNEL_MODERATED; + else + channel->modes &= ~CHANNEL_MODERATED; + break; case 'n': + announce_change(1); + if (parsed->set) + channel->modes |= CHANNEL_NOFROMOUT; + else + channel->modes &= ~CHANNEL_NOFROMOUT; break; case 'o': ensure(parsed->param, reply(peer, 461, msg->command), 0); @@ -195,12 +207,6 @@ 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); @@ -214,6 +220,19 @@ mode_channel(struct Message *msg, struct Peer *peer) channel->modes |= CHANNEL_TOPIC; else channel->modes &= ~CHANNEL_TOPIC; + break; case 'v': + ensure(parsed->param, reply(peer, 461, msg->command), 0); + + for (i = 0; i < channel->peers_c; ++i) + if (!strcmp(channel->peers[i].p->nick, parsed->param)) + break; + ensure(i != channel->peers_c, reply(peer, 441, parsed->param, channel->name), 0); + + announce_change(0); + if (parsed->set) + channel->peers[i].modes |= CHANNEL_VOICE; + else + channel->peers[i].modes &= ~CHANNEL_VOICE; break; default: modebuf[0] = parsed->mode; modebuf[1] = 0; @@ -295,7 +314,7 @@ names(struct Message *msg, struct Peer *peer) chpp = &peer->channels[i]->peers[j]; if (chpp->modes & CHANNEL_OPER) strlcat(buf, "@", sizeof(buf)); - else if (chpp->modes & CHANNEL_VOICE) + if (chpp->modes & CHANNEL_VOICE) strlcat(buf, "+", sizeof(buf)); strlcat(buf, peer->channels[i]->peers[j].p->nick, sizeof(buf)); if (strlen(buf) >= MESSAGE_MAX - 4*PEER_NICK_MAX @@ -466,13 +485,18 @@ privmsg(struct Message *msg, struct Peer *peer) 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); - } + for (i = 0; i < ch->peers_c; ++i) + if (ch->peers[i].p == peer) + break; + + ensure( + (!(ch->modes & CHANNEL_NOFROMOUT) || i != ch->peers_c) + && (!(ch->modes & CHANNEL_MODERATED) + || ch->peers[i].modes & (CHANNEL_OPER | CHANNEL_VOICE) + ), + reply(peer, 404, ch->name), + 0 + ); writechanf( peer, |