Commit 12ad7542 authored by Him188's avatar Him188

Separate `mirai-demos` series from main repository

parent c6ae8e32
apply plugin: "kotlin"
apply plugin: "java"
dependencies {
runtimeOnly files("../../mirai-core/build/classes/kotlin/jvm/main") // IDE bug
runtimeOnly files("../../mirai-core-qqandroid/build/classes/kotlin/jvm/main") // IDE bug
implementation project(":mirai-core-qqandroid")
api group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlinVersion
api group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: coroutinesVersion
}
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE")
package demo.subscribe
import kotlinx.coroutines.CompletableJob
import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.contact.isOperator
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.event.*
import net.mamoe.mirai.message.FriendMessage
import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.nextMessage
import net.mamoe.mirai.message.sendAsImageTo
import net.mamoe.mirai.utils.FileBasedDeviceInfo
import net.mamoe.mirai.utils.MiraiInternalAPI
import java.io.File
@MiraiInternalAPI
private fun readTestAccount(): BotAccount? {
val file = File("testAccount.txt")
if (!file.exists() || !file.canRead()) {
return null
}
println("Reading account from testAccount.text")
val lines = file.readLines()
return try {
BotAccount(lines[0].toLong(), lines[1])
} catch (e: IndexOutOfBoundsException) {
null
}
}
@Suppress("UNUSED_VARIABLE")
suspend fun main() {
val bot = Bot( // JVM 下也可以不写 `QQAndroid.` 引用顶层函数
123456789,
"123456"
) {
// 覆盖默认的配置
+FileBasedDeviceInfo // 使用 "device.json" 保存设备信息
// networkLoggerSupplier = { SilentLogger } // 禁用网络层输出
}.alsoLogin()
bot.messageDSL()
directlySubscribe(bot)
bot.join()//等到直到断开连接
}
/**
* 使用 dsl 监听消息事件
*
* @see subscribeFriendMessages
* @see subscribeMessages
* @see subscribeGroupMessages
*
* @see MessageSubscribersBuilder
*/
fun Bot.messageDSL() {
// 监听这个 bot 的来自所有群和好友的消息
this.subscribeMessages {
// 当接收到消息 == "你好" 时就回复 "你好!"
"你好" reply "你好!"
// 当消息 == "查看 subject" 时, 执行 lambda
case("查看 subject") {
if (subject is QQ) {
reply("消息主体为 QQ, 你在发私聊消息")
} else {
reply("消息主体为 Group, 你在群里发消息")
}
// 在回复的时候, 一般使用 subject 来作为回复对象.
// 因为当群消息时, subject 为这个群.
// 当好友消息时, subject 为这个好友.
// 所有在 MessagePacket(也就是此时的 this 指代的对象) 中实现的扩展方法, 如刚刚的 "reply", 都是以 subject 作为目标
}
// 当消息里面包含这个类型的消息时
has<Image> {
// this: MessagePacket
// message: MessageChain
// sender: QQ
// it: String (MessageChain.toString)
// message[Image].download() // 还未支持 download
if (this is GroupMessage) {
//如果是群消息
// group: Group
this.group.sendMessage("你在一个群里")
// 等同于 reply("你在一个群里")
}
reply("图片, ID= ${message[Image]}")//获取第一个 Image 类型的消息
reply(message)
}
"hello.*world".toRegex() matchingReply {
"Hello!"
}
"123" containsReply "你的消息里面包含 123"
// 当收到 "我的qq" 就执行 lambda 并回复 lambda 的返回值 String
"我的qq" reply { sender.id }
"at all" reply AtAll // at 全体成员
// 如果是这个 QQ 号发送的消息(可以是好友消息也可以是群消息)
sentBy(123456789) {
}
// 当消息前缀为 "我是" 时
startsWith("我是", removePrefix = true) {
// it: 删除了消息前缀 "我是" 后的消息
// 如一条消息为 "我是张三", 则此时的 it 为 "张三".
reply("你是$it")
}
// listener 管理
var repeaterListener: CompletableJob? = null
contains("开启复读") {
repeaterListener?.complete()
bot.subscribeGroupMessages {
repeaterListener = contains("复读") {
reply(message)
}
}
}
contains("关闭复读") {
if (repeaterListener?.complete() == null) {
reply("没有开启复读")
} else {
reply("成功关闭复读")
}
}
// 自定义的 filter, filter 中 it 为转为 String 的消息.
// 也可以用任何能在处理时使用的变量, 如 subject, sender, message
content({ it.length == 3 }) {
reply("你发送了长度为 3 的消息")
}
case("上传好友图片") {
val filename = it.substringAfter("上传好友图片")
File("C:\\Users\\Him18\\Desktop\\$filename").sendAsImageTo(subject)
}
case("上传群图片") {
val filename = it.substringAfter("上传好友图片")
File("C:\\Users\\Him18\\Desktop\\$filename").sendAsImageTo(subject)
}
}
subscribeMessages {
case("你好") {
// this: MessagePacket
// message: MessageChain
// sender: QQ
// it: String (来自 MessageChain.toString)
// group: Group (如果是群消息)
reply("你好")
}
}
subscribeFriendMessages {
contains("A") {
// this: FriendMessage
// message: MessageChain
// sender: QQ
// it: String (来自 MessageChain.toString)
reply("B")
}
}
subscribeGroupMessages {
// this: FriendMessage
// message: MessageChain
// sender: QQ
// it: String (来自 MessageChain.toString)
// group: Group
case("recall") {
reply("😎").recallIn(3000) // 3 秒后自动撤回这条消息
}
case("禁言") {
// 挂起当前协程, 等待下一条满足条件的消息.
// 发送 "禁言" 后需要再发送一条消息 at 一个人.
val value: At = nextMessage { message.any(At) }[At]
value.member().mute(10)
}
startsWith("群名=") {
if (!sender.isOperator()) {
sender.mute(5)
return@startsWith
}
group.name = it
}
}
}
/**
* 监听单个事件
*/
@Suppress("UNUSED_VARIABLE")
suspend fun directlySubscribe(bot: Bot) {
// 在当前协程作用域 (CoroutineScope) 下创建一个子 Job, 监听一个事件.
//
// 手动处理消息
//
// subscribeAlways 函数返回 Listener, Listener 是一个 CompletableJob.
//
// 例如:
// ```kotlin
// runBlocking {// this: CoroutineScope
// subscribeAlways<FriendMessage> {
// }
// }
// ```
// 则这个 `runBlocking` 永远不会结束, 因为 `subscribeAlways` 在 `runBlocking` 的 `CoroutineScope` 下创建了一个 Job.
// 正确的用法为:
// 在 Bot 的 CoroutineScope 下创建一个监听事件的 Job, 则这个子 Job 会在 Bot 离线后自动完成 (complete).
bot.subscribeAlways<FriendMessage> {
// this: FriendMessageEvent
// event: FriendMessageEvent
// 获取第一个纯文本消息, 获取不到会抛出 NoSuchElementException
// val firstText = message.first<PlainText>()
val firstText = message.firstOrNull<PlainText>()
// 获取第一个图片
val firstImage = message.firstOrNull<Image>()
when {
message eq "你好" -> reply("你好!")
"复读" in message -> sender.sendMessage(message)
"发群消息" in message -> {
bot.getGroup(580266363).sendMessage(message.toString().substringAfter("发群消息"))
}
}
}
}
\ No newline at end of file
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.multiplatform'
id 'kotlin-android-extensions'
}
android {
compileSdkVersion 29
defaultConfig {
applicationId "net.mamoe.mirai.demo"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/main.kotlin_module'
exclude 'META-INF/ktor-http.kotlin_module'
exclude 'META-INF/kotlinx-io.kotlin_module'
exclude 'META-INF/atomicfu.kotlin_module'
exclude 'META-INF/ktor-utils.kotlin_module'
exclude 'META-INF/kotlinx-coroutines-io.kotlin_module'
exclude 'META-INF/kotlinx-coroutines-core.kotlin_module'
exclude 'META-INF/ktor-http-cio.kotlin_module'
exclude 'META-INF/ktor-http-cio.kotlin_module'
exclude 'META-INF/ktor-client-core.kotlin_module'
exclude "META-INF/kotlinx-serialization-runtime.kotlin_module"
exclude 'META-INF/ktor-io.kotlin_module'
}
}
kotlin {
targets.fromPreset(presets.android, 'android')
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation project(':mirai-core-qqandroid')
implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlinVersion
implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: coroutinesVersion
implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-android', version: "1.3.2"
//implementation 'com.android.support:appcompat-v7:29.1.1'// https://mvnrepository.com/artifact/androidx.appcompat/appcompat
implementation group: 'androidx.appcompat', name: 'appcompat', version: '1.1.0'
testImplementation "org.jetbrains.kotlin:kotlin-test"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'junit:junit:4.12'
def anko_version = "0.10.8"
implementation "org.jetbrains.anko:anko-commons:$anko_version"
implementation group: 'io.ktor', name: 'ktor-client-android', version: '1.2.5'
implementation("io.ktor:ktor-client-android:1.2.5")
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.mamoe.mirai.demo">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:label="@string/app_name"
android:allowBackup="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="net.mamoe.mirai.demo.MainActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name=".MiraiService"/>
</application>
</manifest>
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.demo
import android.graphics.Bitmap
interface LoginCallback {
suspend fun onCaptcha(bitmap: Bitmap)
suspend fun onSuccess()
suspend fun onFailed()
suspend fun onMessage(message:String)
}
\ No newline at end of file
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("DEPRECATION", "EXPERIMENTAL_API_USAGE")
package net.mamoe.mirai.demo
import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.app.Service
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Bitmap
import android.os.Bundle
import android.os.IBinder
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class MainActivity : AppCompatActivity(),LoginCallback {
private lateinit var progressDialog : ProgressDialog
override suspend fun onCaptcha(bitmap: Bitmap) {
withContext(Dispatchers.Main){
ll_captcha.visibility = View.VISIBLE
iv_captcha.setImageBitmap(bitmap)
needCaptcha = true
if (progressDialog.isShowing){
progressDialog.dismiss()
}
}
}
@SuppressLint("SetTextI18n")
override suspend fun onMessage(message:String) {
withContext(Dispatchers.Main){
msg.text = "${msg.text}\n$message"
}
}
override suspend fun onSuccess() {
withContext(Dispatchers.Main){
Toast.makeText(this@MainActivity,"登录成功",Toast.LENGTH_SHORT).show()
if (progressDialog.isShowing){
progressDialog.dismiss()
}
ll_captcha.visibility = View.GONE
et_pwd.visibility = View.GONE
et_qq.visibility = View.GONE
bt_login.visibility = View.GONE
}
}
override suspend fun onFailed() {
withContext(Dispatchers.Main){
Toast.makeText(this@MainActivity,"登录失败",Toast.LENGTH_SHORT).show()
if (progressDialog.isShowing){
progressDialog.dismiss()
}
}
}
var binder: MiraiService.MiraiBinder? = null
private var needCaptcha = false
private val conn = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
binder = service as MiraiService.MiraiBinder?
}
override fun onServiceDisconnected(name: ComponentName?) {
binder = null
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent(this, MiraiService::class.java)
startService(intent)
bindService(intent, conn, Service.BIND_AUTO_CREATE)
progressDialog = ProgressDialog(this)
bt_login.setOnClickListener {
if (!progressDialog.isShowing){
progressDialog.show()
}
binder?.setCallback(this)
if (!needCaptcha){
val qq = et_qq.text.toString().toLong()
val pwd = et_pwd.text.toString()
binder?.startLogin(qq, pwd)
}else{
val captcha = et_captcha.text.toString()
binder?.setCaptcha(captcha)
}
}
}
override fun onDestroy() {
super.onDestroy()
unbindService(conn)
}
}
\ No newline at end of file
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("EXPERIMENTAL_API_USAGE")
package net.mamoe.mirai.demo
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Binder
import android.os.IBinder
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.io.core.IoBuffer
import kotlinx.io.core.readBytes
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.qqandroid.QQAndroid
import net.mamoe.mirai.utils.LoginSolver
import java.lang.ref.WeakReference
class MiraiService : Service() {
private lateinit var mCaptchaDeferred: CompletableDeferred<String>
private lateinit var mBot: Bot
private var mCaptcha = ""
set(value) {
field = value
mCaptchaDeferred.complete(value)
}
private var mBinder: MiraiBinder? = null
private var mCallback: WeakReference<LoginCallback>? = null
override fun onCreate() {
super.onCreate()
mBinder = MiraiBinder()
}
private fun login(context: Context, qq: Long, pwd: String) {
GlobalScope.launch {
mBot = QQAndroid.Bot(context, qq, pwd) {
loginSolver = object : LoginSolver() {
override suspend fun onSolvePicCaptcha(bot: Bot, data: IoBuffer): String? {
val bytes = data.readBytes()
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
mCaptchaDeferred = CompletableDeferred()
mCallback?.get()?.onCaptcha(bitmap)
return mCaptchaDeferred.await()
}
override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String? {
TODO("not implemented")
}
override suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String? {
TODO("not implemented")
}
}
}.apply {
try {
login()
mCallback?.get()?.onSuccess()
} catch (e: Exception) {
mCallback?.get()?.onFailed()
}
}
mBot.subscribeMessages {
always {
mCallback?.get()?.onMessage("收到来自${sender.id}的消息")
}
// 当接收到消息 == "你好" 时就回复 "你好!"
"你好" reply "你好!"
}
}
}
override fun onBind(intent: Intent?): IBinder? {
return mBinder
}
inner class MiraiBinder : Binder() {
fun startLogin(qq: Long, pwd: String) {
login(applicationContext, qq, pwd)
}
fun setCaptcha(captcha: String) {
mCaptcha = captcha
}
fun setCallback(callback: LoginCallback) {
mCallback = WeakReference(callback)
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="46dp"
android:inputType="number"
android:layout_marginTop="10dp"
android:ems="15"
android:hint="请输入QQ号"
android:id="@+id/et_qq" />
<EditText
android:layout_width="match_parent"
android:layout_height="46dp"
android:inputType="textPassword"
android:hint="请输入密码"
android:layout_marginTop="10dp"
android:id="@+id/et_pwd" />
<LinearLayout
android:id="@+id/ll_captcha"
android:layout_marginTop="5dp"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/et_captcha"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="46dp"
android:hint="输入验证码"/>
<ImageView
android:id="@+id/iv_captcha"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:scaleType="fitXY"/>
</LinearLayout>
<Button
android:text="登录"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:id="@+id/bt_login"
android:background="#3F51B5"
android:textColor="#FFFFFF"/>
<TextView
android:id="@+id/msg"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Mirai</string>
</resources>
\ No newline at end of file
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
apply plugin: "kotlin"
apply plugin: "java"
apply plugin: "application"
apply plugin: "kotlinx-serialization"
dependencies {
runtimeOnly files("../../mirai-core/build/classes/kotlin/jvm/main") // IDE bug
runtimeOnly files("../../mirai-core-qqandroid/build/classes/kotlin/jvm/main") // IDE bug
api project(":mirai-core")
api project(":mirai-core-qqandroid")
api("org.jetbrains.kotlinx:atomicfu:$atomicFuVersion")
implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlinVersion
implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: coroutinesVersion
implementation("org.jetbrains.kotlinx:kotlinx-io:$kotlinXIoVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-io:$coroutinesIoVersion")
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.62'
api 'org.jsoup:jsoup:1.12.1'
}
run{
standardInput = System.in
mainClassName = "demo.gentleman.MainKt"
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ["-XXLanguage:+InlineClasses"]
}
}
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package demo.gentleman
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import net.mamoe.mirai.contact.Contact
/**
* 最少缓存的图片数量
*/
private const val IMAGE_BUFFER_CAPACITY: Int = 5
/**
* 为不同的联系人提供图片
*/
@ExperimentalUnsignedTypes
@ExperimentalCoroutinesApi
object Gentlemen : MutableMap<Long, Gentleman> by mutableMapOf() {
fun provide(key: Contact, keyword: String = ""): Gentleman = this.getOrPut(key.id) { Gentleman(key, keyword) }
}
/**
* 工作是缓存图片
*/
@ExperimentalCoroutinesApi
class Gentleman(private val contact: Contact, private val keyword: String) : Channel<GentleImage> by Channel(IMAGE_BUFFER_CAPACITY) {
init {
GlobalScope.launch {
while (!isClosedForSend) {
send(GentleImage(contact, keyword).apply {
seImage// start downloading
})
}
}
}
}
\ No newline at end of file
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE")
package demo.gentleman
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.mamoe.mirai.Bot
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeGroupMessages
import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.message.FriendMessage
import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.message.data.At
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.buildXMLMessage
import net.mamoe.mirai.message.data.getValue
import net.mamoe.mirai.message.sendAsImageTo
import net.mamoe.mirai.utils.ContextImpl
import java.io.File
import java.util.*
import javax.swing.filechooser.FileSystemView
import kotlin.random.Random
@Suppress("UNUSED_VARIABLE")
suspend fun main() {
val bot = Bot(
ContextImpl(),
913366033,
"a18260132383"
) {
// override config here.
}.alsoLogin()
// 任何可以监听的对象都继承 Event, 因此这个订阅会订阅全部的事件.
GlobalScope.subscribeAlways<Event> {
//bot.logger.verbose("收到了一个事件: $this")
}
// 全局范围订阅事件, 不受 bot 实例影响
GlobalScope.subscribeAlways<BotEvent> {
}
// 订阅来自这个 bot 的群消息事件
bot.subscribeGroupMessages {
startsWith("mute") {
val at: At by message
at.member().mute(30)
}
startsWith("unmute") {
val at: At by message
at.member().unmute()
}
}
// 订阅来自这个 bot 的消息事件, 可以是群消息也可以是好友消息
bot.subscribeMessages {
always {
}
case("at me") { At(sender as Member).reply() }
// 等同于 "at me" reply { At(sender) }
"你好" reply "你好!"
"grouplist" reply {
//"https://ssl.ptlogin2.qq.com/jump?pt_clientver=5509&pt_src=1&keyindex=9&clientuin=" + bot.qqAccount + "&clientkey=" + com.tick_tock.pctim.utils.Util.byte2HexString(
// user.txprotocol.serviceTicketHttp
//).replace(" ", "").toString() + "&u1=http%3A%2F%2Fqun.qq.com%2Fmember.html%23gid%3D168209441"
}
"xml" reply {
val template =
"""
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<msg templateID='1' serviceID='1' action='plugin' actionData='ACTION_LINK' brief='BRIEF' flag='3' url=''>
<item bg='0' layout='4'>
<picture cover='TITLE_PICTURE_LINK'/>
<title size='30' color='#fc7299'>TITLE</title>
</item>
<item>
<summary color='#fc7299'>CONTENT</summary>
<picture cover='CONTENT_PICTURE_LINK'/>
</item>
<source name='ExHentai' icon='ExHentai'/>
</msg>
""".trimIndent()
buildXMLMessage {
item {
picture("http://img.mamoe.net/2019/12/03/be35ccb489ecb.jpg")
title("This is title")
}
item {
summary("This is a summary colored #66CCFF", color = "#66CCFF")
picture("http://img.mamoe.net/2019/12/03/74c8614c4a161.jpg")
}
source("Mirai", "http://img.mamoe.net/2019/12/03/02eea0f6e826a.png")
}.reply()
}
(contains("1") and has<Image>()){
reply("Your message has a string \"1\" and an image contained")
}
has<Image> {
if (this is FriendMessage || (this is GroupMessage && this.permission == MemberPermission.ADMINISTRATOR)) withContext(IO) {
val image: Image by message
// 等同于 val image = message[Image]
try {
image.downloadTo(newTestTempFile(suffix = ".png").also { reply("Temp file: ${it.absolutePath}") })
reply(image.imageId + " downloaded")
} catch (e: Exception) {
e.printStackTrace()
reply(e.message ?: e::class.java.simpleName)
}
}
}
startsWith("上传图片", removePrefix = true) handler@{
val file = File(FileSystemView.getFileSystemView().homeDirectory, it)
if (!file.exists()) {
reply("图片不存在")
return@handler
}
reply("sent")
file.sendAsImageTo(subject)
}
startsWith("色图", removePrefix = true) {
repeat(it.toIntOrNull() ?: 1) {
GlobalScope.launch {
delay(Random.Default.nextLong(100, 1000))
Gentlemen.provide(subject).receive().image.await().send()
}
}
}
startsWith("不够色", removePrefix = true) {
repeat(it.toIntOrNull() ?: 1) {
GlobalScope.launch {
delay(Random.Default.nextLong(100, 1000))
Gentlemen.provide(subject).receive().seImage.await().send()
}
}
}
startsWith("添加好友", removePrefix = true) {
reply(bot.addFriend(it.toLong()).toString())
}
}
bot.join()//等到直到断开连接
}
private fun newTestTempFile(filename: String = "${UUID.randomUUID()}", suffix: String = ".tmp"): File =
File(System.getProperty("user.dir"), filename + suffix).also { it.createNewFile(); it.deleteOnExit() }
\ No newline at end of file
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package demo.gentleman
import demo.gentleman.UserAgent.randomUserAgent
import kotlin.random.Random
import kotlin.random.nextInt
/**
* @see randomUserAgent
*/
object UserAgent : List<String> by listOf(
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.517 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.367",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0",
"Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.367",
"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; rv:21.0) Gecko/20100101 Firefox/21.07",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1500.55 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.367",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:22.0) Gecko/20130328 Firefox/22.07",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.367",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.367",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.14 (KHTML, like Gecko) Chrome/24.0.1292.0 Safari/537.147",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2309.372 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.07",
"Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20130514 Firefox/21.0",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 4.0; InfoPath.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.367",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20120101 Firefox/29.0",
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.367",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.17 Safari/537.36",
"Mozilla/5.0 (Windows NT 4.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.367",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.367",
"Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.0; Trident/4.0; FBSMTWB; .NET CLR 2.0.34861; .NET CLR 3.0.3746.3218; .NET CLR 3.5.33652; msn OptimizedIE8;ENUS)",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.367",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0",
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2226.0 Safari/537.367",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.2 Safari/537.367",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36",
"Mozilla/5.0 (X11; NetBSD) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.1; SV1; .NET CLR 2.8.52393; WOW64; en-US)7",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.367",
"Mozilla/5.0 (Windows NT 6.0; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0",
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.90 Safari/537.367",
"Opera/9.80 (Windows NT 6.1 x64; U; en) Presto/2.7.62 Version/11.00",
"Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.7.62 Version/11.017",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-us) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.15 (KHTML, like Gecko) Chrome/24.0.1295.0 Safari/537.157",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.47",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.3; .NET4.0C; .NET4.0E; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MS-RTC LM 8)7",
"Mozilla/5.0 (X11; OpenBSD amd64; rv:28.0) Gecko/20100101 Firefox/28.0",
"Mozilla/5.0 (X11; CrOS i686 4319.74.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20130405 Firefox/22.07",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1623.0 Safari/537.367",
"Mozilla/5.0 (Windows NT 5.1; rv:21.0) Gecko/20130331 Firefox/21.07",
"Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:21.0.0) Gecko/20121011 Firefox/21.0.0",
"Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:27.0) Gecko/20121011 Firefox/27.07",
"Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/21.0.1",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2117.157 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/4E423F",
"Opera/9.80 (Windows NT 6.0; U; en) Presto/2.7.39 Version/11.007",
"Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.07",
"Mozilla/5.0 (X11; OpenBSD i386) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17",
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/4.0; InfoPath.2; SV1; .NET CLR 2.0.50727; WOW64)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7",
"Mozilla/5.0 (X11; CrOS i686 3912.101.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.367",
"Mozilla/5.0 (Windows x86; rv:19.0) Gecko/20100101 Firefox/19.07",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.367",
"Mozilla/5.0 (Microsoft Windows NT 6.2.9200.0); rv:22.0) Gecko/20130405 Firefox/22.07",
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1866.237 Safari/537.36",
"Opera/9.80 (Windows NT 5.1; U; zh-tw) Presto/2.8.131 Version/11.10",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20130331 Firefox/21.0",
"Opera/9.80 (X11; Linux i686; U; ja) Presto/2.7.62 Version/11.01",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/4.0; GTB7.4; InfoPath.3; SV1; .NET CLR 3.1.76908; WOW64; en-US)7",
"Opera/9.80 (Windows NT 5.1; U; zh-sg) Presto/2.9.181 Version/12.00",
"Mozilla/5.0 (Windows NT 6.1; rv:21.0) Gecko/20130328 Firefox/21.07",
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0.6",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; de-de) AppleWebKit/534.15+ (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4",
"Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20100101 Firefox/21.0",
"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.6.37 Version/11.007",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:25.0) Gecko/20100101 Firefox/25.0",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; zh-cn) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.0; Trident/4.0; InfoPath.1; SV1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 3.0.04506.30)",
"Mozilla/5.0 (Windows NT 5.0; rv:21.0) Gecko/20100101 Firefox/21.07",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.07",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; chromeframe/13.0.782.215)7",
"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.47",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)",
"Mozilla/5.0 (Windows NT 6.1; rv:21.0) Gecko/20130401 Firefox/21.07",
"Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.07",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20130401 Firefox/31.0",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:23.0) Gecko/20131011 Firefox/23.07",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; es-es) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20130330 Firefox/21.0",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101213 Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.27",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20130401 Firefox/21.0",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-gb) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/29.07",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)7",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727)7",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A7",
"Mozilla/5.0 (X11; Linux i586; rv:31.0) Gecko/20100101 Firefox/31.0",
"Opera/9.80 (X11; Linux x86_64; U; Ubuntu/10.10 (maverick); pl) Presto/2.7.62 Version/11.01",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; chromeframe/12.0.742.112)",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/21.0.1",
"Mozilla/5.0 (Windows NT 6.2; rv:21.0) Gecko/20130326 Firefox/21.07",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.47",
"Opera/9.80 (Windows NT 6.1; U; cs) Presto/2.7.62 Version/11.017",
"Mozilla/5.0 (Windows NT 6.2; rv:22.0) Gecko/20130405 Firefox/23.07",
"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; fr-FR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/5.0 (Windows NT 5.1; rv:21.0) Gecko/20130401 Firefox/21.07",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0",
"Mozilla/4.0 (Compatible; MSIE 8.0; Windows NT 5.2; Trident/6.0)",
"Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.7.62 Version/11.007",
"Mozilla/5.0 (X11; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0",
"Mozilla/5.0 (Windows NT 5.1; rv:21.0) Gecko/20100101 Firefox/21.07",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.47",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.07",
"Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.7.62 Version/11.017",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Opera/9.80 (Windows NT 6.1; U; fi) Presto/2.7.62 Version/11.007",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; InfoPath.1; SV1; .NET CLR 3.8.36217; WOW64; en-US)",
"Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25",
"Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko ) Version/5.1 Mobile/9B176 Safari/7534.48.3",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; ko-kr) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; tr-TR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.017",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)",
"Opera/9.80 (Windows NT 6.1; U; sv) Presto/2.7.62 Version/11.017",
"Mozilla/5.0 (Windows NT 6.2; Win64; x64;) Gecko/20100101 Firefox/20.0",
"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.7.62 Version/11.017",
"Mozilla/5.0 (Windows NT 6.1; rv:27.3) Gecko/20130101 Firefox/27.37",
"Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.007",
"Opera/9.80 (Windows NT 6.1; U; ko) Presto/2.7.62 Version/11.007",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; de-de) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Opera/12.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.027",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; yie8)",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; fr-fr) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Opera/9.80 (Windows NT 6.1; WOW64; U; pt) Presto/2.10.229 Version/11.627",
"Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16",
"Mozilla/5.0 (Android 2.2; Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.47",
"Mozilla/5.0 (Windows NT 6.2; rv:22.0) Gecko/20130405 Firefox/22.07",
"Opera/9.80 (X11; Linux i686; U; fr) Presto/2.7.62 Version/11.01",
"Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko7",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 87",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; ko-KR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52",
"Mozilla/5.0 (Windows; U; Windows NT 6.0; de-DE) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.47",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; it-it) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; cs-CZ) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; Media Center PC 6.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C)",
"Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14",
"Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET CLR 1.1.4322; .NET4.0C; Tablet PC 2.0)",
"Opera/9.80 (X11; Linux i686; U; it) Presto/2.7.62 Version/11.00",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.2; SV1; .NET CLR 3.3.69573; WOW64; en-US)7",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.47",
"Opera/9.80 (X11; Linux x86_64; U; fr) Presto/2.9.168 Version/11.50",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; de) Opera 11.51",
"Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.7.62 Version/11.017",
"Opera/9.80 (Windows NT 6.1; U; en-US) Presto/2.7.62 Version/11.017",
"Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
"Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.107",
"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8)",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/534.16+ (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 3.0)",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)7",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Opera/12.0(Windows NT 5.1;U;en)Presto/22.9.168 Version/12.00",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.147",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; it-IT) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.47",
"Opera/9.80 (Windows NT 5.1; U; en) Presto/2.9.168 Version/11.51",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; sv-se) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Opera/12.0(Windows NT 5.2;U;en)Presto/22.9.168 Version/12.00",
"Opera/9.80 (X11; Linux x86_64; U; bg) Presto/2.8.131 Version/11.10",
"Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/5.0 Opera 11.11",
"Opera/9.80 (Windows NT 6.1; U; en-GB) Presto/2.7.62 Version/11.007",
"Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; de) Opera 11.01",
"Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 12.14",
"Opera/9.80 (Windows NT 5.1; U;) Presto/2.7.62 Version/11.017"
) {
val randomUserAgent: String = this[Random.Default.nextInt(0 until this.size)]
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p><a href="http://www.kyotoanimation.co.jp/">京都动画</a>作品<a
href="https://www.bilibili.com/bangumi/media/md3365/?from=search&seid=14448313700764690387">《境界的彼方》</a><a
href="https://zh.moegirl.org/zh-hans/%E6%A0%97%E5%B1%B1%E6%9C%AA%E6%9D%A5">栗山未来(Kuriyama <b>Mirai</b>)</a></p>
<p><a href="https://www.crypton.co.jp/miku_eng">初音未来</a>的线下创作文化活动<a href="https://magicalmirai.com/2019/index_en.html">(Magical
<b>Mirai</b>)</a></p>
</body>
</html>
\ No newline at end of file
[female]
age progression = \u5e74\u9f84\u589e\u957f
age regression = \u8fd4\u8001\u8fd8\u7ae5
infantilism = \u5e7c\u7a1a\u578b
lolicon = \u841d\u8389
low lolicon = \u672a\u901a\u8fc7\u841d\u8389
milf = \u719f\u5973
old lady = \u8001\u5973\u4eba
toddlercon = \u5e7c\u5973
amputee = \u622a\u80a2
body modification = \u8eab\u4f53\u6539\u9020
conjoined = \u8fde\u4f53
doll joints = \u5173\u8282\u5a03\u5a03
gijinka = \u62df\u4eba\u5316
inflation = \u8179\u90e8\u81a8\u80c0
invisible = \u900f\u660e
multiple arms = \u591a\u81c2
multiple breasts = \u591a\u5bf9\u4e73\u623f
muscle = \u808c\u8089
muscle growth = \u808c\u8089\u6210\u957f
stretching = \u62c9\u4f38
tailjob = \u5c3e\u4ea4
wingjob = \u7ffc\u4ea4
wings = \u7fc5\u8180
absorption = \u5438\u6536
petrification = \u77f3\u5316
transformation = \u53d8\u8eab
alien girl = \u5916\u661f\u5973\ud83d\udc7d
angel = \u5929\u4f7f
bear girl = \u72d7\u718a\u5a18
bee girl = \u8702\u5973
bunny girl = \u5154\u5973\u90ce
catgirl = \u732b\u5973
centaur = \u534a\u4eba\u9a6c
cowgirl = \u725b\u5973\u5b69
deer girl = \u9e7f\u5973\u5b69
demon girl = \u6076\u9b54\u5973\u5b69
dog girl = \u72d7\u5973\u5b69
draenei = \u5fb7\u83b1\u5c3c
fairy = \u4ed9\u5973\ud83e\uddda\u2640\ufe0f
frog girl = \u9752\u86d9\u5973\u5b69
fox girl = \u72d0\u5973
furry = \u6bdb\u8338\u8338
giraffe girl = \u957f\u9888\u9e7f\u5a18
ghost = \u5e7d\u7075\ud83d\udc7b
goblin = \u5730\u7cbe
harpy = \u9e1f\u4eba
horse girl = \u9a6c\u5973\u5b69
human on furry = \u4eba\u6bdb
insect girl = \u6606\u866b\u5973\u5b69
kappa = \u6cb3\u7ae5
lizard girl = \u8725\u8734\u5973\u5b69
mermaid = \u7f8e\u4eba\u9c7c\ud83e\udddc\u2640\ufe0f
monkey girl = \u7334\u5973\u5b69
monster girl = \u602a\u7269\u5973\u5b69
mouse girl = \u9f20\u5973\u5b69
necrophilia = \u5978\u5c38
oni = \u9b3c
orc = \u517d\u4eba
panda girl = \u718a\u732b\u5a18
pig girl = \u732a\u5973
plant girl = \u690d\u7269\u5973\u5b69
raccoon girl = \u6d63\u718a\u5973\u5b69
robot = \u673a\u5668\u4eba\ud83e\udd16
shark girl = \u9ca8\u5973\u5b69
sheep girl = \u7f8a\u5973\u5b69
slime = \u53f2\u83b1\u59c6
slime girl = \u53f2\u83b1\u59c6\u5973\u5b69
snake girl = \u86c7\u5973
spider girl = \u8718\u86db\u5a18
squid girl = \u4e4c\u8d3c\u5a18
squirrel girl = \u677e\u9f20\u5a18
tentacles = \u89e6\u624b
vampire = \u5438\u8840\u9b3c\ud83e\udddb\u2640\ufe0f
wolf girl = \u72fc\u5973\u5b69
zombie = \u50f5\u5c38\ud83e\udddf\u2640\ufe0f
bestiality = \u517d\u4ea4
animal on animal = \u517d\u517d
animal on furry = \u517d\u6bdb
bear = \u718a\ud83d\udc3b
camel = \u9a86\u9a7c\ud83d\udc2a
cat = \u732b\ud83d\udc08
cow = \u725b\ud83d\udc04
crab = \u8783\u87f9\ud83e\udd80
dinosaur = \u6050\u9f99\ud83e\udd95
dog = \u72d7\ud83d\udc29
dolphin = \u6d77\u8c5a\ud83d\udc2c
donkey = \u9a74
dragon = \u9f99\ud83d\udc09
eel = \u9cd7\u9c7c
elephant = \u8c61\ud83d\udc18
fish = \u9c7c\ud83d\udc1f
fox = \u72d0\u72f8\ud83e\udd8a
frog = \u9752\u86d9\ud83d\udc38
goat = \u5c71\u7f8a\ud83d\udc10
gorilla = \u7329\u7329\ud83e\udd8d
horse = \u9a6c\ud83d\udc0e
insect = \u6606\u866b\ud83d\udc1c
kangaroo = \u888b\u9f20
lioness = \u72ee\ud83e\udd81
low bestiality = \u672a\u901a\u8fc7\u517d\u4ea4
maggot = \u86c6\ud83d\udc1b
monkey = \u7334\ud83d\udc12
mouse = \u9f20\ud83d\udc01
octopus = \u7ae0\u9c7c\ud83e\udd91
ostrich = \u9e35\u9e1f
panther = \u8c79\ud83d\udc06
pig = \u732a\ud83d\udc16
rabbit = \u5154\ud83d\udc07
reptile = \u722c\u866b
rhinoceros = \u7280\u725b\ud83e\udd8f
sheep = \u7ef5\u7f8a\ud83d\udc11
shark = \u9ca8\ud83e\udd88
slug = \u86de\u8753
snake = \u86c7\ud83d\udc0d
spider = \u8718\u86db\ud83d\udd77
tiger = \u864e\ud83d\udc05
turtle = \u9f9f\ud83d\udc22
unicorn = \u72ec\u89d2\u517d\ud83e\udd84
whale = \u9cb8\ud83d\udc0b
wolf = \u72fc\ud83d\udc3a
worm = \u8815\u866b
zebra = \u6591\u9a6c\ud83e\udd93
giantess = \u5973\u5de8\u4eba
growth = \u5de8\u5927\u5316
midget = \u4f8f\u5112
minigirl = \u8ff7\u4f60\u5973\u5b69
shrinking = \u7f29\u5c0f
tall girl = \u9ad8\u4e2a\u5973
albino = \u767d\u5316
body writing = \u8eab\u4f53\u5199\u4f5c
body painting = \u8eab\u4f53\u7ed8\u753b
dark skin = \u80a4\u8272\u9edd\u9ed1
freckles = \u96c0\u6591
gyaru = \u8fa3\u59b9
large tattoo = \u5168\u8eab\u7eb9\u8eab
scar = \u7622\u75d5
skinsuit = \u76ae\u7269
tanlines = \u6652\u75d5
anorexic = \u7626\u9aa8\u5d99\u5ccb
bbw = \u80d6\u5973\u4eba
ssbbw = \u8d85\u7ea7\u80d6\u5973\u4eba
weight gain = \u4f53\u91cd\u589e\u52a0
ahegao = \u963f\u9ed1\u989c
beauty mark = \u7f8e\u4eba\u75e3
brain fuck = \u8111\u4ea4\ud83e\udde0
cockslapping = \u5c4c\u63b4
crown = \u738b\u51a0\ud83d\udc51
ear fuck = \u8033\u4ea4\ud83d\udc42
elf = \u7cbe\u7075\ud83e\udddd\u2640\ufe0f
facesitting = \u5750\u8138
gasmask = \u9632\u6bd2\u9762\u5177
horns = \u89d2
makeup = \u5316\u5986
kemonomimi = \u517d\u8033
masked face = \u5047\u9762
thick eyebrows = \u6d53\u7709
arfo = \u7206\u70b8\u5934
bald = \u79c3\u9876
hair buns = \u4e38\u5b50\u5934
hairjob = \u53d1\u4e1d\u4ea4
pixie cut = \u7cbe\u7075\u5934
ponytail = \u9a6c\u5c3e\u8fab
prehensile hair = \u6293\u63e1\u53d1
shaved head = \u5149\u5934
twintails = \u53cc\u9a6c\u5c3e
body swap = \u6362\u8eab
chloroform = \u8ff7\u836f
corruption = \u5815\u843d
drugs = \u836f\u7269
drunk = \u9189\u9152
emotionless sex = \u6027\u51b7\u6de1
mind break = \u6d17\u8111
mind control = \u7cbe\u795e\u63a7\u5236
moral degeneration = \u9053\u5fb7\u9000\u5316
parasite = \u5bc4\u751f
possession = \u51ed\u4f9d
shared senses = \u611f\u5b98\u5171\u4eab
sleeping = \u7761\u89c9
blindfold = \u906e\u773c\u5e03
closed eyes = \u95ed\u773c
cum in eye = \u773c\u5c04
dark sclera = \u6df1\u8272\u5de9\u819c
eye penetration = \u63d2\u5165\u773c\u775b
eyemask = \u773c\u90e8\u9762\u5177
eyepatch = \u773c\u7f69
glasses = \u773c\u955c\ud83d\udc53
heterochromia = \u5f02\u8272\u77b3
monoeye = \u72ec\u773c
sunglasses = \u592a\u9633\u955c\ud83d\udd76
unusual pupils = \u5f02\u77b3
nose fuck = \u9f3b\u4ea4
nose hook = \u9f3b\u540a\u94a9
smell = \u6c14\u5473
big lips = \u5927\u5634\u5507\ud83d\udc8b
blowjob = \u53e3\u4ea4
blowjob face = \u53e3\u4ea4\u989c
braces = \u7259\u5957
burping = \u6253\u55dd
coprophagia = \u98df\u7caa
deepthroat = \u6df1\u5589
double blowjob = \u53cc\u91cd\u53e3\u4ea4
foot licking = \u8214\u8db3
gag = \u53e3\u585e
gokkun = \u996e\u7cbe
kissing = \u63a5\u543b\ud83d\udc8f
long tongue = \u957f\u820c\ud83d\udc45
piss drinking = \u996e\u5c3f
rimjob = \u8214\u809b
saliva = \u553e\u6db2
smoking = \u5438\u70df\ud83d\udeac
tooth brushing = \u5237\u7259
unusual teeth = \u5f02\u9f7f
vomit = \u5455\u5410\ud83e\udd2e
vore = \u541e\u98df
asphyxiation = \u7a92\u606f
collar = \u9879\u5708
leash = \u72d7\u94fe
armpit licking = \u814b\u4e0b\u8214
armpit sex = \u814b\u4ea4
hairy armpits = \u814b\u6bdb
fingering = \u6307\u6cd5
fisting = \u62f3\u4ea4\ud83d\udcaa
gloves = \u624b\u5957
handjob = \u6253\u624b\u67aa
big areolae = \u5927\u4e73\u6655
big breasts = \u5de8\u4e73
breast expansion = \u4e73\u623f\u81a8\u80c0
breast feeding = \u54fa\u4e73
breast reduction = \u4e73\u623f\u7f29\u5c0f
gigantic breasts = \u6781\u4e73
huge breasts = \u8d85\u4e73
lactation = \u6bcd\u4e73
milking = \u6324\u5976
multiple paizuri = \u591a\u91cd\u4e73\u4ea4
oppai loli = \u5de8\u4e73\u841d\u8389
paizuri = \u4e73\u4ea4
clothed paizuri = \u7a7f\u8863\u4e73\u4ea4
small breasts = \u8d2b\u4e73
big nipples = \u5927\u4e73\u5934
dark nipples = \u6697\u8272\u4e73\u5934
dicknipples = \u9634\u830e\u4e73\u5934
inverted nipples = \u4e73\u5934\u5185\u9677
multiple nipples = \u591a\u4e73\u5934
nipple birth = \u4e73\u5934\u51fa\u4ea7
nipple expansion = \u4e73\u5934\u81a8\u80c0
nipple fuck = \u4e73\u7a74\u6027\u4ea4
navel fuck = \u809a\u8110\u5978
pregnant = \u6000\u5b55
stomach deformation = \u8179\u90e8\u53d8\u5f62
chastity belt = \u8d1e\u64cd\u5e26
crotch tattoo = \u88c6\u90e8\u7eb9\u8eab
hairy = \u591a\u6bdb
pantyjob = \u5185\u88e4\u4ea4
pubic stubble = \u9634\u6bdb\u832c
urethra insertion = \u5c3f\u9053\u63d2\u5165
adventitious penis = \u7578\u4f4d\u9634\u830e
balls expansion = \u777e\u4e38\u751f\u957f
ball sucking = \u5438\u7403
balljob = \u7403\u4ea4
big balls = \u5927\u777e\u4e38
big penis = \u5927\u6839
dick growth = \u9634\u830e\u751f\u957f
frottage = \u9634\u830e\u6469\u64e6
horse cock = \u9a6c\u6839
huge penis = \u5de8\u6839
multiple penises = \u9e21\u9e21\u590d\u9e21\u9e21
penis birth = \u9634\u830e\u51fa\u4ea7
phimosis = \u5305\u830e
prostate massage = \u524d\u5217\u817a\u6309\u6469
smegma = \u9634\u57a2
adventitious vagina = \u7578\u4f4d\u9634\u9053
big clit = \u5927\u9634\u8482
big vagina = \u5927\u9634\u9053
birth = \u51fa\u4ea7
cervix penetration = \u5b50\u5bab\u9888\u7a7f\u900f
clit growth = \u9634\u8482\u751f\u957f
clit insertion = \u9634\u8482\u63d2\u5165
cunnilingus = \u8214\u9634
defloration = \u7834\u5904
multiple vaginas = \u591a\u9634\u9053
tribadism = \u8d1d\u5408
anal = \u809b\u4ea4
anal birth = \u809b\u95e8\u51fa\u4ea7
ass expansion = \u81c0\u90e8\u81a8\u80c0
assjob = \u5c3b\u4ea4
big ass = \u5927\u5c41\u80a1
enema = \u704c\u80a0
farting = \u653e\u5c41
spanking = \u6253\u5c41\u80a1
tail = \u5c3e\u5df4
eggs = \u4ea7\u5375
gaping = \u655e\u53e3
large insertions = \u5927\u73a9\u5177
nakadashi = \u4e2d\u51fa
prolapse = \u8131\u5782
unbirth = \u5165\u9634
kneepit sex = \u819d\u4e0b\u6027\u4ea4
leg lock = \u52fe\u817f
legjob = \u817f\u4ea4
sumata = \u80a1\u95f4\u6027\u4ea4
denki anma = \u7535\u6c14\u6309\u6469
foot insertion = \u8db3\u63d2\u5165
footjob = \u8db3\u4ea4
sockjob = \u889c\u4ea4\ud83e\udde6
apron = \u56f4\u88d9
bandages = \u7ef7\u5e26
vaginal sticker = \u9634\u8d34
bandaid = \u521b\u53ef\u8d34
bike shorts = \u81ea\u884c\u8f66\u77ed\u88e4
bikini = \u6bd4\u57fa\u5c3c\ud83d\udc59
bloomers = \u5e03\u9c81\u9a6c
bodystocking = \u8fde\u8eab\u889c
bodysuit = \u8fde\u4f53\u7d27\u8eab\u8863
bride = \u5a5a\u7eb1
business suit = \u897f\u88c5
butler = \u7ba1\u5bb6
cashier = \u6536\u94f6\u5458
cheerleader = \u5566\u5566\u961f\u5458
chinese dress = \u5510\u88c5
christmas = \u5723\u8bde\u88c5\ud83e\udd36
clothed male nude female = \u88f8\u5973
clown = \u5c0f\u4e11\ud83e\udd21
condom = \u907f\u5b55\u5957
corset = \u7d27\u8eab\u5185\u8863
cosplaying = Cosplay
crossdressing = \u5f02\u6027\u88c5
diaper = \u5c3f\u5e03
dougi = \u7ec3\u529f\u670d\ud83e\udd4b
fishnets = \u6e14\u7f51
fundoshi = \u516d\u5c3a\u890c
garter belt = \u540a\u889c\u5e26
gothic lolita = \u54e5\u7279\u841d\u8389\u88c5
gymshorts = \u8fd0\u52a8\u77ed\u88e4
haigure = \u9ad8\u53c9\u88c5
hijab = \u5934\u5dfe
hotpants = \u70ed\u88e4
kigurumi = \u5168\u8eab\u5957\u88c5
kimono = \u548c\u670d\ud83d\udc58
kindergarten uniform = \u5e7c\u513f\u56ed\u5236\u670d
kunoichi = \u5973\u5fcd\u88c5
lab coat = \u767d\u5927\u8902
latex = \u4e73\u80f6\u7d27\u8eab\u8863
leotard = \u7d27\u8eab\u8863
lingerie = \u60c5\u8da3\u5185\u8863
living clothes = \u751f\u7269\u8863
magical girl = \u9b54\u6cd5\u5c11\u5973
maid = \u5973\u4ec6\u88c5
mecha girl = \u673a\u5a18
metal armor = \u91d1\u5c5e\u76d4\u7532
miko = \u5deb\u5973\u88c5
military = \u519b\u88c5
nazi = \u7eb3\u7cb9\u519b\u88c5
nun = \u4fee\u5973\u670d
nurse = \u62a4\u58eb\u88c5
pantyhose = \u8fde\u88e4\u889c
pasties = \u4e73\u8d34
piercing = \u7a7f\u5b54
pirate = \u6d77\u76d7\u670d
policewoman = \u8b66\u670d
ponygirl = \u5c0f\u9a6c\u5973
race queen = \u8d5b\u8f66\u5973\u90ce
randoseru = \u4e66\u5305
sarashi = \u7f20\u80f8\u5e03
schoolboy uniform = \u7537\u751f\u5236\u670d
schoolgirl uniform = \u5973\u751f\u5236\u670d
scrotal lingerie = \u9634\u56ca\u888b
small penis = \u5c0f\u5c0f\u9e1f
shimapan = \u6761\u7eb9\u80d6\u6b21
stewardess = \u7a7a\u59d0\u670d
steward = \u7537\u7a7a\u4e58\u670d
stockings = \u957f\u7b52\u889c
swimsuit = \u6cf3\u88c5
school swimsuit = \u6b7b\u5e93\u6c34
sundress = \u590f\u88c5
thigh high boots = \u9ad8\u7b52\u9774
tiara = \u5b9d\u51a0
tights = \u7d27\u8eab\u670d
tracksuit = \u8fd0\u52a8\u670d
waiter = \u7537\u4f8d\u8005\u88c5
waitress = \u5973\u4f8d\u8005\u88c5
wet clothes = \u6e7f\u8eab
witch = \u5973\u5deb\u88c5
double anal = \u53cc\u63d2\u809b\u95e8
double vaginal = \u53cc\u63d2\u9634\u9053
fft threesome = \u5973\u5973\u6276
group = \u4e71\u4ea4
harem = \u540e\u5bab
layer cake = \u5939\u5fc3\u86cb\u7cd5
oyakodon = \u6bcd\u5973\u4e3c
triple anal = \u4e09\u63d2\u809b\u95e8
triple vaginal = \u4e09\u63d2\u9634\u9053
ttf threesome = \u6276\u6276\u5973
twins = \u53cc\u80de\u80ce
all the way through = \u6d88\u5316\u9053\u8d2f\u7a7f
double penetration = \u53cc\u91cd\u63d2\u5165
triple penetration = \u4e09\u91cd\u63d2\u5165
clamp = \u5939\u5177
glory hole = \u5bfb\u6b22\u6d1e
machine = \u673a\u68b0\u5978
onahole = \u98de\u673a\u676f
pillory = \u67b7\u5177
pole dancing = \u94a2\u7ba1\u821e
real doll = \u5145\u6c14\u5a03\u5a03
sex toys = \u6027\u73a9\u5177
speculum = \u6269\u5f20\u5668
strap-on = \u7a7f\u6234\u5f0f\u9633\u5177
syringe = \u6ce8\u5c04\u5668
tail plug = \u5c3e\u585e
tube = \u63d2\u7ba1
vacbed = \u771f\u7a7a\u5e8a
whip = \u97ad\u6253
wooden horse = \u6728\u9a6c
wormhole = \u866b\u6d1e
oil = \u6cb9
underwater = \u6c34\u4e0b
blood = \u6d41\u8840
squirting = \u6f6e\u5439
bukkake = \u7cbe\u6db2\u8986\u76d6
cum bath = \u7cbe\u6db2\u6d74
cum swap = \u4ea4\u6362\u7cbe\u6db2
low scat = \u672a\u901a\u8fc7\u6392\u4fbf
menstruation = \u7ecf\u8840
omorashi = \u6f0f\u5c3f
public use = \u8089\u4fbf\u5668
scat = \u6392\u4fbf\ud83d\udca9
sweating = \u51fa\u6c57
urination = \u6392\u5c3f
chikan = \u75f4\u6c49
rape = \u5f3a\u5978
bdsm = \u8c03\u6559
femdom = \u5973\u6027\u4e3b\u5bfc
forniphilia = \u4eba\u4f53\u5bb6\u5177
human cattle = \u4eba\u7c7b\u9972\u517b
human pet = \u4eba\u5ba0
orgasm denial = \u9ad8\u6f6e\u7981\u6b62
slave = \u5974\u96b6
tickling = \u6320\u75d2
bondage = \u675f\u7f1a
harness = \u633d\u5177
shibari = \u6346\u7ed1
stuck in wall = \u5361\u5728\u5899\u4e0a
abortion = \u5815\u80ce
cannibalism = \u98df\u4eba
catfight = \u732b\u6597
cbt = CBT
dismantling = \u62c6\u89e3
guro = \u80a2\u89e3
electric shocks = \u7535\u51fb
ryona = \u54c0\u568e
snuff = \u6740\u5bb3
torture = \u62f7\u6253
trampling = \u8df5\u8e0f
wrestling = \u6454\u89d2
autofellatio = \u81ea\u5439
autopaizuri = \u81ea\u4e73\u4ea4
masturbation = \u81ea\u6170
phone sex = \u7535\u8bdd\u6027\u7231
selfcest = \u81ea\u4ea4
solo action = \u81ea\u6478
table masturbation = \u684c\u89d2\u81ea\u6170
blind = \u5931\u660e
handicapped = \u6b8b\u75be
mute = \u54d1\u5df4
futanari = \u6276\u5979
gender bender = \u6027\u8f6c\u6362
shemale = \u4eba\u5996\u2642
bisexual = \u53cc\u6027
dickgirl on dickgirl = \u6276\u4e0a\u6276
male on dickgirl = \u7537\u4e0a\u6276
first person perspective = \u7b2c\u4e00\u4eba\u79f0\u89c6\u89d2
x-ray = \u900f\u89c6
blackmail = \u52d2\u7d22
coach = \u6559\u7ec3
impregnation = \u53d7\u5b55
prostitution = \u63f4\u4ea4
teacher = \u6559\u5e08
tomboy = \u5047\u5c0f\u5b50
tutor = \u5bb6\u5ead\u6559\u5e08
vtuber = \u865a\u62df\u4e3b\u64ad
widow = \u5be1\u5987
yandere = \u75c5\u5a07
yuri = \u767e\u5408
dickgirls only = \u7eaf\u6276\u5979
females only = \u7eaf\u5973\u6027\u26a2
sole dickgirl = \u5355\u6276\u5979
sole female = \u5355\u5973\u4e3b
cheating = \u51fa\u8f68
netorare = NTR
swinging = \u6362\u59bb
aunt = \u963f\u59e8
cousin = \u8868\u59d0\u59b9
daughter = \u5973\u513f
granddaughter = \u5b59\u5973
grandmother = \u7956\u6bcd
incest = \u4e71\u4f26
inseki = \u59fb\u4eb2
mother = \u6bcd\u4eb2
niece = \u4f84\u5973
sister = \u59d0\u59b9
exhibitionism = \u9732\u9634\u7656
filming = \u6444\u50cf
hidden sex = \u9690\u853d\u6027\u4ea4
humiliation = \u5c48\u8fb1
voyeurism = \u5077\u7aa5
[misc]
yukkuri = \u6cb9\u5e93\u91cc
animal on animal = \u517d\u517d
body swap = \u6362\u8eab
frottage = \u9634\u830e\u6469\u64e6
ffm threesome = \u5973\u7537\u5973
group = \u4e71\u4ea4
mmf threesome = \u7537\u5973\u7537
mmt threesome = \u7537\u6276\u7537
mtf threesome = \u7537\u6276\u5973
oyakodon = \u4eb2\u5b50\u4e3c
ttm threesome = \u6276\u6276\u7537
twins = \u53cc\u80de\u80ce
dakimakura = \u62b1\u6795
time stop = \u65f6\u95f4\u505c\u6b62\u23f1\ufe0f
3d = 3D
anaglyph = \u7ea2\u84dd3D
animated = \u52a8\u56fe
anthology = \u9009\u96c6
artbook = \u753b\u96c6
comic = \u8fde\u73af\u6f2b\u753b
figure = \u624b\u529e
full color = \u5168\u5f69\u8272
game sprite = \u50cf\u7d20\u753b
how to = \u6559\u7a0b
multi-work series = \u7cfb\u5217\u4f5c\u54c1
novel = \u5c0f\u8bf4
paperchild = \u7eb8\u7247\u4eba
redraw = \u91cd\u7ed8
screenshots = \u622a\u56fe
stereoscopic = \u7acb\u4f53\u56fe
story arc = \u6545\u4e8b\u7ebf
tankoubon = \u5355\u884c\u672c
themeless = \u65e0\u4e3b\u9898
variant set = \u53d8\u4f53\u96c6
webtoon = Webtoon
western cg\u200e = \u897f\u65b9CG\u96c6
western non-h = \u897f\u65b9\u65e0H
western imageset = \u897f\u65b9\u56fe\u7247\u96c6
uncensored = \u65e0\u4fee\u6b63
mosaic censorship = \u9a6c\u8d5b\u514b\u4fee\u6b63
full censorship = \u5b8c\u5168\u4fee\u6b63
hardcore = \u786c\u6838
non-nude = \u65e0\u88f8\u4f53
already uploaded = \u5df2\u4e0a\u4f20
compilation = \u91cd\u590d
forbidden content = \u7981\u6b62\u5185\u5bb9
realporn = \u771f\u4eba\u8272\u60c5
replaced = \u5df2\u66ff\u6362
watermarked = \u6c34\u5370
incomplete = \u7f3a\u9875
missing cover = \u7f3a\u5c01\u9762
out of order = \u987a\u5e8f\u9519\u4e71
sample = \u6837\u672c
scanmark = \u6c34\u5370
caption = \u8bf4\u660e\u6587\u5b57
poor grammar = \u6e23\u7ffb
nudity only = \u4ec5\u88f8\u4f53
no penetration = \u65e0\u63d2\u5165
incest = \u4e71\u4f26
inseki = \u59fb\u4eb2
thumbelina = \u62c7\u6307\u59d1\u5a18
apply plugin: "java"
apply plugin: "kotlin"
dependencies {
runtimeOnly files("../../mirai-core/build/classes/kotlin/jvm/main") // IDE bug
runtimeOnly files("../../mirai-core-qqandroid/build/classes/kotlin/jvm/main") // IDE bug
implementation project(":mirai-core-qqandroid")
implementation project(":mirai-japt")
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
\ No newline at end of file
package demo;
import net.mamoe.mirai.japt.BlockingBot;
import net.mamoe.mirai.japt.BlockingContacts;
import net.mamoe.mirai.japt.BlockingQQ;
import net.mamoe.mirai.japt.Events;
import net.mamoe.mirai.message.GroupMessage;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.Image;
import net.mamoe.mirai.message.data.MessageUtils;
import net.mamoe.mirai.utils.BotConfiguration;
import net.mamoe.mirai.utils.SystemDeviceInfoKt;
import java.io.File;
class BlockingTest {
public static void main(String[] args) throws InterruptedException {
// 使用自定义的配置
BlockingBot bot = BlockingBot.newInstance(123456, "", new BotConfiguration() {
{
setDeviceInfo(context ->
SystemDeviceInfoKt.loadAsDeviceInfo(new File("deviceInfo.json"), context)
);
setHeartbeatPeriodMillis(50 * 1000);
}
});
// 使用默认的配置
// BlockingBot bot = BlockingBot.newInstance(123456, "");
bot.login();
bot.getFriendList().forEach(friend -> {
System.out.println(friend.getNick());
});
Events.subscribeAlways(GroupMessage.class, (GroupMessage message) -> {
final BlockingQQ sender = BlockingContacts.createBlocking(message.getSender());
sender.sendMessage("Hello World!");
System.out.println("发送完了");
sender.sendMessage(MessageUtils.newChain()
.plus(new At(message.getSender()))
.plus(Image.fromId("{xxxx}.jpg"))
.plus("123465")
);
});
Thread.sleep(999999999);
}
}
......@@ -21,34 +21,14 @@ pluginManagement {
rootProject.name = 'mirai'
include(':mirai-demos')
try {
def keyProps = new Properties()
def keyFile = file("local.properties")
if (keyFile.exists()) keyFile.withInputStream { keyProps.load(it) }
if (!keyProps.getProperty("sdk.dir", "").isEmpty()) {
include(':mirai-demos:mirai-demo-android')
project(':mirai-demos:mirai-demo-android').projectDir = file('mirai-demos/mirai-demo-android')
} else {
println("Android SDK 可能未安装. \n将不会加载模块 `mirai-demo-android`, 但这并不影响其他 demo 的加载 ")
println("Android SDK might not be installed. \nModule `mirai-demo-android` will not be included, but other demos will not be influenced")
}
} catch (Exception e) {
e.printStackTrace()
}
include(':mirai-core')
//include(':mirai-core-timpc')
include(':mirai-core-qqandroid')
//include(':mirai-api')
include(':mirai-api-http')
include(':mirai-demos:mirai-demo-1')
include(':mirai-demos:mirai-demo-gentleman')
include(':mirai-demos:mirai-demo-java')
include(':mirai-plugins')
include(':mirai-plugins:image-sender')
//include(':mirai-plugins')
//include(':mirai-plugins:image-sender')
try{
def javaVersion = System.getProperty("java.version")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment