Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OneBotMember 支持禁言API, OneBotGroup 支持全群禁言, OneBotFriend 支持好友送赞API #18

Merged
merged 4 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import kotlin.coroutines.CoroutineContext
*
* @author ForteScarlet
*/
public interface OneBotFriend : Contact {
public interface OneBotFriend : Contact, SendLikeSupport {
/**
* 协程上下文。源自 [OneBotBot], 但是不含 [Job][kotlinx.coroutines.Job]。
*/
Expand All @@ -56,12 +56,28 @@ public interface OneBotFriend : Contact {
override val avatar: String
get() = qqAvatar640(id.literal)

/**
* 向此好友发送消息。
*
* @throws Throwable 任何请求API过程中可能产生的异常
*/
@ST
override suspend fun send(message: Message): OneBotMessageReceipt

/**
* 向此好友发送消息。
*
* @throws Throwable 任何请求API过程中可能产生的异常
*/
@ST
override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt

/**
* 向此好友发送消息。
*
* @throws Throwable 任何请求API过程中可能产生的异常
*/
@ST
override suspend fun send(text: String): OneBotMessageReceipt

}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ public interface OneBotGroup : ChatGroup, DeleteSupport {
*/
@JvmSynthetic
override suspend fun delete(vararg options: DeleteOption)

/**
* 设置全群禁言。
*
* @param enable 是开启还是关闭全群禁言
*
* @throws Throwable 任何请求API过程中可能产生的异常
*/
@ST
public suspend fun ban(enable: Boolean)
}

/**
Expand Down Expand Up @@ -162,3 +172,19 @@ public sealed class OneBotGroupDeleteOption : DeleteOption {

}
}

/**
* 开启全群禁言。
*/
@JvmSynthetic
public suspend fun OneBotGroup.ban() {
ban(true)
}

/**
* 取消全群禁言。
*/
@JvmSynthetic
public suspend fun OneBotGroup.unban() {
ban(false)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import love.forte.simbot.ability.DeleteSupport
import love.forte.simbot.ability.StandardDeleteOption
import love.forte.simbot.common.id.ID
import love.forte.simbot.common.id.literal
import love.forte.simbot.common.time.TimeUnit
import love.forte.simbot.component.onebot.v11.common.utils.qqAvatar640
import love.forte.simbot.component.onebot.v11.core.api.SetGroupBanApi
import love.forte.simbot.component.onebot.v11.core.api.SetGroupKickApi
import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot
import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt
Expand All @@ -34,6 +36,7 @@ import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
import kotlin.time.Duration


/**
Expand Down Expand Up @@ -107,11 +110,65 @@ public interface OneBotMember : Member, DeleteSupport {
* - [OneBotMemberDeleteOption] 的所有实现
*
* @throws Throwable 任何可能在请求API时得到的异常
* @throws IllegalStateException 某些无法得知群号的情况下抛出的异常
*/
@JvmSynthetic
override suspend fun delete(vararg options: DeleteOption) {
StandardDeleteOption
SetGroupKickApi
override suspend fun delete(vararg options: DeleteOption)

/**
* 禁言此成员。
* 禁言时长范围应当在 1m ~ 30d 之间,
* 不过 [duration] 最终会被转为秒值。
* 如果值为 [Duration.ZERO] 或最终秒值为 `0` 则等同于 [unban],
* 如果转化后的秒值为负数,则会抛出 [IllegalArgumentException]。
*
* 不会在代码中校验时长的最大有效值,这会直接交给OneBot服务端处理。
*
* @param duration 禁言时长。
* 通常来讲,时间范围应当在 1m ~ 30d 之间。
* 如果值为 [Duration.ZERO] 则等同于 [unban]。
*
* @throws IllegalArgumentException 如果参数代表的秒值 **小于0**
* @throws IllegalStateException 某些无法得知群号的情况下抛出的异常
* @throws Throwable 任何请求API时可能得到的异常
*
* @see SetGroupBanApi
*
*/
@JvmSynthetic
public suspend fun ban(duration: Duration)

/**
* 禁言此成员。
* 禁言时长范围应当在 1m ~ 30d 之间,
* 不过 [duration] 最终会根据 [unit] 被转为秒值。
* 如果最终秒值为 `0` 则等同于 [unban],
* 如果 [duration] 为负数,则会抛出 [IllegalArgumentException]。
*
* 不会在代码中校验时长的最大有效值,这会直接交给OneBot服务端处理。
*
* @param duration 禁言时长
* @param unit [duration] 的时间单位
*
* @throws IllegalArgumentException 如果参数代表的秒值 **小于0**
* @throws IllegalStateException 某些无法得知群号的情况下抛出的异常
* @throws Throwable 任何请求API时可能得到的异常
*
* @see SetGroupBanApi
*
*/
@ST
public suspend fun ban(duration: Long, unit: TimeUnit)

/**
* 取消此成员禁言。相当于 `ban(Duration.ZERO)`。
*
* @throws IllegalStateException 某些无法得知群号的情况下抛出的异常
* @throws Throwable 任何请求API时可能得到的异常
*/
@ST
public suspend fun unban() {
ban(Duration.ZERO)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024. ForteScarlet.
*
* This file is part of simbot-component-onebot.
*
* simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot.
* If not, see <https://www.gnu.org/licenses/>.
*/

package love.forte.simbot.component.onebot.v11.core.actor

import love.forte.simbot.suspendrunner.ST


/**
*
* 支持发送好友赞行为的接口定义。
*
* @author ForteScarlet
*/
public interface SendLikeSupport {
/**
* 发送好友赞。
*
* @param times 次数。
* 一般来说一人一天最多赞10次,
* 但是这将交由OneBot服务端进行校验和处理。
* @throws Throwable 任何请求API过程可能产生的异常
*/
@ST
public suspend fun sendLike(times: Int)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package love.forte.simbot.component.onebot.v11.core.actor.internal
import love.forte.simbot.common.id.ID
import love.forte.simbot.component.onebot.v11.core.actor.OneBotFriend
import love.forte.simbot.component.onebot.v11.core.api.GetFriendListResult
import love.forte.simbot.component.onebot.v11.core.api.SendLikeApi
import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl
import love.forte.simbot.component.onebot.v11.core.bot.requestDataBy
import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt
Expand Down Expand Up @@ -61,6 +62,13 @@ internal abstract class OneBotFriendImpl : OneBotFriend {
).requestDataBy(bot).toReceipt(bot)
}

override suspend fun sendLike(times: Int) {
SendLikeApi.create(
userId = id,
times = times
).requestDataBy(bot)
}

override fun toString(): String = "OneBotFriend(id=$id, bot=${bot.id})"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ import love.forte.simbot.common.id.ID
import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup
import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroupDeleteOption
import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember
import love.forte.simbot.component.onebot.v11.core.api.GetGroupInfoResult
import love.forte.simbot.component.onebot.v11.core.api.GetGroupMemberInfoApi
import love.forte.simbot.component.onebot.v11.core.api.GetGroupMemberListApi
import love.forte.simbot.component.onebot.v11.core.api.SetGroupLeaveApi
import love.forte.simbot.component.onebot.v11.core.api.*
import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl
import love.forte.simbot.component.onebot.v11.core.bot.requestDataBy
import love.forte.simbot.component.onebot.v11.core.bot.requestResultBy
Expand Down Expand Up @@ -140,6 +137,13 @@ internal abstract class OneBotGroupImpl : OneBotGroup {
}
}

override suspend fun ban(enable: Boolean) {
SetGroupWholeBanApi.create(
groupId = id,
enable = enable
).requestDataBy(bot)
}

override fun toString(): String = "OneBotGroup(id=$id, bot=${bot.id})"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ package love.forte.simbot.component.onebot.v11.core.actor.internal
import love.forte.simbot.ability.DeleteOption
import love.forte.simbot.ability.StandardDeleteOption
import love.forte.simbot.common.id.ID
import love.forte.simbot.common.time.TimeUnit
import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember
import love.forte.simbot.component.onebot.v11.core.actor.OneBotMemberDeleteOption
import love.forte.simbot.component.onebot.v11.core.actor.OneBotMemberRole
import love.forte.simbot.component.onebot.v11.core.api.GetGroupMemberInfoResult
import love.forte.simbot.component.onebot.v11.core.api.SetGroupAnonymousBanApi
import love.forte.simbot.component.onebot.v11.core.api.SetGroupBanApi
import love.forte.simbot.component.onebot.v11.core.api.SetGroupKickApi
import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl
import love.forte.simbot.component.onebot.v11.core.bot.requestDataBy
Expand All @@ -39,12 +42,17 @@ import love.forte.simbot.message.Message
import love.forte.simbot.message.MessageContent
import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmInline
import kotlin.time.Duration


internal abstract class OneBotMemberImpl : OneBotMember {
protected abstract val bot: OneBotBotImpl
protected abstract val groupId: ID?

protected inline val groupIdOrFailure: ID
get() = groupId
?: error("The group id for current member $this is unknown")

override suspend fun send(text: String): OneBotMessageReceipt {
return sendPrivateTextMsgApi(
target = id,
Expand Down Expand Up @@ -121,6 +129,45 @@ internal abstract class OneBotMemberImpl : OneBotMember {
}
}

override suspend fun ban(duration: Duration) {
if (duration == Duration.ZERO) {
doUnban()
}

val seconds = duration.inWholeSeconds
require(seconds >= 0) {
"The seconds for ban must >= 0, but $seconds"
}

doBan(seconds)
}

override suspend fun ban(duration: Long, unit: TimeUnit) {
require(duration >= 0) {
"The duration for ban must >= 0, but $duration in $unit"
}

if (duration == 0L) {
doUnban()
}

doBan(unit.toSeconds(duration))
}

private suspend fun doUnban() {
doBan(0L)
}

protected open suspend fun doBan(seconds: Long) {
val groupId = groupIdOrFailure

SetGroupBanApi.create(
groupId = groupId,
userId = id,
duration = seconds
).requestDataBy(bot)
}

override fun toString(): String = "OneBotMember(id=$id, bot=${bot.id})"
}

Expand All @@ -136,14 +183,14 @@ internal class OneBotMemberPrivateMessageEventSenderImpl(
override val id: ID
get() = source.userId


override val name: String
get() = source.nickname
}

internal class OneBotMemberGroupMessageEventSenderImpl(
private val source: GroupMessageEvent.Sender,
override val groupId: ID?,
private val anonymous: GroupMessageEvent.Anonymous?,
override val bot: OneBotBotImpl,
) : OneBotMemberImpl() {
override val coroutineContext: CoroutineContext = bot.subContext
Expand All @@ -160,6 +207,21 @@ internal class OneBotMemberGroupMessageEventSenderImpl(
override val role: OneBotMemberRole
get() = OneBotMemberRole.valueOfLenient(source.role)
?: OneBotMemberRole.MEMBER

override suspend fun doBan(seconds: Long) {
val anonymous = this.anonymous
if (anonymous == null) {
super.doBan(seconds)
} else {
val groupId = groupIdOrFailure

SetGroupAnonymousBanApi.create(
groupId = groupId,
anonymousFlag = anonymous.flag,
duration = seconds
).requestDataBy(bot)
}
}
}

internal fun PrivateMessageEvent.Sender.toMember(
Expand All @@ -179,10 +241,12 @@ internal fun PrivateMessageEvent.Sender.toMember(
internal fun GroupMessageEvent.Sender.toMember(
bot: OneBotBotImpl,
groupId: ID,
anonymous: GroupMessageEvent.Anonymous?
): OneBotMemberGroupMessageEventSenderImpl =
OneBotMemberGroupMessageEventSenderImpl(
source = this,
groupId = groupId,
anonymous = anonymous,
bot = bot,
)

Expand Down
Loading
Loading