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
ece200d4
Commit
ece200d4
authored
Sep 10, 2019
by
Him188moe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated docs, migrated TEA encryption from java to kotlin, fixed bugs
parent
87532418
Changes
34
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
384 additions
and
324 deletions
+384
-324
mirai-core/src/main/java/net/mamoe/mirai/Bot.java
mirai-core/src/main/java/net/mamoe/mirai/Bot.java
+13
-5
mirai-core/src/main/java/net/mamoe/mirai/MiraiMain.java
mirai-core/src/main/java/net/mamoe/mirai/MiraiMain.java
+1
-5
mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt
mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt
+4
-1
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
+6
-1
mirai-core/src/main/java/net/mamoe/mirai/event/events/bot/BotEvent.java
.../main/java/net/mamoe/mirai/event/events/bot/BotEvent.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/event/events/bot/BotEvents.kt
...c/main/java/net/mamoe/mirai/event/events/bot/BotEvents.kt
+0
-18
mirai-core/src/main/java/net/mamoe/mirai/event/events/bot/BotLoginSucceedEvent.java
...et/mamoe/mirai/event/events/bot/BotLoginSucceedEvent.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
.../main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
+2
-2
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
.../main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
+0
-8
mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
...ore/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
+10
-14
mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/AddFriendResult.kt
.../net/mamoe/mirai/network/packet/action/AddFriendResult.kt
+2
-0
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt
...et/login/ServerLoginResponseVerificationCodeInitPacket.kt
+3
-3
mirai-core/src/main/java/net/mamoe/mirai/plugin/MiraiPluginBase.java
...src/main/java/net/mamoe/mirai/plugin/MiraiPluginBase.java
+2
-0
mirai-core/src/main/java/net/mamoe/mirai/plugin/MiraiPluginManager.java
.../main/java/net/mamoe/mirai/plugin/MiraiPluginManager.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskExceptionHandler.java
.../java/net/mamoe/mirai/task/MiraiTaskExceptionHandler.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java
.../src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/task/MiraiThreadPool.java
...e/src/main/java/net/mamoe/mirai/task/MiraiThreadPool.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/BotAccount.java
...-core/src/main/java/net/mamoe/mirai/utils/BotAccount.java
+0
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/CharImageUtil.java
...re/src/main/java/net/mamoe/mirai/utils/CharImageUtil.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/ClientLoginStatus.java
...rc/main/java/net/mamoe/mirai/utils/ClientLoginStatus.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/EventException.java
...e/src/main/java/net/mamoe/mirai/utils/EventException.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/LoggerTextFormat.java
...src/main/java/net/mamoe/mirai/utils/LoggerTextFormat.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/MiraiLogger.kt
...i-core/src/main/java/net/mamoe/mirai/utils/MiraiLogger.kt
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
+0
-263
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.kt
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.kt
+277
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/Tested.kt
mirai-core/src/main/java/net/mamoe/mirai/utils/Tested.kt
+3
-1
mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
+6
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfigSection.java
...java/net/mamoe/mirai/utils/config/MiraiConfigSection.java
+4
-1
mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiSynchronizedLinkedListMap.java
...oe/mirai/utils/config/MiraiSynchronizedLinkedListMap.java
+4
-2
mirai-core/src/main/java/net/mamoe/mirai/utils/setting/MiraiSettingListSection.java
...et/mamoe/mirai/utils/setting/MiraiSettingListSection.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/setting/MiraiSettingMapSection.java
...net/mamoe/mirai/utils/setting/MiraiSettingMapSection.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/setting/MiraiSettingSection.java
...va/net/mamoe/mirai/utils/setting/MiraiSettingSection.java
+3
-0
mirai-core/src/main/java/net/mamoe/mirai/utils/setting/MiraiSettings.java
...ain/java/net/mamoe/mirai/utils/setting/MiraiSettings.java
+2
-0
No files found.
mirai-core/src/main/java/net/mamoe/mirai/Bot.java
View file @
ece200d4
...
...
@@ -17,20 +17,28 @@ import java.util.concurrent.atomic.AtomicInteger;
* Mirai 的机器人. 一个机器人实例登录一个 QQ 账号.
* Mirai 为多账号设计, 可同时维护多个机器人.
* <br>
* {@link Bot} 由
2
个模块组成.
* {@link Bot} 由
3
个模块组成.
* {@linkplain ContactSystem 联系人管理}: 可通过 {@link Bot#contacts} 访问
* {@linkplain BotNetworkHandler 网络处理器}: 可通过 {@link Bot#network} 访问
* {@linkplain BotAccount 机器人账号信息}: 可通过 {@link Bot#account} 访问
* <br>
* 若你需要得到机器人的 QQ 账号, 请访问 {@link Bot#account}
* 若你需要得到服务器上所有机器人列表, 请访问 {@link Bot#instances}
*
* <p>
* Bot that is the base of the whole program.
* It consists of
* a {@link ContactSystem}, which manage contacts such as {@link QQ} and {@link Group};
* a {@link BotNetworkHandler}, which manages the connection to the server;
* a {@link BotAccount}, which stores the account information(e.g. qq number the bot)
* <br>
* To get all the QQ contacts, access {@link Bot#account}
* To get all the Robot instance, access {@link Bot#instances}
* </p>
*
* @author Him188moe
* @author NatrualHG
* @see net.mamoe.mirai.contact.Contact
*
* <p>
* Bot that is the base of the whole program.
* It contains a {@link ContactSystem}, which manage contacts such as {@link QQ} and {@link Group}.
*/
public
final
class
Bot
implements
Closeable
{
public
static
final
List
<
Bot
>
instances
=
Collections
.
synchronizedList
(
new
LinkedList
<>());
...
...
mirai-core/src/main/java/net/mamoe/mirai/MiraiMain.java
View file @
ece200d4
package
net.mamoe.mirai
;
import
net.mamoe.mirai.event.MiraiEventHook
;
import
net.mamoe.mirai.event.MiraiEventManager
;
import
net.mamoe.mirai.event.events.qq.FriendMessageEvent
;
/**
* @author
Him188moe
* @author
NaturalHG
*/
public
final
class
MiraiMain
{
private
static
MiraiServer
server
;
...
...
mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java
View file @
ece200d4
...
...
@@ -23,6 +23,9 @@ import java.util.Scanner;
import
java.util.concurrent.ExecutionException
;
/**
* Mirai 服务器.
* 管理一些基础的事务
*
* @author NaturalHG
*/
public
class
MiraiServer
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt
View file @
ece200d4
...
...
@@ -6,9 +6,12 @@ import net.mamoe.mirai.message.defaults.MessageChain
import
net.mamoe.mirai.message.defaults.PlainText
/**
* 联系人.
*
* A contact is a [QQ] or a [Group] for one particular [Bot] instance only.
*
* @param bot Owner [Bot]
* @param bot the Owner [Bot]
* @param number the id number of this contact
* @author Him188moe
*/
abstract
class
Contact
internal
constructor
(
val
bot
:
Bot
,
val
number
:
Long
)
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt
View file @
ece200d4
...
...
@@ -7,7 +7,11 @@ import net.mamoe.mirai.utils.ContactList
import
java.io.Closeable
/**
* 群
* 群.
*
* Group ID 与 Group Number 并不是同一个值.
* - Group Number([Group.number]) 是通常使用的群号码.(在 QQ 客户端中可见)
* - Group ID([Group.groupId]) 是与服务器通讯时使用的 id.(在 QQ 客户端中不可见)
*
* Java 获取 groupNumber: `group.getNumber()`
* Java 获取所属 bot: `group.getBot()`
...
...
@@ -15,6 +19,7 @@ import java.io.Closeable
* Java 获取 groupId: `group.getGroupId()`
*
* Java 调用 [groupNumberToId] : `Group.groupNumberToId(number)`
* @author Him188moe
*/
class
Group
(
bot
:
Bot
,
number
:
Long
)
:
Contact
(
bot
,
number
),
Closeable
{
val
groupId
=
groupNumberToId
(
number
)
...
...
mirai-core/src/main/java/net/mamoe/mirai/event/events/bot/BotEvent.java
View file @
ece200d4
...
...
@@ -6,6 +6,9 @@ import org.jetbrains.annotations.NotNull;
import
java.util.Objects
;
/**
* @author Him188moe
*/
public
abstract
class
BotEvent
extends
MiraiEvent
{
private
final
Bot
bot
;
...
...
mirai-core/src/main/java/net/mamoe/mirai/event/events/bot/BotEvents.kt
deleted
100644 → 0
View file @
87532418
package
net.mamoe.mirai.event.events.bot
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.event.MiraiEvent
/**
* @author Him188moe
*/
class
BotLoginEvent
(
val
bot
:
Bot
)
:
MiraiEvent
()
class
BotLogoutEvent
(
val
bot
:
Bot
)
:
MiraiEvent
()
class
BotMessageReceivedEvent
(
val
bot
:
Bot
,
val
type
:
Type
,
val
message
:
String
)
:
MiraiEvent
()
{
enum
class
Type
{
FRIEND
,
GROUP
}
}
mirai-core/src/main/java/net/mamoe/mirai/event/events/bot/BotLoginSucceedEvent.java
View file @
ece200d4
...
...
@@ -2,6 +2,9 @@ package net.mamoe.mirai.event.events.bot;
import
net.mamoe.mirai.Bot
;
/**
* @author NaturalHG
*/
public
final
class
BotLoginSucceedEvent
extends
BotEvent
{
public
BotLoginSucceedEvent
(
Bot
bot
)
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt
View file @
ece200d4
...
...
@@ -423,7 +423,7 @@ class BotNetworkHandler(private val bot: Bot) : Closeable {
//登录成功后会收到大量上次的消息, 忽略掉
MiraiThreadPool
.
getInstance
().
schedule
({
messageHandler
.
ignoreMessage
=
false
},
2
,
TimeUnit
.
SECONDS
)
},
3
,
TimeUnit
.
SECONDS
)
this
.
tlv0105
=
packet
.
tlv0105
sendPacket
(
ClientChangeOnlineStatusPacket
(
bot
.
account
.
qqNumber
,
sessionKey
,
ClientLoginStatus
.
ONLINE
))
...
...
@@ -485,7 +485,7 @@ class BotNetworkHandler(private val bot: Bot) : Closeable {
* 处理消息事件, 承担消息发送任务.
*/
inner
class
MessageHandler
:
PacketHandler
()
{
internal
var
ignoreMessage
:
Boolean
=
fals
e
internal
var
ignoreMessage
:
Boolean
=
tru
e
init
{
//todo for test
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt
View file @
ece200d4
...
...
@@ -112,10 +112,6 @@ fun DataOutputStream.encryptAndWrite(byteArray: ByteArray, key: ByteArray) {
this
.
write
(
TEA
.
encrypt
(
byteArray
,
key
))
}
fun
DataOutputStream
.
encryptAndWrite
(
byteArray
:
ByteArray
,
cryptor
:
TEA
)
{
this
.
write
(
cryptor
.
encrypt
(
byteArray
))
}
fun
DataOutputStream
.
encryptAndWrite
(
key
:
ByteArray
,
encoder
:
(
ByteArrayDataOutputStream
)
->
Unit
)
{
this
.
write
(
TEA
.
encrypt
(
ByteArrayDataOutputStream
().
let
{
encoder
(
it
);
it
.
toByteArray
()
},
key
))
}
...
...
@@ -125,10 +121,6 @@ fun DataOutputStream.encryptAndWrite(keyHex: String, encoder: (ByteArrayDataOutp
this
.
encryptAndWrite
(
keyHex
.
hexToBytes
(),
encoder
)
}
fun
DataOutputStream
.
encryptAndWrite
(
cryptor
:
TEA
,
encoder
:
(
ByteArrayDataOutputStream
)
->
Unit
)
{
this
.
write
(
cryptor
.
encrypt
(
ByteArrayDataOutputStream
().
let
{
encoder
(
it
);
it
.
toByteArray
()
}))
}
@ExperimentalUnsignedTypes
@Throws
(
IOException
::
class
)
fun
DataOutputStream
.
writeTLV0006
(
qq
:
Long
,
password
:
String
,
loginTime
:
Int
,
loginIP
:
String
,
tgtgtKey
:
ByteArray
)
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt
View file @
ece200d4
...
...
@@ -67,7 +67,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
*/
@ExperimentalUnsignedTypes
@PacketId
(
"08 25 31 01"
)
class
ClientTouchPacket
(
val
qq
:
Long
,
val
serverIp
:
String
)
:
ClientPacket
()
{
class
ClientTouchPacket
(
private
val
qq
:
Long
,
private
val
serverIp
:
String
)
:
ClientPacket
()
{
@ExperimentalUnsignedTypes
@Throws
(
IOException
::
class
)
override
fun
encode
()
{
...
...
@@ -75,19 +75,15 @@ class ClientTouchPacket(val qq: Long, val serverIp: String) : ClientPacket() {
this
.
writeHex
(
Protocol
.
fixVer
)
this
.
writeHex
(
Protocol
.
key0825
)
this
.
write
(
TEA
.
CRYPTOR_0825KEY
.
encrypt
(
object
:
ByteArrayDataOutputStream
()
{
@Throws
(
IOException
::
class
)
override
fun
toByteArray
():
ByteArray
{
this
.
writeHex
(
Protocol
.
constantData1
)
this
.
writeHex
(
Protocol
.
constantData2
)
this
.
writeQQ
(
qq
)
this
.
writeHex
(
"00 00 00 00 03 09 00 08 00 01"
)
this
.
writeIP
(
serverIp
);
this
.
writeHex
(
"00 02 00 36 00 12 00 02 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 14 00 1D 01 02 00 19"
)
this
.
writeHex
(
Protocol
.
publicKey
)
return
super
.
toByteArray
()
}
}.
toByteArray
()))
this
.
encryptAndWrite
(
Protocol
.
key0825
)
{
it
.
writeHex
(
Protocol
.
constantData1
)
it
.
writeHex
(
Protocol
.
constantData2
)
it
.
writeQQ
(
qq
)
it
.
writeHex
(
"00 00 00 00 03 09 00 08 00 01"
)
it
.
writeIP
(
serverIp
);
it
.
writeHex
(
"00 02 00 36 00 12 00 02 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 14 00 1D 01 02 00 19"
)
it
.
writeHex
(
Protocol
.
publicKey
)
}
}
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/AddFriendResult.kt
View file @
ece200d4
...
...
@@ -2,6 +2,8 @@ package net.mamoe.mirai.network.packet.action
/**
* 添加好友结果
*
* @author Him188moe
*/
enum
class
AddFriendResult
{
/**
...
...
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt
View file @
ece200d4
package
net.mamoe.mirai.network.packet.login
import
net.mamoe.mirai.network.Protocol
import
net.mamoe.mirai.network.packet.ServerPacket
import
net.mamoe.mirai.network.packet.cutTail
import
net.mamoe.mirai.network.packet.dataInputStream
import
net.mamoe.mirai.network.packet.goto
import
net.mamoe.mirai.utils.TEA
import
net.mamoe.mirai.utils.TestedSuccessfully
import
net.mamoe.mirai.utils.hexToUBytes
import
java.io.DataInputStream
...
...
@@ -40,9 +39,10 @@ class ServerLoginResponseVerificationCodeInitPacket(input: DataInputStream, priv
}
@ExperimentalUnsignedTypes
fun
decrypt
():
ServerLoginResponseVerificationCodeInitPacket
{
this
.
input
goto
14
val
data
=
TEA
.
CRYPTOR_SHARE_KEY
.
decrypt
(
this
.
input
.
readAllBytes
().
cutTail
(
1
));
val
data
=
this
.
decryptBy
(
Protocol
.
shareKey
).
goto
(
0
).
readAllBytes
()
return
ServerLoginResponseVerificationCodeInitPacket
(
data
.
dataInputStream
(),
data
.
size
).
setId
(
this
.
idHex
)
}
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/plugin/MiraiPluginBase.java
View file @
ece200d4
...
...
@@ -9,6 +9,8 @@ import net.mamoe.mirai.Bot;
*
* @see net.mamoe.mirai.event.MiraiEventManager
* @see net.mamoe.mirai.event.MiraiEventManagerKt
* @author Him188moe
* @author NaturalHG
*/
public
abstract
class
MiraiPluginBase
{
}
mirai-core/src/main/java/net/mamoe/mirai/plugin/MiraiPluginManager.java
View file @
ece200d4
package
net.mamoe.mirai.plugin
;
/**
* @author NaturalHG
*/
public
class
MiraiPluginManager
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskExceptionHandler.java
View file @
ece200d4
package
net.mamoe.mirai.task
;
/**
* @author NaturalHG
*/
@FunctionalInterface
public
interface
MiraiTaskExceptionHandler
{
void
onHandle
(
Throwable
e
);
...
...
mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java
View file @
ece200d4
...
...
@@ -10,6 +10,9 @@ import java.util.concurrent.atomic.AtomicInteger;
import
java.util.function.Consumer
;
import
java.util.function.Predicate
;
/**
* @author NaturalHG
*/
public
final
class
MiraiTaskManager
{
private
static
MiraiTaskManager
instance
=
new
MiraiTaskManager
();
...
...
mirai-core/src/main/java/net/mamoe/mirai/task/MiraiThreadPool.java
View file @
ece200d4
...
...
@@ -3,6 +3,9 @@ package net.mamoe.mirai.task;
import
java.io.Closeable
;
import
java.util.concurrent.ScheduledThreadPoolExecutor
;
/**
* @author NaturalHG
*/
public
final
class
MiraiThreadPool
extends
ScheduledThreadPoolExecutor
implements
Closeable
{
private
static
MiraiThreadPool
instance
=
new
MiraiThreadPool
();
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/
Rob
otAccount.java
→
mirai-core/src/main/java/net/mamoe/mirai/utils/
B
otAccount.java
View file @
ece200d4
File moved
mirai-core/src/main/java/net/mamoe/mirai/utils/CharImageUtil.java
View file @
ece200d4
package
net.mamoe.mirai.utils
;
import
java.awt.image.BufferedImage
;
/**
* @author NaturalHG
*/
public
final
class
CharImageUtil
{
public
static
String
createCharImg
(
BufferedImage
image
)
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/ClientLoginStatus.java
View file @
ece200d4
package
net.mamoe.mirai.utils
;
/**
* QQ 在线状态
*
* @author Him188moe
* @see net.mamoe.mirai.network.packet.login.ClientChangeOnlineStatusPacket
*/
public
enum
ClientLoginStatus
{
/**
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/EventException.java
View file @
ece200d4
package
net.mamoe.mirai.utils
;
/**
* @author NaturalHG
*/
public
class
EventException
extends
RuntimeException
{
private
final
Throwable
cause
;
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/LoggerTextFormat.java
View file @
ece200d4
package
net.mamoe.mirai.utils
;
/**
* @author NaturalHG
*/
public
enum
LoggerTextFormat
{
RESET
(
"\33[0m"
),
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/MiraiLogger.kt
View file @
ece200d4
...
...
@@ -6,6 +6,9 @@ import java.util.*
/**
* used to replace old logger
*
* @author Him188moe
* @author NaturalHG
*/
object
MiraiLogger
{
infix
fun
log
(
o
:
Any
?)
=
info
(
o
)
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.java
deleted
100644 → 0
View file @
87532418
package
net.mamoe.mirai.utils
;
import
net.mamoe.mirai.network.Protocol
;
import
java.nio.ByteBuffer
;
import
java.util.Random
;
/**
* TEA 加密
*
* @author iweiz https://github.com/iweizime/StepChanger/blob/master/app/src/main/java/me/iweizi/stepchanger/qq/Cryptor.java
*/
public
final
class
TEA
{
public
static
final
TEA
CRYPTOR_SHARE_KEY
=
new
TEA
(
Protocol
.
INSTANCE
.
hexToBytes
(
Protocol
.
shareKey
));
public
static
final
TEA
CRYPTOR_0825KEY
=
new
TEA
(
Protocol
.
INSTANCE
.
hexToBytes
(
Protocol
.
key0825
));
private
static
final
long
UINT32_MASK
=
0xffffffff
L
;
private
final
long
[]
mKey
;
private
final
Random
mRandom
;
private
final
byte
[]
key
;
private
byte
[]
mOutput
;
private
byte
[]
mInBlock
;
private
int
mIndexPos
;
private
byte
[]
mIV
;
private
int
mOutPos
;
private
int
mPreOutPos
;
private
boolean
isFirstBlock
;
public
TEA
(
byte
[]
key
)
{
this
.
key
=
key
;
mKey
=
new
long
[
4
];
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
mKey
[
i
]
=
pack
(
key
,
i
*
4
,
4
);
}
mRandom
=
new
Random
();
isFirstBlock
=
true
;
}
public
static
byte
[]
encrypt
(
byte
[]
source
,
byte
[]
key
)
{
return
new
TEA
(
key
).
encrypt
(
source
);
}
public
static
byte
[]
encrypt
(
byte
[]
source
,
String
keyHex
)
{
return
encrypt
(
source
,
UtilsKt
.
hexToBytes
(
keyHex
));
}
public
static
byte
[]
decrypt
(
byte
[]
source
,
byte
[]
key
)
{
return
new
TEA
(
key
).
decrypt
(
source
);
}
public
static
byte
[]
decrypt
(
byte
[]
source
,
String
keyHex
)
{
return
decrypt
(
source
,
UtilsKt
.
hexToBytes
(
keyHex
));
}
@SuppressWarnings
(
"SameParameterValue"
)
private
static
long
pack
(
byte
[]
bytes
,
int
offset
,
int
len
)
{
long
result
=
0
;
int
max_offset
=
len
>
8
?
offset
+
8
:
offset
+
len
;
for
(
int
index
=
offset
;
index
<
max_offset
;
index
++)
{
result
=
result
<<
8
|
((
long
)
bytes
[
index
]
&
0xff
L
);
}
return
result
>>
32
|
result
&
UINT32_MASK
;
}
private
int
rand
()
{
return
mRandom
.
nextInt
();
}
private
byte
[]
encode
(
byte
[]
bytes
)
{
long
v0
=
pack
(
bytes
,
0
,
4
);
long
v1
=
pack
(
bytes
,
4
,
4
);
long
sum
=
0
;
long
delta
=
0x9e3779b9
L
;
for
(
int
i
=
0
;
i
<
16
;
i
++)
{
sum
=
(
sum
+
delta
)
&
UINT32_MASK
;
v0
+=
((
v1
<<
4
)
+
mKey
[
0
])
^
(
v1
+
sum
)
^
((
v1
>>>
5
)
+
mKey
[
1
]);
v0
&=
UINT32_MASK
;
v1
+=
((
v0
<<
4
)
+
mKey
[
2
])
^
(
v0
+
sum
)
^
((
v0
>>>
5
)
+
mKey
[
3
]);
v1
&=
UINT32_MASK
;
}
return
ByteBuffer
.
allocate
(
8
).
putInt
((
int
)
v0
).
putInt
((
int
)
v1
).
array
();
}
private
byte
[]
decode
(
byte
[]
bytes
,
int
offset
)
{
long
v0
=
pack
(
bytes
,
offset
,
4
);
long
v1
=
pack
(
bytes
,
offset
+
4
,
4
);
long
delta
=
0x9e3779b9
L
;
long
sum
=
(
delta
<<
4
)
&
UINT32_MASK
;
for
(
int
i
=
0
;
i
<
16
;
i
++)
{
v1
-=
((
v0
<<
4
)
+
mKey
[
2
])
^
(
v0
+
sum
)
^
((
v0
>>>
5
)
+
mKey
[
3
]);
v1
&=
UINT32_MASK
;
v0
-=
((
v1
<<
4
)
+
mKey
[
0
])
^
(
v1
+
sum
)
^
((
v1
>>>
5
)
+
mKey
[
1
]);
v0
&=
UINT32_MASK
;
sum
=
(
sum
-
delta
)
&
UINT32_MASK
;
}
return
ByteBuffer
.
allocate
(
8
).
putInt
((
int
)
v0
).
putInt
((
int
)
v1
).
array
();
}
private
void
encodeOneBlock
()
{
for
(
mIndexPos
=
0
;
mIndexPos
<
8
;
mIndexPos
++)
{
mInBlock
[
mIndexPos
]
=
isFirstBlock
?
mInBlock
[
mIndexPos
]
:
((
byte
)
(
mInBlock
[
mIndexPos
]
^
mOutput
[
mPreOutPos
+
mIndexPos
]));
}
System
.
arraycopy
(
encode
(
mInBlock
),
0
,
mOutput
,
mOutPos
,
8
);
for
(
mIndexPos
=
0
;
mIndexPos
<
8
;
mIndexPos
++)
{
int
out_pos
=
mOutPos
+
mIndexPos
;
mOutput
[
out_pos
]
=
(
byte
)
(
mOutput
[
out_pos
]
^
mIV
[
mIndexPos
]);
}
System
.
arraycopy
(
mInBlock
,
0
,
mIV
,
0
,
8
);
mPreOutPos
=
mOutPos
;
mOutPos
+=
8
;
mIndexPos
=
0
;
isFirstBlock
=
false
;
}
@SuppressWarnings
(
"BooleanMethodIsAlwaysInverted"
)
private
boolean
decodeOneBlock
(
byte
[]
ciphertext
,
int
offset
,
int
len
)
{
for
(
mIndexPos
=
0
;
mIndexPos
<
8
;
mIndexPos
++)
{
if
(
mOutPos
+
mIndexPos
<
len
)
{
mIV
[
mIndexPos
]
=
(
byte
)
(
mIV
[
mIndexPos
]
^
ciphertext
[
mOutPos
+
offset
+
mIndexPos
]);
continue
;
}
return
true
;
}
mIV
=
decode
(
mIV
,
0
);
mOutPos
+=
8
;
mIndexPos
=
0
;
return
true
;
}
@SuppressWarnings
(
"SameParameterValue"
)
private
byte
[]
encrypt
(
byte
[]
plaintext
,
int
offset
,
int
len
)
{
mInBlock
=
new
byte
[
8
];
mIV
=
new
byte
[
8
];
mOutPos
=
0
;
mPreOutPos
=
0
;
isFirstBlock
=
true
;
mIndexPos
=
(
len
+
10
)
%
8
;
if
(
mIndexPos
!=
0
)
{
mIndexPos
=
8
-
mIndexPos
;
}
mOutput
=
new
byte
[
mIndexPos
+
len
+
10
];
mInBlock
[
0
]
=
(
byte
)
(
rand
()
&
0xf8
|
mIndexPos
);
for
(
int
i
=
1
;
i
<=
mIndexPos
;
i
++)
{
mInBlock
[
i
]
=
(
byte
)
(
rand
()
&
0xff
);
}
++
mIndexPos
;
for
(
int
i
=
0
;
i
<
8
;
i
++)
{
mIV
[
i
]
=
0
;
}
int
g
=
0
;
while
(
g
<
2
)
{
if
(
mIndexPos
<
8
)
{
mInBlock
[
mIndexPos
++]
=
(
byte
)
(
rand
()
&
0xff
);
++
g
;
}
if
(
mIndexPos
==
8
)
{
encodeOneBlock
();
}
}
for
(;
len
>
0
;
len
--)
{
if
(
mIndexPos
<
8
)
{
mInBlock
[
mIndexPos
++]
=
plaintext
[
offset
++];
}
if
(
mIndexPos
==
8
)
{
encodeOneBlock
();
}
}
for
(
g
=
0
;
g
<
7
;
g
++)
{
if
(
mIndexPos
<
8
)
{
mInBlock
[
mIndexPos
++]
=
(
byte
)
0
;
}
if
(
mIndexPos
==
8
)
{
encodeOneBlock
();
}
}
return
mOutput
;
}
@SuppressWarnings
(
"SameParameterValue"
)
private
byte
[]
decrypt
(
byte
[]
cipherText
,
int
offset
,
int
len
)
{
if
(
len
%
8
!=
0
||
len
<
16
)
{
throw
new
IllegalArgumentException
(
"must len % 8 == 0 && len >= 16"
);
}
mIV
=
decode
(
cipherText
,
offset
);
mIndexPos
=
mIV
[
0
]
&
7
;
int
plen
=
len
-
mIndexPos
-
10
;
isFirstBlock
=
true
;
if
(
plen
<
0
)
{
return
null
;
}
mOutput
=
new
byte
[
plen
];
mPreOutPos
=
0
;
mOutPos
=
8
;
++
mIndexPos
;
int
g
=
0
;
while
(
g
<
2
)
{
if
(
mIndexPos
<
8
)
{
++
mIndexPos
;
++
g
;
}
if
(
mIndexPos
==
8
)
{
isFirstBlock
=
false
;
if
(!
decodeOneBlock
(
cipherText
,
offset
,
len
))
{
throw
new
RuntimeException
(
"Unable to decode"
);
}
}
}
for
(
int
outpos
=
0
;
plen
!=
0
;
plen
--)
{
if
(
mIndexPos
<
8
)
{
mOutput
[
outpos
++]
=
isFirstBlock
?
mIV
[
mIndexPos
]
:
(
byte
)
(
cipherText
[
mPreOutPos
+
offset
+
mIndexPos
]
^
mIV
[
mIndexPos
]);
++
mIndexPos
;
}
if
(
mIndexPos
==
8
)
{
mPreOutPos
=
mOutPos
-
8
;
isFirstBlock
=
false
;
if
(!
decodeOneBlock
(
cipherText
,
offset
,
len
))
{
throw
new
RuntimeException
(
"Unable to decode"
);
}
}
}
for
(
g
=
0
;
g
<
7
;
g
++)
{
if
(
mIndexPos
<
8
)
{
if
((
cipherText
[
mPreOutPos
+
offset
+
mIndexPos
]
^
mIV
[
mIndexPos
])
!=
0
)
{
throw
new
RuntimeException
();
}
else
{
++
mIndexPos
;
}
}
if
(
mIndexPos
==
8
)
{
mPreOutPos
=
mOutPos
;
if
(!
decodeOneBlock
(
cipherText
,
offset
,
len
))
{
throw
new
RuntimeException
(
"Unable to decode"
);
}
}
}
return
mOutput
;
}
public
byte
[]
encrypt
(
byte
[]
plaintext
)
{
return
encrypt
(
plaintext
,
0
,
plaintext
.
length
);
}
public
byte
[]
decrypt
(
byte
[]
ciphertext
)
{
try
{
return
decrypt
(
ciphertext
,
0
,
ciphertext
.
length
);
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Source: "
+
UtilsKt
.
toUHexString
(
ciphertext
,
" "
));
System
.
out
.
println
(
"Key: "
+
UtilsKt
.
toUHexString
(
this
.
key
,
" "
));
throw
e
;
}
}
}
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.kt
0 → 100644
View file @
ece200d4
package
net.mamoe.mirai.utils
import
net.mamoe.mirai.network.Protocol
import
java.nio.ByteBuffer
import
java.util.*
import
kotlin.experimental.and
import
kotlin.experimental.xor
/**
* @author Him188moe
*/
/**
* TEA 加密
*
* @author iweiz https://github.com/iweizime/StepChanger/blob/master/app/src/main/java/me/iweizi/stepchanger/qq/Cryptor.java
*/
class
TEA
(
private
val
key
:
ByteArray
)
{
companion
object
{
val
CRYPTOR_SHARE_KEY
=
TEA
(
Protocol
.
hexToBytes
(
Protocol
.
shareKey
))
val
CRYPTOR_0825KEY
=
TEA
(
Protocol
.
hexToBytes
(
Protocol
.
key0825
))
private
val
UINT32_MASK
=
0
xffffffffL
fun
doOption
(
data
:
ByteArray
,
key
:
ByteArray
,
encrypt
:
Boolean
):
ByteArray
{
val
mRandom
=
Random
()
lateinit
var
mOutput
:
ByteArray
lateinit
var
mInBlock
:
ByteArray
var
mIndexPos
:
Int
lateinit
var
mIV
:
ByteArray
var
mOutPos
=
0
var
mPreOutPos
=
0
var
isFirstBlock
:
Boolean
=
true
val
mKey
=
LongArray
(
4
)
for
(
i
in
0
..
3
)
{
mKey
[
i
]
=
pack
(
key
,
i
*
4
,
4
)
}
fun
rand
():
Int
{
return
mRandom
.
nextInt
()
}
fun
encode
(
bytes
:
ByteArray
):
ByteArray
{
var
v0
=
pack
(
bytes
,
0
,
4
)
var
v1
=
pack
(
bytes
,
4
,
4
)
var
sum
:
Long
=
0
val
delta
=
0
x9e3779b9L
for
(
i
in
0
..
15
)
{
sum
=
sum
+
delta
and
UINT32_MASK
v0
+=
(
v1
shl
4
)
+
mKey
[
0
]
xor
v1
+
sum
xor
v1
.
ushr
(
5
)
+
mKey
[
1
]
v0
=
v0
and
UINT32_MASK
v1
+=
(
v0
shl
4
)
+
mKey
[
2
]
xor
v0
+
sum
xor
v0
.
ushr
(
5
)
+
mKey
[
3
]
v1
=
v1
and
UINT32_MASK
}
return
ByteBuffer
.
allocate
(
8
).
putInt
(
v0
.
toInt
()).
putInt
(
v1
.
toInt
()).
array
()
}
fun
decode
(
bytes
:
ByteArray
,
offset
:
Int
):
ByteArray
{
var
v0
=
pack
(
bytes
,
offset
,
4
)
var
v1
=
pack
(
bytes
,
offset
+
4
,
4
)
val
delta
=
0
x9e3779b9L
var
sum
=
delta
shl
4
and
UINT32_MASK
for
(
i
in
0
..
15
)
{
v1
-=
(
v0
shl
4
)
+
mKey
[
2
]
xor
v0
+
sum
xor
v0
.
ushr
(
5
)
+
mKey
[
3
]
v1
=
v1
and
UINT32_MASK
v0
-=
(
v1
shl
4
)
+
mKey
[
0
]
xor
v1
+
sum
xor
v1
.
ushr
(
5
)
+
mKey
[
1
]
v0
=
v0
and
UINT32_MASK
sum
=
sum
-
delta
and
UINT32_MASK
}
return
ByteBuffer
.
allocate
(
8
).
putInt
(
v0
.
toInt
()).
putInt
(
v1
.
toInt
()).
array
()
}
fun
encodeOneBlock
()
{
mIndexPos
=
0
while
(
mIndexPos
<
8
)
{
mInBlock
[
mIndexPos
]
=
if
(
isFirstBlock
)
mInBlock
[
mIndexPos
]
else
(
mInBlock
[
mIndexPos
]
xor
mOutput
[
mPreOutPos
+
mIndexPos
])
mIndexPos
++
}
System
.
arraycopy
(
encode
(
mInBlock
),
0
,
mOutput
,
mOutPos
,
8
)
mIndexPos
=
0
while
(
mIndexPos
<
8
)
{
val
out_pos
=
mOutPos
+
mIndexPos
mOutput
[
out_pos
]
=
(
mOutput
[
out_pos
]
xor
mIV
[
mIndexPos
])
mIndexPos
++
}
System
.
arraycopy
(
mInBlock
,
0
,
mIV
,
0
,
8
)
mPreOutPos
=
mOutPos
mOutPos
+=
8
mIndexPos
=
0
isFirstBlock
=
false
}
fun
decodeOneBlock
(
ciphertext
:
ByteArray
,
offset
:
Int
,
len
:
Int
):
Boolean
{
mIndexPos
=
0
while
(
mIndexPos
<
8
)
{
if
(
mOutPos
+
mIndexPos
<
len
)
{
mIV
[
mIndexPos
]
=
(
mIV
[
mIndexPos
]
xor
ciphertext
[
mOutPos
+
offset
+
mIndexPos
])
mIndexPos
++
continue
}
return
true
}
mIV
=
decode
(
mIV
,
0
)
mOutPos
+=
8
mIndexPos
=
0
return
true
}
fun
encrypt
(
plaintext
:
ByteArray
,
offset
:
Int
,
len
:
Int
):
ByteArray
{
var
len
=
len
;
var
offset
=
offset
;
mInBlock
=
ByteArray
(
8
)
mIV
=
ByteArray
(
8
)
mOutPos
=
0
mPreOutPos
=
0
isFirstBlock
=
true
mIndexPos
=
(
len
+
10
)
%
8
if
(
mIndexPos
!=
0
)
{
mIndexPos
=
8
-
mIndexPos
}
mOutput
=
ByteArray
(
mIndexPos
+
len
+
10
)
mInBlock
[
0
]
=
(
rand
()
and
0
xf8
or
mIndexPos
).
toByte
()
for
(
i
in
1
..
mIndexPos
)
{
mInBlock
[
i
]
=
(
rand
()
and
0
xff
).
toByte
()
}
++
mIndexPos
for
(
i
in
0
..
7
)
{
mIV
[
i
]
=
0
}
var
g
=
0
while
(
g
<
2
)
{
if
(
mIndexPos
<
8
)
{
mInBlock
[
mIndexPos
++]
=
(
rand
()
and
0
xff
).
toByte
()
++
g
}
if
(
mIndexPos
==
8
)
{
encodeOneBlock
()
}
}
while
(
len
>
0
)
{
if
(
mIndexPos
<
8
)
{
mInBlock
[
mIndexPos
++]
=
plaintext
[
offset
++]
}
if
(
mIndexPos
==
8
)
{
encodeOneBlock
()
}
len--
}
g
=
0
while
(
g
<
7
)
{
if
(
mIndexPos
<
8
)
{
mInBlock
[
mIndexPos
++]
=
0
.
toByte
()
}
if
(
mIndexPos
==
8
)
{
encodeOneBlock
()
}
g
++
}
return
mOutput
}
fun
decrypt
(
cipherText
:
ByteArray
,
offset
:
Int
,
len
:
Int
):
ByteArray
?
{
require
(!(
len
%
8
!=
0
||
len
<
16
))
{
"must len % 8 == 0 && len >= 16"
}
mIV
=
decode
(
cipherText
,
offset
)
mIndexPos
=
(
mIV
[
0
]
and
7
).
toInt
()
var
plen
=
len
-
mIndexPos
-
10
isFirstBlock
=
true
if
(
plen
<
0
)
{
return
null
}
mOutput
=
ByteArray
(
plen
)
mPreOutPos
=
0
mOutPos
=
8
++
mIndexPos
var
g
=
0
while
(
g
<
2
)
{
if
(
mIndexPos
<
8
)
{
++
mIndexPos
++
g
}
if
(
mIndexPos
==
8
)
{
isFirstBlock
=
false
if
(!
decodeOneBlock
(
cipherText
,
offset
,
len
))
{
throw
RuntimeException
(
"Unable to decode"
)
}
}
}
var
outpos
=
0
while
(
plen
!=
0
)
{
if
(
mIndexPos
<
8
)
{
mOutput
[
outpos
++]
=
if
(
isFirstBlock
)
mIV
[
mIndexPos
]
else
(
cipherText
[
mPreOutPos
+
offset
+
mIndexPos
]
xor
mIV
[
mIndexPos
])
++
mIndexPos
}
if
(
mIndexPos
==
8
)
{
mPreOutPos
=
mOutPos
-
8
isFirstBlock
=
false
if
(!
decodeOneBlock
(
cipherText
,
offset
,
len
))
{
throw
RuntimeException
(
"Unable to decode"
)
}
}
plen--
}
g
=
0
while
(
g
<
7
)
{
if
(
mIndexPos
<
8
)
{
if
(
cipherText
[
mPreOutPos
+
offset
+
mIndexPos
].
xor
(
mIV
[
mIndexPos
]).
toInt
()
!=
0
)
{
throw
RuntimeException
()
}
else
{
++
mIndexPos
}
}
if
(
mIndexPos
==
8
)
{
mPreOutPos
=
mOutPos
if
(!
decodeOneBlock
(
cipherText
,
offset
,
len
))
{
throw
RuntimeException
(
"Unable to decode"
)
}
}
g
++
}
return
mOutput
}
return
if
(
encrypt
)
{
encrypt
(
data
,
0
,
data
.
size
)
}
else
{
try
{
return
decrypt
(
data
,
0
,
data
.
size
)
!!
}
catch
(
e
:
Exception
)
{
println
(
"Source: "
+
data
.
toUHexString
(
" "
))
println
(
"Key: "
+
key
.
toUHexString
(
" "
))
throw
e
}
}
}
fun
encrypt
(
source
:
ByteArray
,
key
:
ByteArray
):
ByteArray
{
return
doOption
(
source
,
key
,
true
)
}
fun
encrypt
(
source
:
ByteArray
,
keyHex
:
String
):
ByteArray
{
return
encrypt
(
source
,
keyHex
.
hexToBytes
())
}
fun
decrypt
(
source
:
ByteArray
,
key
:
ByteArray
):
ByteArray
{
return
doOption
(
source
,
key
,
false
)
}
fun
decrypt
(
source
:
ByteArray
,
keyHex
:
String
):
ByteArray
{
return
decrypt
(
source
,
keyHex
.
hexToBytes
())
}
private
fun
pack
(
bytes
:
ByteArray
,
offset
:
Int
,
len
:
Int
):
Long
{
var
result
:
Long
=
0
val
max_offset
=
if
(
len
>
8
)
offset
+
8
else
offset
+
len
for
(
index
in
offset
until
max_offset
)
{
result
=
result
shl
8
or
(
bytes
[
index
].
toLong
()
and
0
xffL
)
}
return
result
shr
32
or
(
result
and
UINT32_MASK
)
}
}
}
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/utils/Tested.kt
View file @
ece200d4
package
net.mamoe.mirai.utils
/**
* 仅用于测试时标记, 未来会删除
*
* @author Him188moe
*/
annotation
class
TestedSuccessfully
\ No newline at end of file
internal
annotation
class
TestedSuccessfully
\ No newline at end of file
mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt
View file @
ece200d4
...
...
@@ -8,6 +8,11 @@ import java.lang.reflect.Field
import
java.util.*
import
java.util.zip.CRC32
/**
* @author Him188moe
* @author NaturalHG
*/
@JvmSynthetic
fun
ByteArray
.
toHexString
():
String
=
toHexString
(
" "
)
...
...
@@ -64,6 +69,7 @@ open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream())
open
fun
toUByteArray
():
UByteArray
=
(
out
as
ByteArrayOutputStream
).
toByteArray
().
toUByteArray
()
}
@JvmSynthetic
fun
lazyEncode
(
t
:
(
ByteArrayDataOutputStream
)
->
Unit
):
ByteArray
=
ByteArrayDataOutputStream
().
let
{
t
(
it
);
return
it
.
toByteArray
()
}
@ExperimentalUnsignedTypes
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfigSection.java
View file @
ece200d4
...
...
@@ -7,6 +7,9 @@ import java.util.Map;
import
java.util.concurrent.Callable
;
import
java.util.function.Supplier
;
/**
* @author NaturalHG
*/
public
class
MiraiConfigSection
<
T
>
extends
MiraiSynchronizedLinkedListMap
<
String
,
T
>
{
public
MiraiConfigSection
(){
...
...
@@ -148,7 +151,7 @@ public class MiraiConfigSection<T> extends MiraiSynchronizedLinkedListMap<String
}
if
(
content
instanceof
Map
){
return
new
MiraiConfigSection
<>(
(
LinkedHashMap
<
String
,
D
>)
content
(
LinkedHashMap
<
String
,
D
>)
content
);
}
return
null
;
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiSynchronizedLinkedListMap.java
View file @
ece200d4
...
...
@@ -11,8 +11,10 @@ import java.util.function.Function;
/**
* 实现了可以直接被继承的 SynchronizedLinkedListMap<K,V>
*
* @param <K>
* @param <V>
* @param <K> the type of key
* @param <V> the type of value
*
* @author NaturalHG
*/
public
class
MiraiSynchronizedLinkedListMap
<
K
,
V
>
extends
AbstractMap
<
K
,
V
>
{
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/setting/MiraiSettingListSection.java
View file @
ece200d4
...
...
@@ -10,6 +10,9 @@ import java.util.concurrent.locks.Lock;
import
java.util.concurrent.locks.ReentrantLock
;
/**
* @author NaturalHG
*/
public
class
MiraiSettingListSection
extends
Vector
<
Object
>
implements
MiraiSettingSection
{
private
Lock
lock
=
new
ReentrantLock
();
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/setting/MiraiSettingMapSection.java
View file @
ece200d4
...
...
@@ -9,6 +9,9 @@ import java.util.concurrent.ConcurrentHashMap;
import
java.util.stream.Collectors
;
/**
* @author NaturalHG
*/
public
class
MiraiSettingMapSection
extends
ConcurrentHashMap
<
String
,
Object
>
implements
MiraiSettingSection
{
@SuppressWarnings
(
"unchecked"
)
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/setting/MiraiSettingSection.java
View file @
ece200d4
...
...
@@ -4,6 +4,9 @@ import org.ini4j.Profile;
import
java.io.Closeable
;
/**
* @author NaturalHG
*/
public
interface
MiraiSettingSection
extends
Closeable
{
void
saveAsSection
(
Profile
.
Section
section
);
}
...
...
mirai-core/src/main/java/net/mamoe/mirai/utils/setting/MiraiSettings.java
View file @
ece200d4
...
...
@@ -15,6 +15,8 @@ import java.util.concurrent.ConcurrentHashMap;
* Thread-safe Mirai Config <br>
* Only supports <code>INI</code> format <br>
* Supports {@link Map} and {@link List}
*
* @author NaturalHG
*/
public
class
MiraiSettings
{
...
...
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