mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-24 14:30:09 +08:00
Message analysis
This commit is contained in:
parent
21a0df80e0
commit
9fda59afc3
@ -4,8 +4,147 @@ package net.mamoe.mirai.message;
|
||||
* @author Him188moe
|
||||
*/
|
||||
public enum FaceID {
|
||||
// TODO: 2019/9/1
|
||||
Face_jingya(0),
|
||||
Face_piezui(1),
|
||||
Face_se(2),
|
||||
Face_fadai(3),
|
||||
Face_deyi(4),
|
||||
Face_liulei(5),
|
||||
Face_haixiu(6),
|
||||
Face_bizui(7),
|
||||
Face_shui(8),
|
||||
Face_daku(9),
|
||||
Face_ganga(10),
|
||||
Face_fanu(11),
|
||||
Face_tiaopi(12),
|
||||
Face_ciya(13),
|
||||
Face_weixiao(14),
|
||||
Face_nanguo(15),
|
||||
Face_ku(16),
|
||||
Face_zhuakuang(18),
|
||||
Face_tu(19),
|
||||
Face_touxiao(20),
|
||||
Face_keai(21),
|
||||
Face_baiyan(22),
|
||||
Face_aoman(23),
|
||||
Face_ji_e(24),
|
||||
Face_kun(25),
|
||||
Face_jingkong(26),
|
||||
Face_liuhan(27),
|
||||
Face_hanxiao(28),
|
||||
Face_dabing(29),
|
||||
Face_fendou(30),
|
||||
Face_zhouma(31),
|
||||
Face_yiwen(32),
|
||||
Face_yun(34),
|
||||
Face_zhemo(35),
|
||||
Face_shuai(36),
|
||||
Face_kulou(37),
|
||||
Face_qiaoda(38),
|
||||
Face_zaijian(39),
|
||||
Face_fadou(41),
|
||||
Face_aiqing(42),
|
||||
Face_tiaotiao(43),
|
||||
Face_zhutou(46),
|
||||
Face_yongbao(49),
|
||||
Face_dan_gao(53),
|
||||
Face_shandian(54),
|
||||
Face_zhadan(55),
|
||||
Face_dao(56),
|
||||
Face_zuqiu(57),
|
||||
Face_bianbian(59),
|
||||
Face_kafei(60),
|
||||
Face_fan(61),
|
||||
Face_meigui(63),
|
||||
Face_diaoxie(64),
|
||||
Face_aixin(66),
|
||||
Face_xinsui(67),
|
||||
Face_liwu(69),
|
||||
Face_taiyang(74),
|
||||
Face_yueliang(75),
|
||||
Face_qiang(76),
|
||||
Face_ruo(77),
|
||||
Face_woshou(78),
|
||||
Face_shengli(79),
|
||||
Face_feiwen(85),
|
||||
Face_naohuo(86),
|
||||
Face_xigua(89),
|
||||
Face_lenghan(96),
|
||||
Face_cahan(97),
|
||||
Face_koubi(98),
|
||||
Face_guzhang(99),
|
||||
Face_qiudale(100),
|
||||
Face_huaixiao(101),
|
||||
Face_zuohengheng(102),
|
||||
Face_youhengheng(103),
|
||||
Face_haqian(104),
|
||||
Face_bishi(105),
|
||||
Face_weiqu(106),
|
||||
Face_kuaikule(107),
|
||||
Face_yinxian(108),
|
||||
Face_qinqin(109),
|
||||
Face_xia(110),
|
||||
Face_kelian(111),
|
||||
Face_caidao(112),
|
||||
Face_pijiu(113),
|
||||
Face_lanqiu(114),
|
||||
Face_pingpang(115),
|
||||
Face_shiai(116),
|
||||
Face_piaochong(117),
|
||||
Face_baoquan(118),
|
||||
Face_gouyin(119),
|
||||
Face_quantou(120),
|
||||
Face_chajin(121),
|
||||
Face_aini(122),
|
||||
Face_bu(123),
|
||||
Face_hao(124),
|
||||
Face_zhuanquan(125),
|
||||
Face_ketou(126),
|
||||
Face_huitou(127),
|
||||
Face_tiaosheng(128),
|
||||
Face_huishou(129),
|
||||
Face_jidong(130),
|
||||
Face_jiewu(131),
|
||||
Face_xianwen(132),
|
||||
Face_zuotaiji(133),
|
||||
Face_youtaiji(134),
|
||||
Face_shuangxi(136),
|
||||
Face_bianpao(137),
|
||||
Face_denglong(138),
|
||||
Face_facai(139),
|
||||
Face_K_ge(140),
|
||||
Face_gouwu(141),
|
||||
Face_youjian(142),
|
||||
Face_shuai_qi(143),
|
||||
Face_hecai(144),
|
||||
Face_qidao(145),
|
||||
Face_baojin(146),
|
||||
Face_bangbangtang(147),
|
||||
Face_he_nai(148),
|
||||
Face_xiamian(149),
|
||||
Face_xiangjiao(150),
|
||||
Face_feiji(151),
|
||||
Face_kaiche(152),
|
||||
Face_gaotiezuochetou(153),
|
||||
Face_chexiang(154),
|
||||
Face_gaotieyouchetou(155),
|
||||
Face_duoyun(156),
|
||||
Face_xiayu(157),
|
||||
Face_chaopiao(158),
|
||||
Face_xiongmao(159),
|
||||
Face_dengpao(160),
|
||||
Face_fengche(161),
|
||||
Face_naozhong(162),
|
||||
Face_dasan(163),
|
||||
Face_caiqiu(164),
|
||||
Face_zuanjie(165),
|
||||
Face_shafa(166),
|
||||
Face_zhijin(167),
|
||||
Face_yao(168),
|
||||
Face_shouqiang(169),
|
||||
Face_qingwa(170),
|
||||
|
||||
// TODO: 2019/9/1 添加更多表情
|
||||
|
||||
;
|
||||
|
||||
@ -18,4 +157,15 @@ public enum FaceID {
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static FaceID ofId(int id) {
|
||||
for (FaceID value : FaceID.values()) {
|
||||
if (value.id == id) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ public abstract class Message {
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
public String toDebugString() {
|
||||
return this.getClass().getSimpleName() + String.format("(%s)", this.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 把这个消息连接到另一个消息的头部. 相当于字符串相加
|
||||
* <p>
|
||||
@ -76,4 +80,5 @@ public abstract class Message {
|
||||
this.concat(new At(target));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,10 @@ public final class Face extends Message {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO: 2019/9/1
|
||||
throw new UnsupportedOperationException();
|
||||
if (id == null) {
|
||||
return "[face?]";
|
||||
|
||||
}
|
||||
return String.format("[face%d]", id.getId());
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import java.net.URL;
|
||||
* @author Him188moe
|
||||
*/
|
||||
public final class Image extends Message {
|
||||
private String imageID;
|
||||
|
||||
public Image(InputStream inputStream) {
|
||||
|
||||
}
|
||||
@ -33,11 +35,11 @@ public final class Image extends Message {
|
||||
* @param imageID
|
||||
*/
|
||||
public Image(String imageID) {
|
||||
|
||||
this.imageID = imageID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return null;
|
||||
return imageID;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ public final class MessageChain extends Message {
|
||||
list.add(message);
|
||||
}
|
||||
|
||||
public MessageChain() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return An unmodifiable list
|
||||
*/
|
||||
@ -45,6 +49,10 @@ public final class MessageChain extends Message {
|
||||
return this.list.stream().map(Message::toString).collect(Collectors.joining(""));
|
||||
}
|
||||
|
||||
public synchronized String toDebugString() {
|
||||
return String.format("MessageChain(%s)", this.list.stream().map(Message::toDebugString).collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Message concat(@NotNull Message tail) {
|
||||
this.list.add(tail);
|
||||
|
@ -64,6 +64,11 @@ object Protocol {
|
||||
*/
|
||||
const val key0836 = "EF 4A 36 6A 16 A8 E6 3D 2E EA BD 1F 98 C1 3C DA"
|
||||
|
||||
/**
|
||||
* 发送/接受消息中的一个const
|
||||
*/
|
||||
const val friendMessageConst1 = "00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91"
|
||||
|
||||
private val hexToByteArrayCacheMap: MutableMap<Int, ByteArray> = mutableMapOf()
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
@ -171,11 +171,10 @@ fun DataOutputStream.writeCRC32(key: ByteArray) {
|
||||
@ExperimentalUnsignedTypes
|
||||
@TestedSuccessfully
|
||||
fun DataOutputStream.writeDeviceName(random: Boolean = false) {
|
||||
val deviceName: String
|
||||
if (random) {
|
||||
deviceName = String(getRandomByteArray(10))
|
||||
val deviceName: String = if (random) {
|
||||
String(getRandomByteArray(10))
|
||||
} else {
|
||||
deviceName = InetAddress.getLocalHost().hostName
|
||||
InetAddress.getLocalHost().hostName
|
||||
}
|
||||
this.writeShort(deviceName.length + 2)
|
||||
this.writeShort(deviceName.length)
|
||||
|
@ -1,9 +1,14 @@
|
||||
package net.mamoe.mirai.network.packet
|
||||
|
||||
import net.mamoe.mirai.message.FaceID
|
||||
import net.mamoe.mirai.message.Message
|
||||
import net.mamoe.mirai.message.defaults.Face
|
||||
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.Protocol
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.DataInputStream
|
||||
@ -103,15 +108,15 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
|
||||
//println(this.input.goto(110 + fontLength).readNBytesAt(2).toUHexString())//always 00 00
|
||||
|
||||
messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) {
|
||||
19 -> MessageType.NORMAL
|
||||
14 -> MessageType.XML
|
||||
6 -> MessageType.AT
|
||||
0x13 -> MessageType.NORMAL
|
||||
0xE -> MessageType.XML
|
||||
0x06 -> MessageType.AT
|
||||
|
||||
|
||||
1 -> MessageType.PLAIN_TEXT
|
||||
2 -> MessageType.FACE
|
||||
3 -> MessageType.IMAGE
|
||||
25 -> MessageType.ANONYMOUS
|
||||
0x01 -> MessageType.PLAIN_TEXT
|
||||
0x02 -> MessageType.FACE
|
||||
0x03 -> MessageType.IMAGE
|
||||
0x19 -> MessageType.ANONYMOUS
|
||||
|
||||
else -> {
|
||||
MiraiLogger debug ("ServerGroupMessageEventPacket id=$id")
|
||||
@ -185,23 +190,103 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
override fun decode() {
|
||||
//start at Sep1.0:27
|
||||
input.goto(0)
|
||||
println()
|
||||
println(input.readAllBytes().toUHexString())
|
||||
input.goto(0)
|
||||
|
||||
qq = input.readIntAt(0).toLong()
|
||||
val msgLength = input.readShortAt(22)
|
||||
val fontLength = input.readShortAt(93 + msgLength)
|
||||
val offset = msgLength + fontLength
|
||||
qq = input.readUIntAt(0).toLong()
|
||||
|
||||
val l1 = input.readShortAt(22)
|
||||
input.goto(93 + l1)
|
||||
val l2 = input.readShort()
|
||||
input.readNBytes(l2)//font
|
||||
input.skip(2)//2个0x00
|
||||
message = input.readSections()
|
||||
println(message.toDebugString())
|
||||
|
||||
/*
|
||||
val offset = unknownLength0 + fontLength//57
|
||||
message = MessageChain(PlainText(let {
|
||||
val offset2 = input.readShortAt(101 + offset)
|
||||
input.goto(103 + offset).readVarString(offset2.toInt())
|
||||
}))
|
||||
val length = input.readShortAt(101 + offset)//
|
||||
input.goto(103 + offset).readString(length.toInt())
|
||||
}))*/
|
||||
}
|
||||
|
||||
private fun DataInputStream.readSection(): Message? {
|
||||
val messageType = this.readByte().toInt()
|
||||
val sectionLength = this.readShort().toLong()//sectionLength: short
|
||||
this.skip(1)//message和face是 0x01, image是0x06
|
||||
return when (messageType) {
|
||||
0x01 -> PlainText(readShortVarString())
|
||||
0x02 -> {
|
||||
//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
|
||||
|
||||
val id1 = FaceID.ofId(readShortVarNumber().toInt())//可能这个是id, 也可能下面那个
|
||||
this.skip(this.readByte().toLong())
|
||||
val id2 = this.readShortVarNumber()//某id?
|
||||
return Face(id1)
|
||||
}
|
||||
0x06 -> {
|
||||
this.skip(sectionLength - 37 - 1)
|
||||
val imageId = String(this.readNBytes(36))
|
||||
this.skip(1)//0x41
|
||||
return Image(imageId)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun DataInputStream.readSections(): MessageChain {
|
||||
val chain = MessageChain()
|
||||
var got: Message? = null
|
||||
do {
|
||||
if (got != null) {
|
||||
chain.concat(got)
|
||||
}
|
||||
got = this.readSection()
|
||||
} while (got != null)
|
||||
return chain
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
println(String("16 20 20 39 39 31 30 20 38 38 31 43 42 20 20 20 20 20 20 31 37 36 32 65 42 39 45 32 37 32 31 43 39 36 44 37 39 41 38 32 31 36 45 30 41 44 34 30 42 35 39 35 39 31 38 36 2E 6A 70 67 66 2F 65 64 33 39 30 66 38 34 2D 34 66 38 37 2D 34 36 64 63 2D 62 33 38 35 2D 34 35 35 36 62 35 31 30 61 61 35 33 41".replace(" ", " ").hexToBytes()))
|
||||
println(".jpg".toByteArray().size)
|
||||
}
|
||||
/*
|
||||
|
||||
牛逼 (10404
|
||||
3E 03 3F A2 8F 00 1A E5 00 0B 53 3B 64 6B 91 17 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 40 5D 73 AF A1 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 AF A1 1F EE 24 55 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
|
||||
|
||||
牛逼 (10404
|
||||
3E 03 3F A2 8F 00 1A E5 00 00 86 F3 09 18 83 47 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 41 5D 73 B3 21 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 B3 20 94 B0 82 BC 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
|
||||
|
||||
牛逼 (19947
|
||||
76 E4 B8 DD 8F 00 1A E5 00 0D A2 8A 0A 65 7C D0 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 76 E4 B8 DD 8F 00 1A E5 4E 35 88 98 FE 64 7C E9 33 F7 2F B1 32 5D 5F A9 00 0B 77 FC 5D 73 B4 38 02 5B 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 B4 38 A6 60 C7 9A 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 0E 00 07 01 00 04 00 00 00 00
|
||||
|
||||
牛逼 (jiahua
|
||||
B1 89 BE 09 8F 00 1A E5 00 0D EB CB 09 90 BA CF 1F 40 00 A6 00 00 00 20 00 05 00 02 00 01 00 06 00 04 00 01 05 0F 00 09 00 06 03 E9 20 02 E5 B3 00 0A 00 04 01 00 00 00 25 15 B1 89 BE 09 8F 00 1A E5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B 77 A3 5D 73 B4 7D 00 00 5D 73 B4 7D 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 73 B4 7D 0E A3 93 E3 00 00 00 00 09 00 86 00 00 09 48 65 6C 76 65 74 69 63 61 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 0E 01 00 04 00 00 00 00 0A 00 04 00 00 00 00 19 00 1C 01 00 19 AA 02 16 08 00 88 01 00 9A 01 0E 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00
|
||||
|
||||
牛逼 (jiahua
|
||||
B1 89 BE 09 8F 00 1A E5 00 0B 03 A2 09 90 BB 7A 1F 40 00 A6 00 00 00 20 00 05 00 02 00 01 00 06 00 04 00 01 05 0F 00 09 00 06 03 E9 20 02 E5 B3 00 0A 00 04 01 00 00 00 25 15 B1 89 BE 09 8F 00 1A E5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B 77 A5 5D 73 B6 33 00 00 5D 73 B6 33 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 73 B6 33 22 DE A7 56 00 00 00 00 09 00 86 00 00 09 48 65 6C 76 65 74 69 63 61 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 0E 01 00 04 00 00 00 00 0A 00 04 00 00 00 00 19 00 1C 01 00 19 AA 02 16 08 00 88 01 00 9A 01 0E 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00
|
||||
|
||||
牛逼[EMOJI表情1]牛逼 (10404
|
||||
3E 03 3F A2 8F 00 1A E5 00 0B 59 A3 64 6B 91 17 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 44 5D 73 BA D9 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 BA D9 12 C7 FC CD 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 02 00 14 01 00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
|
||||
|
||||
牛逼[EMOJI表情2]牛逼 (10404
|
||||
3E 03 3F A2 8F 00 1A E5 00 0D 4D 4A 09 18 83 47 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 45 5D 73 BF A0 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 BF A0 68 31 43 A2 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 09 01 00 06 E7 89 9B E9 80 BC 02 00 14 01 00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
|
||||
|
||||
牛逼[EMOJI表情1]牛逼 (10404
|
||||
3E 03 3F A2 8F 00 1A E5 00 02 3C 8E 64 6B 91 17 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 47 5D 73 C3 76 01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00 5D 73 C3 75 41 3B 97 72 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 0F 01 00 0C E7 89 9B E9 80 BC E7 89 9B E9 80 BC 02 00 14 01 00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D 01 00 09 01 00 06 E7 89 9B E9 80 BC 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
|
||||
|
||||
[图片] (10404
|
||||
3E 03 3F A2 8F 00 1A E5 00 0E 02 CF 64 6B A0 0C 1F 40 00 A6 00 00 00 2D 00 05 00 02 00 01 00 06 00 04 00 01 2E 01 00 09 00 06 00 01 00 00 00 01 00 0A 00 04 01 00 00 00 00 01 00 04 00 00 00 00 00 03 00 01 01 38 03 3E 03 3F A2 8F 00 1A E5 3B DF D8 CE 2B 2E 96 D0 12 CF 0D 44 CF C9 22 A0 00 0B 32 4B 5D 73 D1 1C 01 1D 00 00 00 00 01 00 00 00 0C 4D 53 47 00 00 00 00 00 5D 73 D1 1C F5 78 37 16 00 00 00 00 0C 00 86 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 06 00 F0 02 00 1B 28 5A 53 41 58 40 57 4B 52 4A 5A 31 7E 33 59 4F 53 53 4C 4D 32 4B 49 2E 6A 70 67 03 00 04 00 00 06 E2 04 00 25 2F 65 64 33 39 30 66 38 34 2D 34 66 38 37 2D 34 36 64 63 2D 62 33 38 35 2D 34 35 35 36 62 35 31 30 61 61 35 33 14 00 04 03 00 00 00 18 00 25 2F 65 64 33 39 30 66 38 34 2D 34 66 38 37 2D 34 36 64 63 2D 62 33 38 35 2D 34 35 35 36 62 35 31 30 61 61 35 33 19 00 04 00 00 00 38 1A 00 04 00 00 00 34 FF 00 63 16 20 20 39 39 31 30 20 38 38 31 43 42 20 20 20 20 20 20 31 37 36 32 65 42 39 45 32 37 32 31 43 39 36 44 37 39 41 38 32 31 36 45 30 41 44 34 30 42 35 39 35 39 31 38 36 2E 6A 70 67 66 2F 65 64 33 39 30 66 38 34 2D 34 66 38 37 2D 34 36 64 63 2D 62 33 38 35 2D 34 35 35 36 62 35 31 30 61 61 35 33 41 0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 告知服务器已经收到数据
|
||||
@ -257,7 +342,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
||||
//.gif
|
||||
}else {
|
||||
val offset2 = input.readShortAt(101 + offset)
|
||||
input.goto(103 + offset).readVarString(offset2.toInt())
|
||||
input.goto(103 + offset).readString(offset2.toInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,10 +5,7 @@ import net.mamoe.mirai.network.packet.PacketNameFormatter.adjustName
|
||||
import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
|
||||
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
|
||||
import net.mamoe.mirai.network.packet.login.*
|
||||
import net.mamoe.mirai.utils.TEA
|
||||
import net.mamoe.mirai.utils.getAllDeclaredFields
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
import net.mamoe.mirai.utils.*
|
||||
import java.io.DataInputStream
|
||||
|
||||
/**
|
||||
@ -66,7 +63,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
|
||||
}
|
||||
|
||||
return ServerLoginResponseFailedPacket(when (bytes.size) {
|
||||
319, 135 -> LoginState.WRONG_PASSWORD
|
||||
63, 319, 135, 351 -> LoginState.WRONG_PASSWORD
|
||||
//135 -> LoginState.RETYPE_PASSWORD
|
||||
279 -> LoginState.BLOCKED
|
||||
263 -> LoginState.UNKNOWN_QQ_NUMBER
|
||||
@ -77,7 +74,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
|
||||
/*
|
||||
//unknown
|
||||
63 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)")
|
||||
351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data or Unknown error)")//包数据有误
|
||||
351 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)")
|
||||
|
||||
else -> throw IllegalArgumentException(bytes.size.toString())*/
|
||||
}, stream).apply { this.idHex = idHex }
|
||||
@ -183,7 +180,7 @@ fun DataInputStream.readShortVarString(): String {
|
||||
return String(this.readNBytes(this.readShort().toInt()))
|
||||
}
|
||||
|
||||
fun DataInputStream.readVarString(length: Int): String {
|
||||
fun DataInputStream.readString(length: Int): String {
|
||||
return String(this.readNBytes(length))
|
||||
}
|
||||
|
||||
@ -208,6 +205,17 @@ fun <N : Number> DataInputStream.readNBytes(length: N): ByteArray {
|
||||
return this.readNBytes(length.toInt())
|
||||
}
|
||||
|
||||
|
||||
fun DataInputStream.readShortVarNumber(): Number {
|
||||
return when (this.readShort().toInt()) {
|
||||
1 -> this.readByte()
|
||||
2 -> this.readShort()
|
||||
4 -> this.readInt()
|
||||
8 -> this.readLong()
|
||||
else -> throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
fun DataInputStream.readNBytesIn(range: IntRange): ByteArray {
|
||||
this.goto(range.first)
|
||||
return this.readNBytes(range.last - range.first + 1)
|
||||
@ -218,6 +226,12 @@ fun <N : Number> DataInputStream.readIntAt(position: N): Int {
|
||||
return this.readInt();
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun <N : Number> DataInputStream.readUIntAt(position: N): UInt {
|
||||
this.goto(position)
|
||||
return this.readNBytes(4).toUInt();
|
||||
}
|
||||
|
||||
fun <N : Number> DataInputStream.readByteAt(position: N): Byte {
|
||||
this.goto(position)
|
||||
return this.readByte();
|
||||
|
@ -35,7 +35,8 @@ class ClientSendFriendMessagePacket(
|
||||
it.writeHex("00 00 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00")
|
||||
it.writeTime()
|
||||
it.writeRandom(4)
|
||||
it.writeHex("00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91")
|
||||
it.writeHex("00 00 00 00 09 00 86")
|
||||
it.writeHex(Protocol.friendMessageConst1)
|
||||
it.writeZero(2)
|
||||
|
||||
if ("[face" in message
|
||||
|
@ -30,7 +30,7 @@ class ClientSendGroupMessagePacket(
|
||||
it.writeHex("00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00")
|
||||
it.writeTime()
|
||||
it.writeRandom(4)
|
||||
it.writeHex("00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91")
|
||||
it.writeHex("Protocol.messageConst1")
|
||||
it.writeZero(2)
|
||||
|
||||
//messages
|
||||
|
@ -101,7 +101,7 @@ private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: I
|
||||
this.writeHex("00 38")//length
|
||||
this.write(token0825)//length
|
||||
this.writeHex("03 0F")//tag
|
||||
this.writeDeviceName(true)//todo 随机
|
||||
this.writeDeviceName(false)
|
||||
|
||||
this.writeHex("00 05 00 06 00 02")
|
||||
this.writeQQ(qq)
|
||||
|
@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.network.packet.ServerPacket
|
||||
import net.mamoe.mirai.network.packet.goto
|
||||
import net.mamoe.mirai.network.packet.readNBytesAt
|
||||
import net.mamoe.mirai.network.packet.readVarString
|
||||
import net.mamoe.mirai.network.packet.readString
|
||||
import net.mamoe.mirai.utils.TestedSuccessfully
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
import java.io.DataInputStream
|
||||
@ -43,7 +43,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
|
||||
this.token88 = this.input.readNBytesAt(189 + msgLength, 136)
|
||||
|
||||
val nickLength = this.input.goto(624 + msgLength).readByte().toInt()
|
||||
this.nickname = this.input.readVarString(nickLength)
|
||||
this.nickname = this.input.readString(nickLength)
|
||||
|
||||
//this.age = this.input.goto(packetDataLength - 28).readShortAt()
|
||||
|
||||
|
@ -55,10 +55,11 @@ fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this)
|
||||
fun String.hexToUBytes(): UByteArray = Protocol.hexToUBytes(this)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun String.hexToShort(): Short = hexToBytes().let { ((it[1].toInt() shl 8) + it[0]).toShort() }
|
||||
fun String.hexToInt(): Int = hexToBytes().toUInt().toInt()
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun String.hexToInt(): Int = hexToBytes().let { ((it[0].toInt() shl 24) + (it[1].toInt() shl 16) + (it[2].toInt() shl 8) + it[3]) }
|
||||
fun ByteArray.toUInt(): UInt =
|
||||
this[0].toUInt().and(255u).shl(24) + this[1].toUInt().and(255u).shl(16) + this[2].toUInt().and(255u).shl(8) + this[3].toUInt().and(255u).shl(0)
|
||||
|
||||
open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) {
|
||||
open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
|
||||
|
@ -50,10 +50,20 @@ public class HexComparator {
|
||||
|
||||
@SuppressWarnings({"unused", "NonAsciiCharacters"})
|
||||
private static class TestConsts {
|
||||
private static final String 牛逼 = UtilsKt.toUHexString("牛逼".getBytes(), " ");
|
||||
private static final String NIU_BI = UtilsKt.toUHexString("牛逼".getBytes(), " ");
|
||||
private static final String _1994701021 = ClientPacketKt.toUHexString(1994701021, " ");
|
||||
private static final String _1040400290 = ClientPacketKt.toUHexString(1040400290, " ");
|
||||
private static final String _580266363 = ClientPacketKt.toUHexString(580266363, " ");
|
||||
|
||||
private static final String _1040400290_ = "3E 03 3F A2";
|
||||
private static final String _1994701021_ = "76 E4 B8 DD";
|
||||
private static final String _jiahua_ = "B1 89 BE 09";
|
||||
|
||||
private static final String SINGLE_PLAIN_MESSAGE_HEAD = "00 00 01 00 09 01";
|
||||
|
||||
private static final String MESSAGE_TAIL_10404 = "0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00".replace(" ", " ");
|
||||
//private static final String MESSAGE_TAIL2_10404 ="".replace(" ", " ");
|
||||
|
||||
}
|
||||
|
||||
private final List<Match> matches = new LinkedList<>();
|
||||
@ -88,7 +98,7 @@ public class HexComparator {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
return new LinkedList<>() {{
|
||||
int index = 0;
|
||||
int index = -1;
|
||||
while ((index = hex.indexOf(constValue, index + 1)) != -1) {
|
||||
add(new IntRange(index / 3, (index + constValue.length()) / 3));
|
||||
}
|
||||
@ -105,18 +115,20 @@ public class HexComparator {
|
||||
}
|
||||
|
||||
private static void buildConstNameChain(int length, ConstMatcher constMatcher, StringBuilder constNameBuilder) {
|
||||
//System.out.println(constMatcher.matches);
|
||||
for (int i = 0; i < length; i++) {
|
||||
constNameBuilder.append(" ");
|
||||
String match = constMatcher.getMatchedConstName(i / 4);
|
||||
if (match != null) {
|
||||
int appendedNameLength = match.length();
|
||||
constNameBuilder.append(match);
|
||||
while (constMatcher.getMatchedConstName(i++ / 4) != null) {
|
||||
if (appendedNameLength-- <= 0) {
|
||||
while (match.equals(constMatcher.getMatchedConstName(i++ / 4))) {
|
||||
if (appendedNameLength-- < 0) {
|
||||
constNameBuilder.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
constNameBuilder.append(" ".repeat(match.length() % 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -281,10 +293,10 @@ public class HexComparator {
|
||||
System.out.println(HexComparator.compare(
|
||||
//mirai
|
||||
|
||||
"2A 22 96 29 7B 00 40 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 EC 21 40 06 18 89 54 BC 00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 0A 01 00 07 E7 89 9B E9 80 BC 21\n"
|
||||
"2A 22 96 29 7B 00 40 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 EC 21 40 06 18 89 54 BC Protocol.messageConst1 00 00 01 00 0A 01 00 07 E7 89 9B E9 80 BC 21\n"
|
||||
,
|
||||
//e
|
||||
"2A 22 96 29 7B 00 3F 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 6B 8E 1A FE 39 0B FC 00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 0A 01 00 07 6D 65 73 73 61 67 65"
|
||||
"2A 22 96 29 7B 00 3F 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 6B 8E 1A FE 39 0B FC Protocol.messageConst1 00 00 01 00 0A 01 00 07 6D 65 73 73 61 67 65"
|
||||
));
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user