Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
Mirai
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
Mirai
Commits
38e3f133
Commit
38e3f133
authored
Sep 29, 2019
by
liujiahua123123
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
615de9ef
312fb437
Changes
47
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
47 changed files
with
508 additions
and
328 deletions
+508
-328
README.md
README.md
+8
-7
mirai-api/pom.xml
mirai-api/pom.xml
+8
-0
mirai-console/pom.xml
mirai-console/pom.xml
+1
-1
mirai-console/src/main/java/net/mamoe/mirai/MiraiConsole.java
...i-console/src/main/java/net/mamoe/mirai/MiraiConsole.java
+1
-3
mirai-console/src/main/java/net/mamoe/mirai/MiraiMain.java
mirai-console/src/main/java/net/mamoe/mirai/MiraiMain.java
+0
-0
mirai-console/src/main/java/net/mamoe/mirai/MiraiServer.java
mirai-console/src/main/java/net/mamoe/mirai/MiraiServer.java
+4
-6
mirai-core/src/main/java/net/mamoe/mirai/Bot.java
mirai-core/src/main/java/net/mamoe/mirai/Bot.java
+6
-28
mirai-core/src/main/java/net/mamoe/mirai/BotKt.kt
mirai-core/src/main/java/net/mamoe/mirai/BotKt.kt
+29
-0
mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt
mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt
+8
-7
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
+2
-2
mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt
mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt
+2
-2
mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventHookKt.kt
...e/src/main/java/net/mamoe/mirai/event/MiraiEventHookKt.kt
+13
-4
mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManagerKt.kt
...rc/main/java/net/mamoe/mirai/event/MiraiEventManagerKt.kt
+28
-13
mirai-core/src/main/java/net/mamoe/mirai/event/events/group/GroupMessageEvent.java
...net/mamoe/mirai/event/events/group/GroupMessageEvent.java
+0
-38
mirai-core/src/main/java/net/mamoe/mirai/event/events/group/GroupMessageEvent.kt
...a/net/mamoe/mirai/event/events/group/GroupMessageEvent.kt
+25
-0
mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketReceivedEvent.java
...mirai/event/events/network/ServerPacketReceivedEvent.java
+2
-2
mirai-core/src/main/java/net/mamoe/mirai/event/events/qq/FriendMessageEvent.java
...a/net/mamoe/mirai/event/events/qq/FriendMessageEvent.java
+0
-20
mirai-core/src/main/java/net/mamoe/mirai/event/events/qq/FriendMessageEvent.kt
...ava/net/mamoe/mirai/event/events/qq/FriendMessageEvent.kt
+24
-0
mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt
mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt
+16
-5
mirai-core/src/main/java/net/mamoe/mirai/message/MessageKey.kt
...-core/src/main/java/net/mamoe/mirai/message/MessageKey.kt
+8
-0
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/At.kt
...core/src/main/java/net/mamoe/mirai/message/defaults/At.kt
+7
-3
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Face.kt
...re/src/main/java/net/mamoe/mirai/message/defaults/Face.kt
+9
-5
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.kt
...e/src/main/java/net/mamoe/mirai/message/defaults/Image.kt
+9
-4
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.kt
...ain/java/net/mamoe/mirai/message/defaults/MessageChain.kt
+28
-12
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/PlainText.kt
...c/main/java/net/mamoe/mirai/message/defaults/PlainText.kt
+9
-5
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/UnsolvedImage.kt
...in/java/net/mamoe/mirai/message/defaults/UnsolvedImage.kt
+2
-2
mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandlerImpl.kt
...ain/java/net/mamoe/mirai/network/BotNetworkHandlerImpl.kt
+57
-35
mirai-core/src/main/java/net/mamoe/mirai/network/NetworkScope.kt
...ore/src/main/java/net/mamoe/mirai/network/NetworkScope.kt
+6
-0
mirai-core/src/main/java/net/mamoe/mirai/network/handler/ActionPacketHandler.kt
...va/net/mamoe/mirai/network/handler/ActionPacketHandler.kt
+11
-8
mirai-core/src/main/java/net/mamoe/mirai/network/handler/DataPacketSocket.kt
.../java/net/mamoe/mirai/network/handler/DataPacketSocket.kt
+2
-17
mirai-core/src/main/java/net/mamoe/mirai/network/handler/MessagePacketHandler.kt
...a/net/mamoe/mirai/network/handler/MessagePacketHandler.kt
+4
-49
mirai-core/src/main/java/net/mamoe/mirai/network/handler/PacketHandler.kt
...ain/java/net/mamoe/mirai/network/handler/PacketHandler.kt
+1
-1
mirai-core/src/main/java/net/mamoe/mirai/network/handler/TemporaryPacketHandler.kt
...net/mamoe/mirai/network/handler/TemporaryPacketHandler.kt
+1
-1
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
.../main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
+0
-6
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
...c/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
+4
-4
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
.../main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
+1
-1
mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt
...n/java/net/mamoe/mirai/network/packet/VerificationCode.kt
+8
-8
mirai-core/src/main/java/net/mamoe/mirai/utils/BotAccount.java
...-core/src/main/java/net/mamoe/mirai/utils/BotAccount.java
+0
-13
mirai-core/src/main/java/net/mamoe/mirai/utils/BotAccount.kt
mirai-core/src/main/java/net/mamoe/mirai/utils/BotAccount.kt
+9
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfig.java
...c/main/java/net/mamoe/mirai/utils/config/MiraiConfig.java
+2
-6
mirai-core/src/test/java/BadQQFilter.kt
mirai-core/src/test/java/BadQQFilter.kt
+1
-1
mirai-core/src/test/java/ConfigTest.java
mirai-core/src/test/java/ConfigTest.java
+0
-8
mirai-core/src/test/java/PacketDebuger.kt
mirai-core/src/test/java/PacketDebuger.kt
+1
-1
mirai-demos/mirai-demo-1/pom.xml
mirai-demos/mirai-demo-1/pom.xml
+57
-0
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
+64
-0
mirai-demos/pom.xml
mirai-demos/pom.xml
+29
-0
pom.xml
pom.xml
+1
-0
No files found.
README.md
View file @
38e3f133
# Mirai
[

](http://hits.dwyl.io/him188/mamoe/mirai)
一个以
<b>
TIM QQ协议(非web)
</b>
驱动的
JAVA(+Kotlin) QQ机器人服务端核心
一个以
<b>
TIM QQ协议(非web)
</b>
驱动的
QQ机器人服务端核心
采用服务端-插件模式运行,同时提供独立的协议层库
**我们承诺项目的所有模块均开源**
...
...
@@ -17,23 +18,23 @@
1.
Clone
2.
Import as Maven project
3.
Run
[
MiraiMain
](
mirai-core/src/main/java/net/mamoe/mirai/MiraiMain.java#L7
)
3.
Run
demo
[
Demo 1 Main
](
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt#L16
)
### 事件 Hook
#### Java:
```
MiraiEventHook.onEvent(FriendMessageEvent.class)
.handler(a -> {
if(a.
getMessageString().equals
("你好"))
a.get
QQ
().sendMessage("你好!");
if(a.
message.eq
("你好"))
a.get
Sender
().sendMessage("你好!");
})
.mountAlways();
```
#### Kotlin:
```
FriendMessageEvent::class.hookAlways{
if(it.message
() valueEquals
"你好")
it.
qq.sendMessage
("你好!")
if(it.message
eq
"你好")
it.
reply
("你好!")
}
```

...
...
@@ -44,7 +45,7 @@ FriendMessageEvent::class.hookAlways{

发送图片已经完成,但我们还在开发上传图片至服务器。
现在你可以通过发送一张图片给机器人账号,再让机器人账号发送这张图片。你可以查看
[
Image
](
src/main/java/net/mamoe/mirai/message/Image.kt
)
现在你可以通过发送一张图片给机器人账号,再让机器人账号发送这张图片。你可以查看
[
Image
.kt
](
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.kt#L20-L93
)
## 语言使用说明
我们使用 Kotlin,但我们也会保留对 Java 和 Java开发者的支持。
...
...
mirai-api/pom.xml
View file @
38e3f133
...
...
@@ -22,6 +22,14 @@
<version>
1.0
</version>
<scope>
compile
</scope>
</dependency>
<dependency>
<groupId>
net.mamoe
</groupId>
<artifactId>
mirai-console
</artifactId>
<version>
1.0
</version>
<scope>
compile
</scope>
</dependency>
</dependencies>
<build>
...
...
mirai-console/pom.xml
View file @
38e3f133
...
...
@@ -18,7 +18,7 @@
<dependency>
<groupId>
net.mamoe
</groupId>
<artifactId>
mirai-
api
</artifactId>
<artifactId>
mirai-
core
</artifactId>
<version>
1.0
</version>
<scope>
compile
</scope>
</dependency>
...
...
mirai-console/src/main/java/net/mamoe/mirai/MiraiConsole.java
View file @
38e3f133
package
net.mamoe.mirai
;
import
java.util.Scanner
;
public
class
MiraiConsole
{
public
static
void
main
(
String
[]
args
){
System
.
out
.
println
(
">>> starting Mirai"
);
MiraiAPI
.
startMirai
(
args
);
//
MiraiAPI.startMirai(args);
}
public
static
void
processCommand
(
String
command
){
...
...
mirai-co
r
e/src/main/java/net/mamoe/mirai/MiraiMain.java
→
mirai-co
nsol
e/src/main/java/net/mamoe/mirai/MiraiMain.java
View file @
38e3f133
File moved
mirai-co
r
e/src/main/java/net/mamoe/mirai/MiraiServer.java
→
mirai-co
nsol
e/src/main/java/net/mamoe/mirai/MiraiServer.java
View file @
38e3f133
...
...
@@ -11,15 +11,12 @@ import net.mamoe.mirai.utils.LoggerTextFormat;
import
net.mamoe.mirai.utils.MiraiLogger
;
import
net.mamoe.mirai.utils.MiraiLoggerKt
;
import
net.mamoe.mirai.utils.config.MiraiConfig
;
import
net.mamoe.mirai.utils.config.MiraiConfigSection
;
import
net.mamoe.mirai.utils.setting.MiraiSettingListSection
;
import
net.mamoe.mirai.utils.setting.MiraiSettingMapSection
;
import
net.mamoe.mirai.utils.setting.MiraiSettings
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.Scanner
;
import
java.util.concurrent.ExecutionException
;
/**
...
...
@@ -91,6 +88,7 @@ public final class MiraiServer {
File
setting
=
new
File
(
this
.
parentFolder
+
"/Mirai.ini"
);
getLogger
().
info
(
"Selecting setting from "
+
LoggerTextFormat
.
GREEN
+
setting
);
/*
if (!setting.exists()) {
this.initSetting(setting);
} else {
...
...
@@ -106,7 +104,7 @@ public final class MiraiServer {
}
if (this.qqs.isEmpty()) {
this.initQQConfig(qqs);
}
}
*/
/*
MiraiSettingMapSection qqs = this.setting.getMapSection("qq");
...
...
@@ -198,12 +196,12 @@ public final class MiraiServer {
String
qqList
=
"
3034551466----zxcvbnm
\n"
;
"
1683921395----bb22222
\n"
;
private
Bot
getAvailableBot
()
throws
ExecutionException
,
InterruptedException
{
for
(
String
it
:
qqList
.
split
(
"\n"
))
{
var
strings
=
it
.
split
(
"----"
);
var
bot
=
new
Bot
(
new
BotAccount
(
Long
.
parseLong
(
strings
[
0
]),
strings
[
1
])
,
List
.
of
()
);
var
bot
=
new
Bot
(
new
BotAccount
(
Long
.
parseLong
(
strings
[
0
]),
strings
[
1
]));
if
(
bot
.
network
.
tryLogin
(
200
).
get
()
==
LoginState
.
SUCCESS
)
{
MiraiLoggerKt
.
success
(
bot
,
"Login succeed"
);
...
...
mirai-core/src/main/java/net/mamoe/mirai/Bot.java
View file @
38e3f133
package
net.mamoe.mirai
;
import
lombok.Getter
;
import
net.mamoe.mirai.contact.Group
;
import
net.mamoe.mirai.contact.QQ
;
import
net.mamoe.mirai.network.BotNetworkHandler
;
import
net.mamoe.mirai.network.BotNetworkHandlerImpl
;
import
net.mamoe.mirai.utils.BotAccount
;
import
net.mamoe.mirai.utils.ContactList
;
import
net.mamoe.mirai.utils.config.MiraiConfigSection
;
import
org.jetbrains.annotations.NotNull
;
import
java.io.Closeable
;
import
java.util.*
;
import
java.util.Collections
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.concurrent.atomic.AtomicInteger
;
/**
...
...
@@ -58,7 +59,7 @@ public final class Bot implements Closeable {
@Override
public
String
toString
()
{
return
String
.
format
(
"Bot{id=%d,qq=%d}"
,
id
,
this
.
account
.
qqNumber
);
return
String
.
format
(
"Bot{id=%d,qq=%d}"
,
id
,
this
.
account
.
getQqNumber
()
);
}
/**
...
...
@@ -93,32 +94,9 @@ public final class Bot implements Closeable {
}
}
/**
* Ref list
*/
@Getter
private
final
List
<
String
>
owners
;
public
boolean
isOwnBy
(
String
ownerName
)
{
return
owners
.
contains
(
ownerName
);
}
public
Bot
(
MiraiConfigSection
<
Object
>
data
)
throws
Throwable
{
this
(
new
BotAccount
(
data
.
getLongOrThrow
(
"account"
,
()
->
new
IllegalArgumentException
(
"account"
)),
data
.
getStringOrThrow
(
"password"
,
()
->
new
IllegalArgumentException
(
"password"
))
),
data
.
getAsOrDefault
(
"owners"
,
ArrayList:
:
new
)
);
}
public
Bot
(
@NotNull
BotAccount
account
,
@NotNull
List
<
String
>
owners
)
{
public
Bot
(
@NotNull
BotAccount
account
)
{
Objects
.
requireNonNull
(
account
);
Objects
.
requireNonNull
(
owners
);
this
.
account
=
account
;
this
.
owners
=
Collections
.
unmodifiableList
(
owners
);
this
.
network
=
new
BotNetworkHandlerImpl
(
this
);
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/BotKt.kt
0 → 100644
View file @
38e3f133
package
net.mamoe.mirai
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.network.packet.ClientPacket
/**
* The mirror of functions in inner classes of [Bot]
*
* @author Him188moe
*/
//Contacts
fun
Bot
.
getQQ
(
number
:
Long
):
QQ
=
this
.
contacts
.
getQQ
(
number
)
fun
Bot
.
getGroupByNumber
(
number
:
Long
):
Group
=
this
.
contacts
.
getGroupByNumber
(
number
)
fun
Bot
.
getGroupById
(
number
:
Long
):
Group
=
this
.
contacts
.
getGroupById
(
number
)
//NetworkHandler
suspend
fun
Bot
.
sendPacket
(
packet
:
ClientPacket
)
{
this
.
network
.
socket
.
sendPacket
(
packet
)
}
//BotAccount
fun
Bot
.
getBotQQ
():
Long
=
this
.
account
.
qqNumber
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt
View file @
38e3f133
...
...
@@ -18,10 +18,7 @@ import java.util.concurrent.CompletableFuture
* @author Him188moe
*/
abstract
class
Contact
internal
constructor
(
val
bot
:
Bot
,
val
number
:
Long
)
{
/**
* Async
*/
abstract
fun
sendMessage
(
message
:
MessageChain
)
abstract
suspend
fun
sendMessage
(
message
:
MessageChain
)
/**
* 上传图片
...
...
@@ -30,19 +27,23 @@ abstract class Contact internal constructor(val bot: Bot, val number: Long) {
return
image
.
upload
(
session
,
this
)
}
fun
sendMessage
(
message
:
Message
)
{
suspend
fun
sendMessage
(
message
:
Message
)
{
if
(
message
is
MessageChain
)
{
return
sendMessage
(
message
)
}
return
sendMessage
(
message
.
toChain
())
}
fun
sendMessage
(
message
:
String
)
{
suspend
fun
sendMessage
(
message
:
String
)
{
this
.
sendMessage
(
PlainText
(
message
))
}
suspend
fun
sendMessage
(
message
:
List
<
Message
>)
{
this
.
sendMessage
(
MessageChain
(
message
))
}
/**
* Async
*/
abstract
fun
sendXMLMessage
(
message
:
String
)
abstract
suspend
fun
sendXMLMessage
(
message
:
String
)
}
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
View file @
38e3f133
...
...
@@ -25,11 +25,11 @@ class Group(bot: Bot, number: Long) : Contact(bot, number), Closeable {
val
groupId
=
groupNumberToId
(
number
)
val
members
=
ContactList
<
QQ
>()
override
fun
sendMessage
(
message
:
MessageChain
)
{
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
bot
.
network
.
message
.
sendGroupMessage
(
this
,
message
)
}
override
fun
sendXMLMessage
(
message
:
String
)
{
override
suspend
fun
sendXMLMessage
(
message
:
String
)
{
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt
View file @
38e3f133
...
...
@@ -18,11 +18,11 @@ import net.mamoe.mirai.message.defaults.MessageChain
* @author Him188moe
*/
class
QQ
(
bot
:
Bot
,
number
:
Long
)
:
Contact
(
bot
,
number
)
{
override
fun
sendMessage
(
message
:
MessageChain
)
{
override
suspend
fun
sendMessage
(
message
:
MessageChain
)
{
bot
.
network
.
message
.
sendFriendMessage
(
this
,
message
)
}
override
fun
sendXMLMessage
(
message
:
String
)
{
override
suspend
fun
sendXMLMessage
(
message
:
String
)
{
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventHookKt.kt
View file @
38e3f133
package
net.mamoe.mirai.event
import
kotlinx.coroutines.runBlocking
import
java.util.function.Consumer
import
java.util.function.Predicate
...
...
@@ -7,12 +8,20 @@ import java.util.function.Predicate
* @author Him188moe
*/
class
MiraiEventHookKt
<
E
:
MiraiEvent
>(
eventClass
:
Class
<
E
>)
:
MiraiEventHook
<
E
>(
eventClass
)
{
fun
onEvent
(
handler
:
(
E
)
->
Unit
)
{
this
@MiraiEventHookKt
.
handler
=
Consumer
(
handler
)
fun
onEvent
(
handler
:
suspend
(
E
)
->
Unit
)
{
this
@MiraiEventHookKt
.
handler
=
Consumer
{
runBlocking
{
handler
(
it
)
}
}
}
fun
validChecker
(
predicate
:
(
E
)
->
Boolean
)
{
this
@MiraiEventHookKt
.
validChecker
=
Predicate
(
predicate
)
fun
validChecker
(
predicate
:
suspend
(
E
)
->
Boolean
)
{
//todo 把 mirai event 变为 suspend, 而不是在这里 run blocking
this
@MiraiEventHookKt
.
validChecker
=
Predicate
{
runBlocking
{
predicate
(
it
)
}
}
}
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManagerKt.kt
View file @
38e3f133
...
...
@@ -2,6 +2,8 @@
package
net.mamoe.mirai.event
import
kotlinx.coroutines.runBlocking
import
net.mamoe.mirai.Bot
import
kotlin.reflect.KClass
/**
...
...
@@ -18,50 +20,63 @@ object EventManager : MiraiEventManager()
/**
* 每次事件触发时都会调用 hook
*/
fun
<
C
:
Class
<
E
>,
E
:
MiraiEvent
>
C
.
hookAlways
(
hook
:
(
E
)
->
Unit
)
{
MiraiEventManager
.
getInstance
().
hookAlways
(
MiraiEventHook
<
E
>(
this
,
hook
))
fun
<
C
:
Class
<
E
>,
E
:
MiraiEvent
>
C
.
hookAlways
(
bot
:
Bot
?
=
null
,
hook
:
suspend
(
E
)
->
Unit
)
{
MiraiEventManager
.
getInstance
().
hookAlways
(
MiraiEventHook
<
E
>(
this
)
{
runBlocking
{
hook
(
it
)
}
})
}
/**
* 当下一次事件触发时调用 hook
*/
fun
<
C
:
Class
<
E
>,
E
:
MiraiEvent
>
C
.
hookOnce
(
hook
:
(
E
)
->
Unit
)
{
MiraiEventManager
.
getInstance
().
hookOnce
(
MiraiEventHook
<
E
>(
this
,
hook
))
fun
<
C
:
Class
<
E
>,
E
:
MiraiEvent
>
C
.
hookOnce
(
bot
:
Bot
?
=
null
,
hook
:
suspend
(
E
)
->
Unit
)
{
//todo bot 限制 实现. 或重写 hook
MiraiEventManager
.
getInstance
().
hookOnce
(
MiraiEventHook
<
E
>(
this
)
{
runBlocking
{
hook
(
it
)
}
})
}
/**
* 每次事件触发时都会调用 hook, 直到 hook 返回 false 时停止 hook
*/
fun
<
C
:
Class
<
E
>,
E
:
MiraiEvent
>
C
.
hookWhile
(
hook
:
(
E
)
->
Boolean
)
{
fun
<
C
:
Class
<
E
>,
E
:
MiraiEvent
>
C
.
hookWhile
(
bot
:
Bot
?
=
null
,
hook
:
suspend
(
E
)
->
Boolean
)
{
MiraiEventManager
.
getInstance
().
hookAlways
(
MiraiEventHookSimple
(
this
,
hook
))
}
/**
* 每次事件触发时都会调用 hook
*
* @param bot 指定仅限于某个 [Bot] 的事件.
*/
fun
<
C
:
KClass
<
E
>,
E
:
MiraiEvent
>
C
.
hookAlways
(
hook
:
(
E
)
->
Unit
)
{
this
.
java
.
hookAlways
(
hook
)
fun
<
C
:
KClass
<
E
>,
E
:
MiraiEvent
>
C
.
hookAlways
(
bot
:
Bot
?
=
null
,
hook
:
suspend
(
E
)
->
Unit
)
{
this
.
java
.
hookAlways
(
bot
,
hook
)
}
/**
* 当下一次事件触发时调用 hook
*/
fun
<
C
:
KClass
<
E
>,
E
:
MiraiEvent
>
C
.
hookOnce
(
hook
:
(
E
)
->
Unit
)
{
this
.
java
.
hookOnce
(
hook
)
fun
<
C
:
KClass
<
E
>,
E
:
MiraiEvent
>
C
.
hookOnce
(
bot
:
Bot
?
=
null
,
hook
:
suspend
(
E
)
->
Unit
)
{
this
.
java
.
hookOnce
(
bot
,
hook
)
}
/**
* 每次事件触发时都会调用 hook, 直到 hook 返回 false 时停止 hook
*/
fun
<
C
:
KClass
<
E
>,
E
:
MiraiEvent
>
C
.
hookWhile
(
hook
:
(
E
)
->
Boolean
)
{
this
.
java
.
hookWhile
(
hook
)
fun
<
C
:
KClass
<
E
>,
E
:
MiraiEvent
>
C
.
hookWhile
(
bot
:
Bot
?
=
null
,
hook
:
suspend
(
E
)
->
Boolean
)
{
this
.
java
.
hookWhile
(
bot
,
hook
)
}
private
class
MiraiEventHookSimple
<
E
:
MiraiEvent
>(
clazz
:
Class
<
E
>,
val
hook
:
(
E
)
->
Boolean
)
:
MiraiEventHook
<
E
>(
clazz
)
{
private
class
MiraiEventHookSimple
<
E
:
MiraiEvent
>(
clazz
:
Class
<
E
>,
val
hook
:
suspend
(
E
)
->
Boolean
)
:
MiraiEventHook
<
E
>(
clazz
)
{
override
fun
accept
(
event
:
MiraiEvent
?):
Boolean
{
@Suppress
(
"UNCHECKED_CAST"
)
return
!
hook
.
invoke
(
event
as
E
)
return
runBlocking
{
return
@
runBlocking
!
hook
.
invoke
(
event
as
E
)
}
}
}
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/event/events/group/GroupMessageEvent.java
deleted
100644 → 0
View file @
615de9ef
package
net.mamoe.mirai.event.events.group
;
import
net.mamoe.mirai.Bot
;
import
net.mamoe.mirai.contact.Group
;
import
net.mamoe.mirai.contact.QQ
;
import
net.mamoe.mirai.message.defaults.MessageChain
;
import
org.jetbrains.annotations.NotNull
;
/**
* @author Him188moe
*/
public
final
class
GroupMessageEvent
extends
GroupEvent
{
public
final
QQ
sender
;
public
final
MessageChain
chain
;
public
final
String
message
;
public
GroupMessageEvent
(
@NotNull
Bot
bot
,
@NotNull
Group
group
,
@NotNull
QQ
sender
,
@NotNull
MessageChain
chain
)
{
super
(
bot
,
group
);
this
.
sender
=
sender
;
this
.
chain
=
chain
;
this
.
message
=
chain
.
toString
();
}
@NotNull
public
MessageChain
getChain
()
{
return
chain
;
}
@NotNull
public
String
getMessage
()
{
return
message
;
}
@NotNull
public
QQ
getSender
()
{
return
sender
;
}
}
mirai-core/src/main/java/net/mamoe/mirai/event/events/group/GroupMessageEvent.kt
0 → 100644
View file @
38e3f133
package
net.mamoe.mirai.event.events.group
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.defaults.MessageChain
/**
* @author Him188moe
*/
class
GroupMessageEvent
(
bot
:
Bot
,
group
:
Group
,
val
sender
:
QQ
,
val
message
:
MessageChain
)
:
GroupEvent
(
bot
,
group
)
{
@JvmSynthetic
suspend
inline
fun
reply
(
message
:
Message
)
=
group
.
sendMessage
(
message
)
@JvmSynthetic
suspend
inline
fun
reply
(
message
:
String
)
=
group
.
sendMessage
(
message
)
@JvmSynthetic
suspend
inline
fun
reply
(
message
:
List
<
Message
>)
=
group
.
sendMessage
(
message
)
@JvmSynthetic
suspend
inline
fun
reply
(
message
:
MessageChain
)
=
group
.
sendMessage
(
message
)
}
mirai-core/src/main/java/net/mamoe/mirai/event/events/network/ServerPacketReceivedEvent.java
View file @
38e3f133
...
...
@@ -2,12 +2,12 @@ package net.mamoe.mirai.event.events.network;
import
net.mamoe.mirai.Bot
;
import
net.mamoe.mirai.event.Cancellable
;
import
net.mamoe.mirai.network.packet.ServerCatchaPacket
;
import
net.mamoe.mirai.network.packet.ServerPacket
;
import
net.mamoe.mirai.network.packet.ServerVerificationCodePacket
;
/**
* 服务器接到某数据包时触发这个事件.
* 注意, 当接收到数据包的加密包(如 {@link Server
VerificationCode
Packet.Encrypted})也会触发这个事件, 随后才会
* 注意, 当接收到数据包的加密包(如 {@link Server
Catcha
Packet.Encrypted})也会触发这个事件, 随后才会
*
* @author Him188moe
*/
...
...
mirai-core/src/main/java/net/mamoe/mirai/event/events/qq/FriendMessageEvent.java
View file @
38e3f133
package
net.mamoe.mirai.event.events.qq
;
import
net.mamoe.mirai.Bot
;
import
net.mamoe.mirai.contact.QQ
;
import
net.mamoe.mirai.message.defaults.MessageChain
;
import
org.jetbrains.annotations.NotNull
;
import
java.util.Objects
;
/**
* @author Him188moe
*/
public
final
class
FriendMessageEvent
extends
FriendEvent
{
public
final
MessageChain
message
;
public
FriendMessageEvent
(
@NotNull
Bot
bot
,
@NotNull
QQ
sender
,
@NotNull
MessageChain
message
)
{
super
(
bot
,
sender
);
this
.
message
=
Objects
.
requireNonNull
(
message
);
}
@NotNull
public
MessageChain
message
()
{
return
message
;
}
}
mirai-core/src/main/java/net/mamoe/mirai/event/events/qq/FriendMessageEvent.kt
0 → 100644
View file @
38e3f133
package
net.mamoe.mirai.event.events.qq
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.defaults.MessageChain
/**
* @author Him188moe
*/
class
FriendMessageEvent
(
bot
:
Bot
,
sender
:
QQ
,
val
message
:
MessageChain
)
:
FriendEvent
(
bot
,
sender
)
{
@JvmSynthetic
suspend
inline
fun
reply
(
message
:
Message
)
=
sender
.
sendMessage
(
message
)
@JvmSynthetic
suspend
inline
fun
reply
(
message
:
String
)
=
sender
.
sendMessage
(
message
)
@JvmSynthetic
suspend
inline
fun
reply
(
message
:
List
<
Message
>)
=
sender
.
sendMessage
(
message
)
@JvmSynthetic
suspend
inline
fun
reply
(
message
:
MessageChain
)
=
sender
.
sendMessage
(
message
)
}
mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt
View file @
38e3f133
...
...
@@ -15,8 +15,8 @@ import java.util.*
* #### 在 Kotlin 使用 [Message]
* 这与使用 [String] 的使用非常类似.
*
* 比较 [Message] 与 [String] (使用 infix [Message.
valueEquals
]):
* `if(message
valueEquals
"你好") qq.sendMessage(message)`
* 比较 [Message] 与 [String] (使用 infix [Message.
eq
]):
* `if(message
eq
"你好") qq.sendMessage(message)`
*
* 连接 [Message] 与 [Message], [String], [BufferedImage] (使用 operator [Message.plus]):
* ```
...
...
@@ -28,7 +28,7 @@ import java.util.*
* @see Contact.sendMessage
*/
abstract
class
Message
{
internal
abstract
val
type
:
Int
internal
abstract
val
type
:
MessageKey
private
var
toStringCache
:
String
?
=
null
private
val
cacheLock
=
object
:
Any
()
{}
...
...
@@ -76,12 +76,17 @@ abstract class Message {
* - [PlainText] 比较 [PlainText.text]
* - [Image] 比较 [Image.imageId]
*/
abstract
infix
fun
valueEquals
(
another
:
Message
):
Boolean
abstract
infix
fun
eq
(
another
:
Message
):
Boolean
/**
* 将这个消息的 [toString] 与 [another] 比较
*/
infix
fun
valueEquals
(
another
:
String
):
Boolean
=
this
.
toString
()
==
another
infix
fun
eq
(
another
:
String
):
Boolean
=
this
.
toString
()
==
another
/**
* 判断 [sub] 是否存在于本消息中
*/
abstract
operator
fun
contains
(
sub
:
String
):
Boolean
/**
* 把这个消息连接到另一个消息的头部. 相当于字符串相加
...
...
@@ -104,6 +109,12 @@ abstract class Message {
* @return message connected
*/
open
fun
concat
(
tail
:
Message
):
MessageChain
{
if
(
tail
is
MessageChain
)
{
return
MessageChain
(
this
).
let
{
tail
.
list
.
forEach
{
child
->
it
.
concat
(
child
)
}
it
}
}
return
MessageChain
(
this
,
Objects
.
requireNonNull
(
tail
))
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/message/MessageKey.kt
0 → 100644
View file @
38e3f133
package
net.mamoe.mirai.message
/**
* @author Him188moe
*/
open
class
MessageKey
(
val
intValue
:
Int
)
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/At.kt
View file @
38e3f133
...
...
@@ -2,7 +2,7 @@ package net.mamoe.mirai.message.defaults
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.Message
Id
import
net.mamoe.mirai.message.Message
Key
/**
* At 一个人
...
...
@@ -10,7 +10,9 @@ import net.mamoe.mirai.message.MessageId
* @author Him188moe
*/
class
At
(
val
target
:
Long
)
:
Message
()
{
override
val
type
:
Int
=
MessageId
.
AT
companion
object
Key
:
MessageKey
(
0
x06
)
override
val
type
:
MessageKey
=
Key
constructor
(
target
:
QQ
)
:
this
(
target
.
number
)
...
...
@@ -20,7 +22,9 @@ class At(val target: Long) : Message() {
TODO
()
}
override
fun
valueEquals
(
another
:
Message
):
Boolean
{
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
false
override
fun
eq
(
another
:
Message
):
Boolean
{
if
(
another
!
is
At
)
{
return
false
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Face.kt
View file @
38e3f133
...
...
@@ -2,7 +2,7 @@ package net.mamoe.mirai.message.defaults
import
net.mamoe.mirai.message.FaceID
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.Message
Id
import
net.mamoe.mirai.message.Message
Key
import
net.mamoe.mirai.network.packet.readLVNumber
import
net.mamoe.mirai.network.packet.writeHex
import
net.mamoe.mirai.network.packet.writeLVByteArray
...
...
@@ -15,14 +15,16 @@ import net.mamoe.mirai.utils.lazyEncode
* @author Him188moe
*/
class
Face
(
val
id
:
FaceID
)
:
Message
()
{
override
val
type
:
Int
=
MessageId
.
FACE
companion
object
Key
:
MessageKey
(
0
x02
)
override
val
type
:
MessageKey
=
Key
override
fun
toStringImpl
():
String
{
return
String
.
format
(
"[face%d]"
,
id
.
id
)
}
override
fun
toByteArray
():
ByteArray
=
lazyEncode
{
section
->
section
.
writeByte
(
this
.
type
)
section
.
writeByte
(
this
.
type
.
intValue
)
section
.
writeLVByteArray
(
lazyEncode
{
child
->
child
.
writeShort
(
1
)
...
...
@@ -37,14 +39,16 @@ class Face(val id: FaceID) : Message() {
}
override
fun
valueEquals
(
another
:
Message
):
Boolean
{
override
fun
eq
(
another
:
Message
):
Boolean
{
if
(
another
!
is
Face
)
{
return
false
}
return
this
.
id
==
another
.
id
}
companion
object
{
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
false
internal
object
PacketHelper
{
fun
ofByteArray
(
data
:
ByteArray
):
Face
=
lazyDecode
(
data
)
{
//00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0
//00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D
...
...
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.kt
View file @
38e3f133
...
...
@@ -2,6 +2,7 @@ package net.mamoe.mirai.message.defaults
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.MessageId
import
net.mamoe.mirai.message.MessageKey
import
net.mamoe.mirai.network.packet.*
import
net.mamoe.mirai.utils.lazyDecode
import
net.mamoe.mirai.utils.lazyEncode
...
...
@@ -16,8 +17,10 @@ import net.mamoe.mirai.utils.toUHexString
*
* @author Him188moe
*/
open
class
Image
internal
constructor
(
val
imageId
:
String
)
:
Message
()
{
override
val
type
:
Int
=
MessageId
.
IMAGE
open
class
Image
(
val
imageId
:
String
)
:
Message
()
{
companion
object
Key
:
MessageKey
(
0
x03
)
override
val
type
:
MessageKey
=
Key
override
fun
toStringImpl
():
String
{
return
imageId
...
...
@@ -43,7 +46,7 @@ open class Image internal constructor(val imageId: String) : Message() {
})
}
override
fun
valueEquals
(
another
:
Message
):
Boolean
{
override
fun
eq
(
another
:
Message
):
Boolean
{
if
(
another
is
Image
)
{
return
this
.
imageId
==
another
.
imageId
}
...
...
@@ -51,7 +54,9 @@ open class Image internal constructor(val imageId: String) : Message() {
return
false
}
companion
object
{
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
false
//No string can be contained in a image
internal
object
PacketHelper
{
@JvmStatic
fun
ofByteArray0x06
(
data
:
ByteArray
):
Image
=
lazyDecode
(
data
)
{
it
.
skip
(
1
)
...
...
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/MessageChain.kt
View file @
38e3f133
package
net.mamoe.mirai.message.defaults
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.Message
Id
import
net.mamoe.mirai.message.Message
Key
import
net.mamoe.mirai.utils.lazyEncode
import
org.intellij.lang.annotations.MagicConstant
import
java.util.*
import
java.util.stream.Collectors
import
java.util.stream.Stream
import
kotlin.reflect.KClass
class
MessageChain
:
Message
{
override
val
type
:
Int
=
MessageId
.
CHAIN
companion
object
Key
:
MessageKey
(
0
xff
)
//only used to compare
override
val
type
:
MessageKey
=
Key
/**
* Elements will not be instances of [MessageChain]
*/
val
list
:
MutableList
<
Message
>
=
Collections
.
synchronizedList
(
LinkedList
<
Message
>())
constructor
(
head
:
Message
,
tail
:
Message
)
{
...
...
@@ -32,18 +37,19 @@ class MessageChain : Message {
constructor
()
/**
* 获取第一个这个类型的消息
*/
operator
fun
get
(
type
:
MessageKey
):
Message
?
=
list
.
firstOrNull
{
it
.
type
==
type
}
fun
size
():
Int
{
return
list
.
size
}
fun
containsType
(
@MagicConstant
(
valuesFromClass
=
MessageId
::
class
)
type
:
Int
):
Boolean
{
for
(
message
in
list
)
{
if
(
message
.
type
==
type
)
{
return
true
}
}
return
false
}
fun
containsType
(
clazz
:
KClass
<
out
Message
>):
Boolean
=
list
.
any
{
clazz
.
isInstance
(
it
)
}
fun
containsType
(
clazz
:
Class
<
out
Message
>):
Boolean
=
list
.
any
{
clazz
.
isInstance
(
it
)
}
operator
fun
contains
(
sub
:
KClass
<
out
Message
>):
Boolean
=
containsType
(
sub
)
operator
fun
contains
(
sub
:
Class
<
out
Message
>):
Boolean
=
containsType
(
sub
)
fun
stream
():
Stream
<
Message
>
{
return
list
.
stream
()
...
...
@@ -58,6 +64,10 @@ class MessageChain : Message {
}
override
fun
concat
(
tail
:
Message
):
MessageChain
{
if
(
tail
is
MessageChain
)
{
tail
.
list
.
forEach
{
child
->
this
.
concat
(
child
)
}
return
this
}
this
.
list
.
add
(
tail
)
clearToStringCache
()
return
this
...
...
@@ -73,10 +83,16 @@ class MessageChain : Message {
}
}
override
fun
valueEquals
(
another
:
Message
):
Boolean
{
override
fun
eq
(
another
:
Message
):
Boolean
{
if
(
another
!
is
MessageChain
)
{
return
false
}
return
this
.
list
==
another
.
list
}
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
list
.
any
{
it
.
contains
(
sub
)
}
operator
fun
component1
():
Message
=
this
.
list
[
0
]
operator
fun
component2
():
Message
=
this
.
list
[
1
]
operator
fun
component3
():
Message
=
this
.
list
[
2
]
}
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/PlainText.kt
View file @
38e3f133
package
net.mamoe.mirai.message.defaults
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.Message
Id
import
net.mamoe.mirai.message.Message
Key
import
net.mamoe.mirai.network.packet.readLVString
import
net.mamoe.mirai.network.packet.writeLVByteArray
import
net.mamoe.mirai.network.packet.writeLVString
...
...
@@ -12,14 +12,16 @@ import net.mamoe.mirai.utils.lazyEncode
* @author Him188moe
*/
class
PlainText
(
private
val
text
:
String
)
:
Message
()
{
override
val
type
:
Int
=
MessageId
.
TEXT
companion
object
Key
:
MessageKey
(
0
x01
)
override
val
type
:
MessageKey
=
Key
override
fun
toStringImpl
():
String
{
return
text
}
override
fun
toByteArray
():
ByteArray
=
lazyEncode
{
section
->
section
.
writeByte
(
this
.
type
)
section
.
writeByte
(
this
.
type
.
intValue
)
section
.
writeLVByteArray
(
lazyEncode
{
child
->
child
.
writeByte
(
0
x01
)
...
...
@@ -27,14 +29,16 @@ class PlainText(private val text: String) : Message() {
})
}
override
fun
valueEquals
(
another
:
Message
):
Boolean
{
override
fun
eq
(
another
:
Message
):
Boolean
{
if
(
another
!
is
PlainText
)
{
return
false
}
return
this
.
text
==
another
.
text
}
companion
object
{
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
this
.
toString
().
contains
(
sub
)
internal
object
PacketHelper
{
fun
ofByteArray
(
data
:
ByteArray
):
PlainText
=
lazyDecode
(
data
)
{
it
.
skip
(
1
)
PlainText
(
it
.
readLVString
())
...
...
mirai-core/src/main/java/net/mamoe/mirai/message/defaults/UnsolvedImage.kt
View file @
38e3f133
...
...
@@ -19,13 +19,13 @@ import javax.imageio.ImageIO
/**
* 不确定是否存在于服务器的 [Image].
* 必须在发送之前 [UnsolvedImage.upload] 或 [Contact.uploadImage], 否则会发送失败.
x *
*
* @suppress todo 重新设计
* @author Him188moe
*/
class
UnsolvedImage
(
filename
:
String
,
val
image
:
BufferedImage
)
:
Image
(
getImageId
(
filename
))
{
constructor
(
imageFile
:
File
)
:
this
(
imageFile
.
name
,
ImageIO
.
read
(
imageFile
))
constructor
(
url
:
URL
)
:
this
(
File
(
url
.
file
))
fun
upload
(
session
:
LoginSession
,
contact
:
Contact
):
CompletableFuture
<
Unit
>
{
return
session
.
expectPacket
<
ServerTryGetImageIDResponsePacket
>
{
toSend
{
ClientTryGetImageIDPacket
(
session
.
bot
.
account
.
qqNumber
,
session
.
sessionKey
,
contact
.
number
,
image
)
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandlerImpl.kt
View file @
38e3f133
This diff is collapsed.
Click to expand it.
mirai-core/src/main/java/net/mamoe/mirai/network/NetworkScope.kt
0 → 100644
View file @
38e3f133
package
net.mamoe.mirai.network
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
object
NetworkScope
:
CoroutineScope
by
CoroutineScope
(
Dispatchers
.
Default
)
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/network/handler/ActionPacketHandler.kt
View file @
38e3f133
package
net.mamoe.mirai.network.handler
import
kotlinx.coroutines.runBlocking
import
net.mamoe.mirai.network.LoginSession
import
net.mamoe.mirai.network.packet.*
import
net.mamoe.mirai.network.packet.action.AddFriendResult
...
...
@@ -32,7 +33,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
private
var
sKeyRefresherFuture
:
ScheduledFuture
<
*
>?
=
null
override
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
override
suspend
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
when
(
packet
)
{
is
ServerCanAddFriendResponsePacket
->
{
this
.
uploadImageSessions
.
forEach
{
...
...
@@ -60,7 +61,9 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
session
.
cookies
=
"uin=o"
+
session
.
bot
.
account
.
qqNumber
+
";skey="
+
session
.
sKey
+
";"
sKeyRefresherFuture
=
MiraiThreadPool
.
getInstance
().
scheduleWithFixedDelay
({
session
.
socket
.
sendPacket
(
ClientSKeyRefreshmentRequestPacket
(
session
.
bot
.
account
.
qqNumber
,
session
.
sessionKey
))
runBlocking
{
session
.
socket
.
sendPacket
(
ClientSKeyRefreshmentRequestPacket
(
session
.
bot
.
account
.
qqNumber
,
session
.
sessionKey
))
}
},
1800000
,
1800000
,
TimeUnit
.
MILLISECONDS
)
session
.
gtk
=
getGTK
(
session
.
sKey
)
...
...
@@ -75,13 +78,13 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
}
fun
addFriend
(
qqNumber
:
Long
,
message
:
Supplier
<
String
>)
{
suspend
fun
addFriend
(
qqNumber
:
Long
,
message
:
Supplier
<
String
>)
{
addFriend
(
qqNumber
,
lazy
{
message
.
get
()
})
}
@JvmSynthetic
fun
addFriend
(
qqNumber
:
Long
,
message
:
Lazy
<
String
>
=
lazyOf
(
""
)):
CompletableFuture
<
AddFriendResult
>
{
suspend
fun
addFriend
(
qqNumber
:
Long
,
message
:
Lazy
<
String
>
=
lazyOf
(
""
)):
CompletableFuture
<
AddFriendResult
>
{
val
future
=
CompletableFuture
<
AddFriendResult
>()
val
session
=
AddFriendSession
(
qqNumber
,
future
,
message
)
// uploadImageSessions.add(session)
...
...
@@ -90,12 +93,12 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
}
fun
requestSKey
()
{
suspend
fun
requestSKey
()
{
session
.
socket
.
sendPacket
(
ClientSKeyRequestPacket
(
session
.
bot
.
account
.
qqNumber
,
session
.
sessionKey
))
}
fun
requestAccountInfo
()
{
suspend
fun
requestAccountInfo
()
{
session
.
socket
.
sendPacket
(
ClientAccountInfoRequestPacket
(
session
.
bot
.
account
.
qqNumber
,
session
.
sessionKey
))
}
...
...
@@ -165,7 +168,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
lateinit
var
id
:
ByteArray
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
suspend
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
if
(!
::
id
.
isInitialized
)
{
return
}
...
...
@@ -202,7 +205,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
}
fun
sendAddRequest
()
{
suspend
fun
sendAddRequest
()
{
session
.
socket
.
sendPacket
(
ClientCanAddFriendPacket
(
session
.
bot
.
account
.
qqNumber
,
qq
,
session
.
sessionKey
).
also
{
this
.
id
=
it
.
packetIdLast
})
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/handler/DataPacketSocket.kt
View file @
38e3f133
...
...
@@ -6,9 +6,7 @@ import net.mamoe.mirai.network.BotNetworkHandlerImpl
import
net.mamoe.mirai.network.LoginSession
import
net.mamoe.mirai.network.packet.ClientPacket
import
net.mamoe.mirai.network.packet.ServerPacket
import
net.mamoe.mirai.task.MiraiThreadPool
import
java.io.Closeable
import
java.util.concurrent.Future
/**
* 网络接口.
...
...
@@ -23,7 +21,7 @@ interface DataPacketSocket : Closeable {
/**
* 分发数据包给 [PacketHandler]
*/
fun
distributePacket
(
packet
:
ServerPacket
)
suspend
fun
distributePacket
(
packet
:
ServerPacket
)
/**
* 发送一个数据包(非异步).
...
...
@@ -32,20 +30,7 @@ interface DataPacketSocket : Closeable {
*
* @see [LoginSession.expectPacket] kotlin DSL
*/
fun
sendPacket
(
packet
:
ClientPacket
)
/**
* 发送一个数据包(异步).
*
* 可通过 hook 事件 [ServerPacketReceivedEvent] 来获取服务器返回.
*
* @see [LoginSession.expectPacket] kotlin DSL
*/
fun
sendPacketAsync
(
packet
:
ClientPacket
):
Future
<
*
>
{
return
MiraiThreadPool
.
getInstance
().
submit
{
sendPacket
(
packet
)
}
}
suspend
fun
sendPacket
(
packet
:
ClientPacket
)
fun
isClosed
():
Boolean
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/handler/MessagePacketHandler.kt
View file @
38e3f133
...
...
@@ -4,10 +4,7 @@ import net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.event.events.group.GroupMessageEvent
import
net.mamoe.mirai.event.events.qq.FriendMessageEvent
import
net.mamoe.mirai.event.hookWhile
import
net.mamoe.mirai.message.defaults.Image
import
net.mamoe.mirai.message.defaults.MessageChain
import
net.mamoe.mirai.message.defaults.PlainText
import
net.mamoe.mirai.network.LoginSession
import
net.mamoe.mirai.network.packet.ServerFriendMessageEventPacket
import
net.mamoe.mirai.network.packet.ServerGroupMessageEventPacket
...
...
@@ -27,49 +24,7 @@ import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacke
class
MessagePacketHandler
(
session
:
LoginSession
)
:
PacketHandler
(
session
)
{
internal
var
ignoreMessage
:
Boolean
=
true
init
{
//todo for test
FriendMessageEvent
::
class
.
hookWhile
{
if
(
session
.
socket
.
isClosed
())
{
return
@
hookWhile
false
}
when
{
it
.
message
valueEquals
"你好"
->
it
.
sender
.
sendMessage
(
"你好!"
)
it
.
message
.
toString
().
startsWith
(
"复读"
)
->
it
.
sender
.
sendMessage
(
it
.
message
())
it
.
message
.
toString
().
startsWith
(
"发群"
)
->
{
it
.
message
().
list
.
toMutableList
().
let
{
messages
->
messages
.
removeAt
(
0
)
sendGroupMessage
(
Group
(
session
.
bot
,
580266363
),
MessageChain
(
messages
))
}
}
/*it.message valueEquals "发图片群" -> sendGroupMessage(Group(session.bot, 580266363), PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
image.upload(session, Group(session.bot, 580266363)).get()
})*/
it
.
message
valueEquals
"发图片群2"
->
sendGroupMessage
(
Group
(
session
.
bot
,
580266363
),
Image
(
"{7AA4B3AA-8C3C-0F45-2D9B-7F302A0ACEAA}.jpg"
).
toChain
())
/* it.message valueEquals "发图片" -> sendFriendMessage(it.sender, PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
image.upload(session, it.sender).get()
})*/
it
.
message
valueEquals
"发图片2"
->
sendFriendMessage
(
it
.
sender
,
PlainText
(
"test"
)
+
Image
(
"{7AA4B3AA-8C3C-0F45-2D9B-7F302A0ACEAA}.jpg"
))
}
return
@
hookWhile
true
}
GroupMessageEvent
::
class
.
hookWhile
{
if
(
session
.
socket
.
isClosed
())
{
return
@
hookWhile
false
}
when
{
it
.
message
.
contains
(
"复读"
)
->
it
.
group
.
sendMessage
(
it
.
chain
)
}
return
@
hookWhile
true
}
}
override
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
override
suspend
fun
onPacketReceived
(
packet
:
ServerPacket
)
{
when
(
packet
)
{
is
ServerGroupUploadFileEventPacket
->
{
//todo
...
...
@@ -99,11 +54,11 @@ class MessagePacketHandler(session: LoginSession) : PacketHandler(session) {
}
}
fun
sendFriendMessage
(
qq
:
QQ
,
message
:
MessageChain
)
{
session
.
socket
.
sendPacket
Async
(
ClientSendFriendMessagePacket
(
session
.
bot
.
account
.
qqNumber
,
qq
.
number
,
session
.
sessionKey
,
message
))
suspend
fun
sendFriendMessage
(
qq
:
QQ
,
message
:
MessageChain
)
{
session
.
socket
.
sendPacket
(
ClientSendFriendMessagePacket
(
session
.
bot
.
account
.
qqNumber
,
qq
.
number
,
session
.
sessionKey
,
message
))
}
fun
sendGroupMessage
(
group
:
Group
,
message
:
MessageChain
)
{
suspend
fun
sendGroupMessage
(
group
:
Group
,
message
:
MessageChain
)
{
session
.
socket
.
sendPacket
(
ClientSendGroupMessagePacket
(
session
.
bot
.
account
.
qqNumber
,
group
.
groupId
,
session
.
sessionKey
,
message
))
}
}
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/network/handler/PacketHandler.kt
View file @
38e3f133
...
...
@@ -11,7 +11,7 @@ import java.io.Closeable
abstract
class
PacketHandler
(
val
session
:
LoginSession
)
:
Closeable
{
abstract
fun
onPacketReceived
(
packet
:
ServerPacket
)
abstract
suspend
fun
onPacketReceived
(
packet
:
ServerPacket
)
override
fun
close
()
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/handler/TemporaryPacketHandler.kt
View file @
38e3f133
...
...
@@ -32,7 +32,7 @@ open class TemporaryPacketHandler<P : ServerPacket>(
this
.
expect
=
handler
}
fun
send
(
session
:
LoginSession
)
{
suspend
fun
send
(
session
:
LoginSession
)
{
this
.
session
=
session
session
.
socket
.
sendPacket
(
toSend
)
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
View file @
38e3f133
...
...
@@ -144,12 +144,6 @@ fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, lo
}
}
fun
main
()
{
println
(
lazyEncode
{
it
.
writeTLV0006
(
1040400290
,
"asdHim188moe"
,
System
.
currentTimeMillis
().
toInt
(),
"123.123.123.123"
,
getRandomByteArray
(
56
))
}.
size
)
}
@Tested
fun
DataOutputStream
.
writeCRC32
()
=
writeCRC32
(
getRandomByteArray
(
16
))
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt
View file @
38e3f133
...
...
@@ -263,10 +263,10 @@ private fun DataInputStream.readSection(): Message? {
val
sectionLength
=
this
.
readShort
().
toLong
()
//sectionLength: short
val
sectionData
=
this
.
readNBytes
(
sectionLength
)
return
when
(
messageType
)
{
0
x01
->
PlainText
.
ofByteArray
(
sectionData
)
0
x02
->
Face
.
ofByteArray
(
sectionData
)
0
x03
->
Image
.
ofByteArray0x03
(
sectionData
)
0
x06
->
Image
.
ofByteArray0x06
(
sectionData
)
0
x01
->
PlainText
.
PacketHelper
.
ofByteArray
(
sectionData
)
0
x02
->
Face
.
PacketHelper
.
ofByteArray
(
sectionData
)
0
x03
->
Image
.
PacketHelper
.
ofByteArray0x03
(
sectionData
)
0
x06
->
Image
.
PacketHelper
.
ofByteArray0x06
(
sectionData
)
0
x19
->
{
//长文本
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt
View file @
38e3f133
...
...
@@ -111,7 +111,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
"00 58"
->
ServerHeartbeatResponsePacket
(
stream
)
"00 BA"
->
Server
VerificationCode
Packet
.
Encrypted
(
stream
,
idHex
)
"00 BA"
->
Server
Catcha
Packet
.
Encrypted
(
stream
,
idHex
)
"00 CE"
,
"00 17"
->
ServerEventPacket
.
Raw
.
Encrypted
(
stream
,
idHex
.
hexToBytes
())
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt
View file @
38e3f133
...
...
@@ -126,7 +126,7 @@ class ClientVerificationCodeRefreshPacket(
* 验证码输入错误, 同时也会给一部分验证码
*/
@PacketId
(
"00 BA 32"
)
class
Server
VerificationCodeWrongPacket
(
input
:
DataInputStream
,
dataSize
:
Int
,
packetId
:
ByteArray
)
:
ServerVerificationCode
TransmissionPacket
(
input
,
dataSize
,
packetId
)
class
Server
CaptchaWrongPacket
(
input
:
DataInputStream
,
dataSize
:
Int
,
packetId
:
ByteArray
)
:
ServerCaptcha
TransmissionPacket
(
input
,
dataSize
,
packetId
)
/**
* 服务器发送验证码图片文件一部分过来
...
...
@@ -134,7 +134,7 @@ class ServerVerificationCodeWrongPacket(input: DataInputStream, dataSize: Int, p
* @author Him188moe
*/
@PacketId
(
"00 BA 31"
)
open
class
Server
VerificationCodeTransmissionPacket
(
input
:
DataInputStream
,
private
val
dataSize
:
Int
,
private
val
packetId
:
ByteArray
)
:
ServerVerificationCode
Packet
(
input
)
{
open
class
Server
CaptchaTransmissionPacket
(
input
:
DataInputStream
,
private
val
dataSize
:
Int
,
private
val
packetId
:
ByteArray
)
:
ServerCatcha
Packet
(
input
)
{
lateinit
var
captchaSectionN
:
ByteArray
lateinit
var
verificationToken
:
ByteArray
//56bytes
...
...
@@ -177,7 +177,7 @@ fun main() {
* @author Him188moe
*/
@PacketId
(
"00 BA 32"
)
class
Server
VerificationCodeCorrectPacket
(
input
:
DataInputStream
)
:
ServerVerificationCode
Packet
(
input
)
{
class
Server
CaptchaCorrectPacket
(
input
:
DataInputStream
)
:
ServerCatcha
Packet
(
input
)
{
lateinit
var
token00BA
:
ByteArray
//56 bytes
...
...
@@ -187,24 +187,24 @@ class ServerVerificationCodeCorrectPacket(input: DataInputStream) : ServerVerifi
}
}
abstract
class
Server
VerificationCode
Packet
(
input
:
DataInputStream
)
:
ServerPacket
(
input
)
{
abstract
class
Server
Catcha
Packet
(
input
:
DataInputStream
)
:
ServerPacket
(
input
)
{
@PacketId
(
"00 BA"
)
class
Encrypted
(
input
:
DataInputStream
,
private
val
id
:
String
)
:
ServerPacket
(
input
)
{
fun
decrypt
():
Server
VerificationCode
Packet
{
fun
decrypt
():
Server
Catcha
Packet
{
this
.
input
goto
14
val
data
=
TEA
.
decrypt
(
this
.
input
.
readAllBytes
().
cutTail
(
1
),
Protocol
.
key00BA
.
hexToBytes
())
if
(
id
.
startsWith
(
"00 BA 32"
))
{
return
when
(
data
.
size
)
{
66
,
95
->
Server
VerificationCode
CorrectPacket
(
data
.
dataInputStream
())
95
->
Server
Captcha
CorrectPacket
(
data
.
dataInputStream
())
//66 -> ServerVerificationCodeUnknownPacket(data.dataInputStream())
else
->
return
Server
VerificationCode
WrongPacket
(
data
.
dataInputStream
(),
data
.
size
,
this
.
input
.
readNBytesAt
(
3
,
4
))
else
->
return
Server
Captcha
WrongPacket
(
data
.
dataInputStream
(),
data
.
size
,
this
.
input
.
readNBytesAt
(
3
,
4
))
}.
setId
(
this
.
idHex
)
}
return
Server
VerificationCode
TransmissionPacket
(
data
.
dataInputStream
(),
data
.
size
,
this
.
input
.
readNBytesAt
(
3
,
4
)).
setId
(
this
.
idHex
)
return
Server
Captcha
TransmissionPacket
(
data
.
dataInputStream
(),
data
.
size
,
this
.
input
.
readNBytesAt
(
3
,
4
)).
setId
(
this
.
idHex
)
}
override
fun
getFixedId
():
String
=
this
.
getFixedId
(
id
)
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/BotAccount.java
deleted
100644 → 0
View file @
615de9ef
package
net.mamoe.mirai.utils
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
@Data
@AllArgsConstructor
public
class
BotAccount
{
public
final
long
qqNumber
;
private
final
String
password
;
}
mirai-core/src/main/java/net/mamoe/mirai/utils/BotAccount.kt
0 → 100644
View file @
38e3f133
package
net.mamoe.mirai.utils
/**
* @author Him188moe
*/
data class
BotAccount
(
val
qqNumber
:
Long
,
val
password
:
String
)
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfig.java
View file @
38e3f133
package
net.mamoe.mirai.utils.config
;
import
kotlin.io.FilesKt
;
import
net.mamoe.mirai.MiraiServer
;
import
org.jetbrains.annotations.NotNull
;
import
org.yaml.snakeyaml.DumperOptions
;
import
org.yaml.snakeyaml.Yaml
;
...
...
@@ -24,10 +23,6 @@ public class MiraiConfig extends MiraiConfigSection<Object> {
private
final
File
root
;
public
MiraiConfig
(
@NotNull
String
configName
)
{
this
(
new
File
(
MiraiServer
.
getInstance
().
getParentFolder
(),
Objects
.
requireNonNull
(
configName
)));
}
public
MiraiConfig
(
@NotNull
File
file
)
{
super
(
parse
(
Objects
.
requireNonNull
(
file
)));
this
.
root
=
file
;
...
...
@@ -47,9 +42,10 @@ public class MiraiConfig extends MiraiConfigSection<Object> {
@SuppressWarnings
(
"unchecked"
)
private
static
LinkedHashMap
<
String
,
Object
>
parse
(
File
file
)
{
/*
if (!file.toURI().getPath().contains(MiraiServer.getInstance().getParentFolder().getPath())) {
file = new File(MiraiServer.getInstance().getParentFolder().getPath(), file.getName());
}
}
*/
if
(!
file
.
exists
())
{
try
{
if
(!
file
.
createNewFile
())
{
...
...
mirai-core/src/test/java/BadQQFilter.kt
View file @
38e3f133
...
...
@@ -74,7 +74,7 @@ fun main() {
return
@
let
password
.
substring
(
0
,
password
.
length
-
1
)
}
return
@
let
password
})
,
listOf
()
)
}))
bot
.
network
.
tryLogin
().
whenComplete
{
state
,
_
->
if
(!(
state
==
LoginState
.
BLOCKED
||
state
==
LoginState
.
DEVICE_LOCK
||
state
==
LoginState
.
WRONG_PASSWORD
))
{
...
...
mirai-core/src/test/java/ConfigTest.java
deleted
100644 → 0
View file @
615de9ef
import
net.mamoe.mirai.MiraiServer
;
import
net.mamoe.mirai.utils.config.MiraiConfig
;
public
class
ConfigTest
{
public
static
void
main
(
String
[]
args
){
MiraiConfig
config
=
new
MiraiConfig
(
"QQ.yml"
);
}
}
mirai-core/src/test/java/PacketDebuger.kt
View file @
38e3f133
...
...
@@ -40,7 +40,7 @@ object Main {
println("-------------------------------------------")
exitProcess(0)*/
va
r
jpcap
:
JpcapCaptor
?
=
null
va
l
jpcap
:
JpcapCaptor
?
val
caplen
=
4096
val
promiscCheck
=
true
...
...
mirai-demos/mirai-demo-1/pom.xml
0 → 100644
View file @
38e3f133
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
net.mamoe
</groupId>
<artifactId>
mirai-demos
</artifactId>
<version>
1.0
</version>
</parent>
<artifactId>
mirai-demo-1
</artifactId>
<version>
1.0
</version>
<build>
<resources>
<resource>
<directory>
/src/main/resources
</directory>
<includes>
<include>
**/*.*
</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>
org.jetbrains.kotlin
</groupId>
<artifactId>
kotlin-maven-plugin
</artifactId>
<executions>
<execution>
<id>
compile
</id>
<phase>
compile
</phase>
<goals>
<goal>
compile
</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>
org.jetbrains.kotlinx
</groupId>
<artifactId>
kotlinx-coroutines-core
</artifactId>
</dependency>
<dependency>
<groupId>
org.jetbrains.kotlin
</groupId>
<artifactId>
kotlin-stdlib
</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt
0 → 100644
View file @
38e3f133
package
demo1
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.event.events.group.GroupMessageEvent
import
net.mamoe.mirai.event.events.qq.FriendMessageEvent
import
net.mamoe.mirai.event.hookAlways
import
net.mamoe.mirai.message.defaults.Image
import
net.mamoe.mirai.message.defaults.PlainText
import
net.mamoe.mirai.network.packet.login.LoginState
import
net.mamoe.mirai.utils.BotAccount
/**
* @author Him188moe
*/
fun
main
()
{
val
bot
=
Bot
(
BotAccount
(
qqNumber
=
1683921395
,
password
=
"bb22222"
))
bot
.
network
.
tryLogin
().
get
().
let
{
check
(
it
==
LoginState
.
SUCCESS
)
{
"Login failed: "
+
it
.
name
}
}
//监听事件:
FriendMessageEvent
::
class
.
hookAlways
{
//获取第一个纯文本消息
val
firstText
=
it
.
message
[
PlainText
]
//获取第一个图片
val
firstImage
=
it
.
message
[
Image
]
when
{
it
.
message
eq
"你好"
->
it
.
reply
(
"你好!"
)
"复读"
in
it
.
message
->
it
.
sender
.
sendMessage
(
it
.
message
)
"发群"
in
it
.
message
->
{
it
.
message
.
list
.
toMutableList
().
let
{
messages
->
messages
.
removeAt
(
0
)
Group
(
bot
,
580266363
).
sendMessage
(
messages
)
}
}
/*it.message eq "发图片群" -> sendGroupMessage(Group(session.bot, 580266363), PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
image.upload(session, Group(session.bot, 580266363)).get()
})*/
it
.
message
eq
"发图片群2"
->
Group
(
bot
,
580266363
).
sendMessage
(
Image
(
"{7AA4B3AA-8C3C-0F45-2D9B-7F302A0ACEAA}.jpg"
))
/* it.message eq "发图片" -> sendFriendMessage(it.sender, PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
image.upload(session, it.sender).get()
})*/
it
.
message
eq
"发图片2"
->
it
.
reply
(
PlainText
(
"test"
)
+
Image
(
"{7AA4B3AA-8C3C-0F45-2D9B-7F302A0ACEAA}.jpg"
))
}
}
GroupMessageEvent
::
class
.
hookAlways
{
when
{
it
.
message
.
contains
(
"复读"
)
->
it
.
reply
(
it
.
message
)
}
}
}
\ No newline at end of file
mirai-demos/pom.xml
0 → 100644
View file @
38e3f133
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
net.mamoe
</groupId>
<artifactId>
mirai
</artifactId>
<version>
1.0
</version>
</parent>
<artifactId>
mirai-demos
</artifactId>
<version>
1.0
</version>
<modules>
<module>
mirai-demo-1
</module>
</modules>
<dependencies>
<dependency>
<groupId>
net.mamoe
</groupId>
<artifactId>
mirai-core
</artifactId>
<version>
1.0
</version>
<scope>
compile
</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
pom.xml
View file @
38e3f133
...
...
@@ -14,6 +14,7 @@
<module>
mirai-ui
</module>
<module>
mirai-console
</module>
<module>
mirai-api
</module>
<module>
mirai-demos
</module>
</modules>
<repositories>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment