diff --git a/irc/channel.go b/irc/channel.go index 8d814838..3854ce4a 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -395,7 +395,7 @@ func channelUserModeHasPrivsOver(clientMode modes.Mode, targetMode modes.Mode) b return targetMode != modes.ChannelFounder && targetMode != modes.ChannelAdmin case modes.Halfop: // halfops cannot kick other halfops - return targetMode != modes.ChannelFounder && targetMode != modes.ChannelAdmin && targetMode != modes.Halfop + return targetMode == modes.Voice || targetMode == modes.Mode(0) default: // voice and unprivileged cannot kick anyone return false diff --git a/irc/modes.go b/irc/modes.go index 40b22875..5919fd20 100644 --- a/irc/modes.go +++ b/irc/modes.go @@ -277,6 +277,9 @@ func (channel *Channel) ProcessAccountToUmodeChange(client *Client, change modes hasPrivs = true } else if channelUserModeHasPrivsOver(clientMode, targetModeNow) && channelUserModeHasPrivsOver(clientMode, targetModeAfter) { hasPrivs = true + } else if change.Op == modes.Remove && account == change.Arg { + // you can always de-op yourself + hasPrivs = true } if !hasPrivs { return nil, errInsufficientPrivs