Commit 9fda59af authored by Him188moe's avatar Him188moe

Message analysis

parent 21a0df80
...@@ -4,8 +4,147 @@ package net.mamoe.mirai.message; ...@@ -4,8 +4,147 @@ package net.mamoe.mirai.message;
* @author Him188moe * @author Him188moe
*/ */
public enum FaceID { 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 { ...@@ -18,4 +157,15 @@ public enum FaceID {
public int getId() { public int getId() {
return id; 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 { ...@@ -24,6 +24,10 @@ public abstract class Message {
@Override @Override
public abstract String toString(); public abstract String toString();
public String toDebugString() {
return this.getClass().getSimpleName() + String.format("(%s)", this.toString());
}
/** /**
* 把这个消息连接到另一个消息的头部. 相当于字符串相加 * 把这个消息连接到另一个消息的头部. 相当于字符串相加
* <p> * <p>
...@@ -76,4 +80,5 @@ public abstract class Message { ...@@ -76,4 +80,5 @@ public abstract class Message {
this.concat(new At(target)); this.concat(new At(target));
return this; return this;
} }
} }
\ No newline at end of file
...@@ -21,7 +21,10 @@ public final class Face extends Message { ...@@ -21,7 +21,10 @@ public final class Face extends Message {
@Override @Override
public String toString() { public String toString() {
// TODO: 2019/9/1 if (id == null) {
throw new UnsupportedOperationException(); return "[face?]";
}
return String.format("[face%d]", id.getId());
} }
} }
...@@ -11,6 +11,8 @@ import java.net.URL; ...@@ -11,6 +11,8 @@ import java.net.URL;
* @author Him188moe * @author Him188moe
*/ */
public final class Image extends Message { public final class Image extends Message {
private String imageID;
public Image(InputStream inputStream) { public Image(InputStream inputStream) {
} }
...@@ -33,11 +35,11 @@ public final class Image extends Message { ...@@ -33,11 +35,11 @@ public final class Image extends Message {
* @param imageID * @param imageID
*/ */
public Image(String imageID) { public Image(String imageID) {
this.imageID = imageID;
} }
@Override @Override
public String toString() { public String toString() {
return null; return imageID;
} }
} }
...@@ -29,6 +29,10 @@ public final class MessageChain extends Message { ...@@ -29,6 +29,10 @@ public final class MessageChain extends Message {
list.add(message); list.add(message);
} }
public MessageChain() {
}
/** /**
* @return An unmodifiable list * @return An unmodifiable list
*/ */
...@@ -45,6 +49,10 @@ public final class MessageChain extends Message { ...@@ -45,6 +49,10 @@ public final class MessageChain extends Message {
return this.list.stream().map(Message::toString).collect(Collectors.joining("")); 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 @Override
public synchronized Message concat(@NotNull Message tail) { public synchronized Message concat(@NotNull Message tail) {
this.list.add(tail); this.list.add(tail);
......
...@@ -64,6 +64,11 @@ object Protocol { ...@@ -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 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() private val hexToByteArrayCacheMap: MutableMap<Int, ByteArray> = mutableMapOf()
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
......
...@@ -171,11 +171,10 @@ fun DataOutputStream.writeCRC32(key: ByteArray) { ...@@ -171,11 +171,10 @@ fun DataOutputStream.writeCRC32(key: ByteArray) {
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
@TestedSuccessfully @TestedSuccessfully
fun DataOutputStream.writeDeviceName(random: Boolean = false) { fun DataOutputStream.writeDeviceName(random: Boolean = false) {
val deviceName: String val deviceName: String = if (random) {
if (random) { String(getRandomByteArray(10))
deviceName = String(getRandomByteArray(10))
} else { } else {
deviceName = InetAddress.getLocalHost().hostName InetAddress.getLocalHost().hostName
} }
this.writeShort(deviceName.length + 2) this.writeShort(deviceName.length + 2)
this.writeShort(deviceName.length) this.writeShort(deviceName.length)
......
package net.mamoe.mirai.network.packet 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.MessageChain
import net.mamoe.mirai.message.defaults.PlainText import net.mamoe.mirai.message.defaults.PlainText
import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.toUHexString import net.mamoe.mirai.utils.toUHexString
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.DataInputStream import java.io.DataInputStream
...@@ -103,15 +108,15 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray, ...@@ -103,15 +108,15 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
//println(this.input.goto(110 + fontLength).readNBytesAt(2).toUHexString())//always 00 00 //println(this.input.goto(110 + fontLength).readNBytesAt(2).toUHexString())//always 00 00
messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) { messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) {
19 -> MessageType.NORMAL 0x13 -> MessageType.NORMAL
14 -> MessageType.XML 0xE -> MessageType.XML
6 -> MessageType.AT 0x06 -> MessageType.AT
1 -> MessageType.PLAIN_TEXT 0x01 -> MessageType.PLAIN_TEXT
2 -> MessageType.FACE 0x02 -> MessageType.FACE
3 -> MessageType.IMAGE 0x03 -> MessageType.IMAGE
25 -> MessageType.ANONYMOUS 0x19 -> MessageType.ANONYMOUS
else -> { else -> {
MiraiLogger debug ("ServerGroupMessageEventPacket id=$id") MiraiLogger debug ("ServerGroupMessageEventPacket id=$id")
...@@ -185,22 +190,102 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray ...@@ -185,22 +190,102 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
override fun decode() { override fun decode() {
//start at Sep1.0:27
input.goto(0) input.goto(0)
println()
println(input.readAllBytes().toUHexString()) println(input.readAllBytes().toUHexString())
input.goto(0) input.goto(0)
qq = input.readIntAt(0).toLong() qq = input.readUIntAt(0).toLong()
val msgLength = input.readShortAt(22)
val fontLength = input.readShortAt(93 + msgLength) val l1 = input.readShortAt(22)
val offset = msgLength + fontLength 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 { message = MessageChain(PlainText(let {
val offset2 = input.readShortAt(101 + offset) val length = input.readShortAt(101 + offset)//
input.goto(103 + offset).readVarString(offset2.toInt()) 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 ...@@ -257,7 +342,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
//.gif //.gif
}else { }else {
val offset2 = input.readShortAt(101 + offset) 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 ...@@ -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.ServerSendFriendMessageResponsePacket
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
import net.mamoe.mirai.network.packet.login.* import net.mamoe.mirai.network.packet.login.*
import net.mamoe.mirai.utils.TEA import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.getAllDeclaredFields
import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.toUHexString
import java.io.DataInputStream import java.io.DataInputStream
/** /**
...@@ -66,7 +63,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { ...@@ -66,7 +63,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
} }
return ServerLoginResponseFailedPacket(when (bytes.size) { return ServerLoginResponseFailedPacket(when (bytes.size) {
319, 135 -> LoginState.WRONG_PASSWORD 63, 319, 135, 351 -> LoginState.WRONG_PASSWORD
//135 -> LoginState.RETYPE_PASSWORD //135 -> LoginState.RETYPE_PASSWORD
279 -> LoginState.BLOCKED 279 -> LoginState.BLOCKED
263 -> LoginState.UNKNOWN_QQ_NUMBER 263 -> LoginState.UNKNOWN_QQ_NUMBER
...@@ -77,7 +74,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { ...@@ -77,7 +74,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
/* /*
//unknown //unknown
63 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)") 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())*/ else -> throw IllegalArgumentException(bytes.size.toString())*/
}, stream).apply { this.idHex = idHex } }, stream).apply { this.idHex = idHex }
...@@ -183,7 +180,7 @@ fun DataInputStream.readShortVarString(): String { ...@@ -183,7 +180,7 @@ fun DataInputStream.readShortVarString(): String {
return String(this.readNBytes(this.readShort().toInt())) return String(this.readNBytes(this.readShort().toInt()))
} }
fun DataInputStream.readVarString(length: Int): String { fun DataInputStream.readString(length: Int): String {
return String(this.readNBytes(length)) return String(this.readNBytes(length))
} }
...@@ -208,6 +205,17 @@ fun <N : Number> DataInputStream.readNBytes(length: N): ByteArray { ...@@ -208,6 +205,17 @@ fun <N : Number> DataInputStream.readNBytes(length: N): ByteArray {
return this.readNBytes(length.toInt()) 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 { fun DataInputStream.readNBytesIn(range: IntRange): ByteArray {
this.goto(range.first) this.goto(range.first)
return this.readNBytes(range.last - range.first + 1) return this.readNBytes(range.last - range.first + 1)
...@@ -218,6 +226,12 @@ fun <N : Number> DataInputStream.readIntAt(position: N): Int { ...@@ -218,6 +226,12 @@ fun <N : Number> DataInputStream.readIntAt(position: N): Int {
return this.readInt(); 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 { fun <N : Number> DataInputStream.readByteAt(position: N): Byte {
this.goto(position) this.goto(position)
return this.readByte(); return this.readByte();
......
...@@ -35,7 +35,8 @@ class ClientSendFriendMessagePacket( ...@@ -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.writeHex("00 00 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00")
it.writeTime() it.writeTime()
it.writeRandom(4) 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) it.writeZero(2)
if ("[face" in message if ("[face" in message
......
...@@ -30,7 +30,7 @@ class ClientSendGroupMessagePacket( ...@@ -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.writeHex("00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00")
it.writeTime() it.writeTime()
it.writeRandom(4) 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) it.writeZero(2)
//messages //messages
......
...@@ -101,7 +101,7 @@ private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: I ...@@ -101,7 +101,7 @@ private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: I
this.writeHex("00 38")//length this.writeHex("00 38")//length
this.write(token0825)//length this.write(token0825)//length
this.writeHex("03 0F")//tag this.writeHex("03 0F")//tag
this.writeDeviceName(true)//todo 随机 this.writeDeviceName(false)
this.writeHex("00 05 00 06 00 02") this.writeHex("00 05 00 06 00 02")
this.writeQQ(qq) this.writeQQ(qq)
......
...@@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol ...@@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.ServerPacket import net.mamoe.mirai.network.packet.ServerPacket
import net.mamoe.mirai.network.packet.goto import net.mamoe.mirai.network.packet.goto
import net.mamoe.mirai.network.packet.readNBytesAt 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.TestedSuccessfully
import net.mamoe.mirai.utils.toUHexString import net.mamoe.mirai.utils.toUHexString
import java.io.DataInputStream import java.io.DataInputStream
...@@ -43,7 +43,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in ...@@ -43,7 +43,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
this.token88 = this.input.readNBytesAt(189 + msgLength, 136) this.token88 = this.input.readNBytesAt(189 + msgLength, 136)
val nickLength = this.input.goto(624 + msgLength).readByte().toInt() 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() //this.age = this.input.goto(packetDataLength - 28).readShortAt()
......
...@@ -55,10 +55,11 @@ fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this) ...@@ -55,10 +55,11 @@ fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this)
fun String.hexToUBytes(): UByteArray = Protocol.hexToUBytes(this) fun String.hexToUBytes(): UByteArray = Protocol.hexToUBytes(this)
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun String.hexToShort(): Short = hexToBytes().let { ((it[1].toInt() shl 8) + it[0]).toShort() } fun String.hexToInt(): Int = hexToBytes().toUInt().toInt()
@ExperimentalUnsignedTypes @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 class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) {
open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray() open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
......
...@@ -50,10 +50,20 @@ public class HexComparator { ...@@ -50,10 +50,20 @@ public class HexComparator {
@SuppressWarnings({"unused", "NonAsciiCharacters"}) @SuppressWarnings({"unused", "NonAsciiCharacters"})
private static class TestConsts { 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 _1994701021 = ClientPacketKt.toUHexString(1994701021, " ");
private static final String _1040400290 = ClientPacketKt.toUHexString(1040400290, " "); private static final String _1040400290 = ClientPacketKt.toUHexString(1040400290, " ");
private static final String _580266363 = ClientPacketKt.toUHexString(580266363, " "); 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<>(); private final List<Match> matches = new LinkedList<>();
...@@ -88,7 +98,7 @@ public class HexComparator { ...@@ -88,7 +98,7 @@ public class HexComparator {
return new LinkedList<>(); return new LinkedList<>();
} }
return new LinkedList<>() {{ return new LinkedList<>() {{
int index = 0; int index = -1;
while ((index = hex.indexOf(constValue, index + 1)) != -1) { while ((index = hex.indexOf(constValue, index + 1)) != -1) {
add(new IntRange(index / 3, (index + constValue.length()) / 3)); add(new IntRange(index / 3, (index + constValue.length()) / 3));
} }
...@@ -105,18 +115,20 @@ public class HexComparator { ...@@ -105,18 +115,20 @@ public class HexComparator {
} }
private static void buildConstNameChain(int length, ConstMatcher constMatcher, StringBuilder constNameBuilder) { private static void buildConstNameChain(int length, ConstMatcher constMatcher, StringBuilder constNameBuilder) {
//System.out.println(constMatcher.matches);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
constNameBuilder.append(" "); constNameBuilder.append(" ");
String match = constMatcher.getMatchedConstName(i / 4); String match = constMatcher.getMatchedConstName(i / 4);
if (match != null) { if (match != null) {
int appendedNameLength = match.length(); int appendedNameLength = match.length();
constNameBuilder.append(match); constNameBuilder.append(match);
while (constMatcher.getMatchedConstName(i++ / 4) != null) { while (match.equals(constMatcher.getMatchedConstName(i++ / 4))) {
if (appendedNameLength-- <= 0) { if (appendedNameLength-- < 0) {
constNameBuilder.append(" "); constNameBuilder.append(" ");
} }
} }
constNameBuilder.append(" ".repeat(match.length() % 4));
} }
} }
} }
...@@ -281,10 +293,10 @@ public class HexComparator { ...@@ -281,10 +293,10 @@ public class HexComparator {
System.out.println(HexComparator.compare( System.out.println(HexComparator.compare(
//mirai //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 //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"
)); ));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment