mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-23 22:30:47 +08:00
Improved message parsing
This commit is contained in:
parent
c6373ec727
commit
522ac8b839
@ -1,174 +1,167 @@
|
|||||||
package net.mamoe.mirai.message;
|
package net.mamoe.mirai.message
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author LamGC
|
* @author LamGC
|
||||||
* @author Him188moe
|
* @author Him188moe
|
||||||
*/
|
*/
|
||||||
public enum FaceID {
|
@Suppress("EnumEntryName", "unused", "SpellCheckingInspection")
|
||||||
|
enum class FaceID constructor(val id: Int) {
|
||||||
unknown(0xff),
|
unknown(0xff),
|
||||||
|
|
||||||
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 添加更多表情
|
// TODO: 2019/9/1 添加更多表情
|
||||||
|
jingya(0),
|
||||||
|
piezui(1),
|
||||||
|
se(2),
|
||||||
|
fadai(3),
|
||||||
|
deyi(4),
|
||||||
|
liulei(5),
|
||||||
|
haixiu(6),
|
||||||
|
bizui(7),
|
||||||
|
shui(8),
|
||||||
|
daku(9),
|
||||||
|
ganga(10),
|
||||||
|
fanu(11),
|
||||||
|
tiaopi(12),
|
||||||
|
ciya(13),
|
||||||
|
weixiao(14),
|
||||||
|
nanguo(15),
|
||||||
|
ku(16),
|
||||||
|
zhuakuang(18),
|
||||||
|
tu(19),
|
||||||
|
touxiao(20),
|
||||||
|
keai(21),
|
||||||
|
baiyan(22),
|
||||||
|
aoman(23),
|
||||||
|
ji_e(24),
|
||||||
|
kun(25),
|
||||||
|
jingkong(26),
|
||||||
|
liuhan(27),
|
||||||
|
hanxiao(28),
|
||||||
|
dabing(29),
|
||||||
|
fendou(30),
|
||||||
|
zhouma(31),
|
||||||
|
yiwen(32),
|
||||||
|
yun(34),
|
||||||
|
zhemo(35),
|
||||||
|
shuai(36),
|
||||||
|
kulou(37),
|
||||||
|
qiaoda(38),
|
||||||
|
zaijian(39),
|
||||||
|
fadou(41),
|
||||||
|
aiqing(42),
|
||||||
|
tiaotiao(43),
|
||||||
|
zhutou(46),
|
||||||
|
yongbao(49),
|
||||||
|
dan_gao(53),
|
||||||
|
shandian(54),
|
||||||
|
zhadan(55),
|
||||||
|
dao(56),
|
||||||
|
zuqiu(57),
|
||||||
|
bianbian(59),
|
||||||
|
kafei(60),
|
||||||
|
fan(61),
|
||||||
|
meigui(63),
|
||||||
|
diaoxie(64),
|
||||||
|
aixin(66),
|
||||||
|
xinsui(67),
|
||||||
|
liwu(69),
|
||||||
|
taiyang(74),
|
||||||
|
yueliang(75),
|
||||||
|
qiang(76),
|
||||||
|
ruo(77),
|
||||||
|
woshou(78),
|
||||||
|
shengli(79),
|
||||||
|
feiwen(85),
|
||||||
|
naohuo(86),
|
||||||
|
xigua(89),
|
||||||
|
lenghan(96),
|
||||||
|
cahan(97),
|
||||||
|
koubi(98),
|
||||||
|
guzhang(99),
|
||||||
|
qiudale(100),
|
||||||
|
huaixiao(101),
|
||||||
|
zuohengheng(102),
|
||||||
|
youhengheng(103),
|
||||||
|
haqian(104),
|
||||||
|
bishi(105),
|
||||||
|
weiqu(106),
|
||||||
|
kuaikule(107),
|
||||||
|
yinxian(108),
|
||||||
|
qinqin(109),
|
||||||
|
xia(110),
|
||||||
|
kelian(111),
|
||||||
|
caidao(112),
|
||||||
|
pijiu(113),
|
||||||
|
lanqiu(114),
|
||||||
|
pingpang(115),
|
||||||
|
shiai(116),
|
||||||
|
piaochong(117),
|
||||||
|
baoquan(118),
|
||||||
|
gouyin(119),
|
||||||
|
quantou(120),
|
||||||
|
chajin(121),
|
||||||
|
aini(122),
|
||||||
|
bu(123),
|
||||||
|
hao(124),
|
||||||
|
zhuanquan(125),
|
||||||
|
ketou(126),
|
||||||
|
huitou(127),
|
||||||
|
tiaosheng(128),
|
||||||
|
huishou(129),
|
||||||
|
jidong(130),
|
||||||
|
jiewu(131),
|
||||||
|
xianwen(132),
|
||||||
|
zuotaiji(133),
|
||||||
|
youtaiji(134),
|
||||||
|
shuangxi(136),
|
||||||
|
bianpao(137),
|
||||||
|
denglong(138),
|
||||||
|
facai(139),
|
||||||
|
K_ge(140),
|
||||||
|
gouwu(141),
|
||||||
|
youjian(142),
|
||||||
|
shuai_qi(143),
|
||||||
|
hecai(144),
|
||||||
|
qidao(145),
|
||||||
|
baojin(146),
|
||||||
|
bangbangtang(147),
|
||||||
|
he_nai(148),
|
||||||
|
xiamian(149),
|
||||||
|
xiangjiao(150),
|
||||||
|
feiji(151),
|
||||||
|
kaiche(152),
|
||||||
|
gaotiezuochetou(153),
|
||||||
|
chexiang(154),
|
||||||
|
gaotieyouchetou(155),
|
||||||
|
duoyun(156),
|
||||||
|
xiayu(157),
|
||||||
|
chaopiao(158),
|
||||||
|
xiongmao(159),
|
||||||
|
dengpao(160),
|
||||||
|
fengche(161),
|
||||||
|
naozhong(162),
|
||||||
|
dasan(163),
|
||||||
|
caiqiu(164),
|
||||||
|
zuanjie(165),
|
||||||
|
shafa(166),
|
||||||
|
zhijin(167),
|
||||||
|
yao(168),
|
||||||
|
shouqiang(169),
|
||||||
|
qingwa(170);
|
||||||
|
|
||||||
;
|
override fun toString(): String {
|
||||||
|
return "$name($id)"
|
||||||
private final int id;
|
|
||||||
|
|
||||||
FaceID(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
companion object {
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FaceID ofId(int id) {
|
fun ofId(id: Int): FaceID {
|
||||||
for (FaceID value : FaceID.values()) {
|
for (value in values()) {
|
||||||
if (value.id == id) {
|
if (value.id == id) {
|
||||||
return value;
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FaceID.unknown;
|
return unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,11 @@ class Face(val id: FaceID) : Message() {
|
|||||||
override val type: MessageKey = Key
|
override val type: MessageKey = Key
|
||||||
|
|
||||||
override fun toStringImpl(): String {
|
override fun toStringImpl(): String {
|
||||||
return String.format("[face%d]", id.id)
|
return "[face${id.id}]"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toObjectString(): String {
|
||||||
|
return "Face[$id]"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toByteArray(): ByteArray = dataEncode { section ->
|
override fun toByteArray(): ByteArray = dataEncode { section ->
|
||||||
@ -48,7 +52,7 @@ class Face(val id: FaceID) : Message() {
|
|||||||
|
|
||||||
override operator fun contains(sub: String): Boolean = false
|
override operator fun contains(sub: String): Boolean = false
|
||||||
|
|
||||||
internal object PacketHelper {
|
object PacketHelper {
|
||||||
fun ofByteArray(data: ByteArray): Face = dataDecode(data) {
|
fun ofByteArray(data: ByteArray): Face = dataDecode(data) {
|
||||||
//00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0
|
//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
|
//00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D
|
||||||
|
@ -22,7 +22,11 @@ open class Image(val imageId: String) : Message() {
|
|||||||
override val type: MessageKey = Key
|
override val type: MessageKey = Key
|
||||||
|
|
||||||
override fun toStringImpl(): String {
|
override fun toStringImpl(): String {
|
||||||
return imageId
|
return "[$imageId]"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toObjectString(): String {
|
||||||
|
return "Image[$imageId]"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toByteArray(): ByteArray = dataEncode { section ->
|
override fun toByteArray(): ByteArray = dataEncode { section ->
|
||||||
@ -55,7 +59,7 @@ open class Image(val imageId: String) : Message() {
|
|||||||
|
|
||||||
override operator fun contains(sub: String): Boolean = false //No string can be contained in a image
|
override operator fun contains(sub: String): Boolean = false //No string can be contained in a image
|
||||||
|
|
||||||
internal object PacketHelper {
|
object PacketHelper {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ofByteArray0x06(data: ByteArray): Image = dataDecode(data) {
|
fun ofByteArray0x06(data: ByteArray): Image = dataDecode(data) {
|
||||||
it.skip(1)
|
it.skip(1)
|
||||||
|
@ -2,7 +2,12 @@ package net.mamoe.mirai.message.defaults
|
|||||||
|
|
||||||
import net.mamoe.mirai.message.Message
|
import net.mamoe.mirai.message.Message
|
||||||
import net.mamoe.mirai.message.MessageKey
|
import net.mamoe.mirai.message.MessageKey
|
||||||
|
import net.mamoe.mirai.network.protocol.tim.packet.readLVByteArray
|
||||||
|
import net.mamoe.mirai.network.protocol.tim.packet.readNBytes
|
||||||
|
import net.mamoe.mirai.utils.dataDecode
|
||||||
import net.mamoe.mirai.utils.dataEncode
|
import net.mamoe.mirai.utils.dataEncode
|
||||||
|
import net.mamoe.mirai.utils.toUHexString
|
||||||
|
import java.io.DataInputStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
@ -95,4 +100,69 @@ class MessageChain : Message {
|
|||||||
operator fun component1(): Message = this.list[0]
|
operator fun component1(): Message = this.list[0]
|
||||||
operator fun component2(): Message = this.list[1]
|
operator fun component2(): Message = this.list[1]
|
||||||
operator fun component3(): Message = this.list[2]
|
operator fun component3(): Message = this.list[2]
|
||||||
|
|
||||||
|
object PacketHelper {
|
||||||
|
@JvmStatic
|
||||||
|
fun ofByteArray(byteArray: ByteArray): MessageChain = dataDecode(byteArray) {
|
||||||
|
it.readMessageChain()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DataInputStream.readMessage(): Message? {
|
||||||
|
val messageType = this.readByte().toInt()
|
||||||
|
val sectionLength = this.readShort().toLong()//sectionLength: short
|
||||||
|
val sectionData = this.readNBytes(sectionLength)
|
||||||
|
return when (messageType) {
|
||||||
|
0x01 -> PlainText.PacketHelper.ofByteArray(sectionData)
|
||||||
|
0x02 -> Face.PacketHelper.ofByteArray(sectionData)
|
||||||
|
0x03 -> Image.PacketHelper.ofByteArray0x03(sectionData)
|
||||||
|
0x06 -> Image.PacketHelper.ofByteArray0x06(sectionData)
|
||||||
|
|
||||||
|
|
||||||
|
0x19 -> {//长文本
|
||||||
|
val value = readLVByteArray()
|
||||||
|
//todo 未知压缩算法
|
||||||
|
PlainText(String(value))
|
||||||
|
|
||||||
|
// PlainText(String(GZip.uncompress( value)))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
0x14 -> {//长文本
|
||||||
|
val value = readLVByteArray()
|
||||||
|
println(value.size)
|
||||||
|
println(value.toUHexString())
|
||||||
|
//todo 未知压缩算法
|
||||||
|
this.skip(7)//几个TLV
|
||||||
|
return PlainText(String(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
0x0E -> {
|
||||||
|
//null
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
println("未知的messageType=0x${messageType.toByte().toUHexString()}")
|
||||||
|
println("后文=${this.readAllBytes().toUHexString()}")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DataInputStream.readMessageChain(): MessageChain {
|
||||||
|
val chain = MessageChain()
|
||||||
|
var got: Message? = null
|
||||||
|
do {
|
||||||
|
if (got != null) {
|
||||||
|
chain.concat(got)
|
||||||
|
}
|
||||||
|
if (this.available() == 0) {
|
||||||
|
return chain
|
||||||
|
}
|
||||||
|
got = this.readMessage()
|
||||||
|
} while (got != null)
|
||||||
|
return chain
|
||||||
}
|
}
|
@ -38,7 +38,7 @@ class PlainText(private val text: String) : Message() {
|
|||||||
|
|
||||||
override operator fun contains(sub: String): Boolean = this.toString().contains(sub)
|
override operator fun contains(sub: String): Boolean = this.toString().contains(sub)
|
||||||
|
|
||||||
internal object PacketHelper {
|
object PacketHelper {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ofByteArray(data: ByteArray): PlainText = dataDecode(data) {
|
fun ofByteArray(data: ByteArray): PlainText = dataDecode(data) {
|
||||||
it.skip(1)
|
it.skip(1)
|
||||||
|
@ -39,6 +39,7 @@ object TIMProtocol {
|
|||||||
*/
|
*/
|
||||||
const val fixVer2 = "02 00 00 00 01 01 01 00 00 68 20"
|
const val fixVer2 = "02 00 00 00 01 01 01 00 00 68 20"
|
||||||
// 02 38 03 00 CD 48 68 3E 03 3F A2 02 00 00 00
|
// 02 38 03 00 CD 48 68 3E 03 3F A2 02 00 00 00
|
||||||
|
// 02 00 00 00 01 2E 01 00 00 69 35
|
||||||
/**
|
/**
|
||||||
* 0825data1
|
* 0825data1
|
||||||
*/
|
*/
|
||||||
@ -105,6 +106,7 @@ object TIMProtocol {
|
|||||||
* length=15
|
* length=15
|
||||||
*/
|
*/
|
||||||
const val messageConst1 = "00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91"
|
const val messageConst1 = "00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91"
|
||||||
|
// TIM最新 22 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()
|
||||||
|
|
||||||
|
@ -2,11 +2,8 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.network.protocol.tim.packet
|
package net.mamoe.mirai.network.protocol.tim.packet
|
||||||
|
|
||||||
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.readMessageChain
|
||||||
import net.mamoe.mirai.network.protocol.tim.TIMProtocol
|
import net.mamoe.mirai.network.protocol.tim.TIMProtocol
|
||||||
import net.mamoe.mirai.utils.dataDecode
|
import net.mamoe.mirai.utils.dataDecode
|
||||||
import net.mamoe.mirai.utils.hexToBytes
|
import net.mamoe.mirai.utils.hexToBytes
|
||||||
@ -49,7 +46,7 @@ abstract class ServerEventPacket(input: DataInputStream, val packetId: ByteArray
|
|||||||
|
|
||||||
@PacketId("00 17")
|
@PacketId("00 17")
|
||||||
class Encrypted(input: DataInputStream, private val packetId: ByteArray) : ServerPacket(input) {
|
class Encrypted(input: DataInputStream, private val packetId: ByteArray) : ServerPacket(input) {
|
||||||
fun decrypt(sessionKey: ByteArray): Raw = Raw(decryptBy(sessionKey), packetId).setId(this.idHex)
|
fun decrypt(sessionKey: ByteArray): Raw = Raw(this.decryptBy(sessionKey), packetId).setId(this.idHex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +132,7 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
|
|||||||
this.input.goto(108)
|
this.input.goto(108)
|
||||||
this.input.readLVByteArray()
|
this.input.readLVByteArray()
|
||||||
input.skip(2)//2个0x00
|
input.skip(2)//2个0x00
|
||||||
message = input.readSections()
|
message = input.readMessageChain()
|
||||||
|
|
||||||
val map = input.readTLVMap(true)
|
val map = input.readTLVMap(true)
|
||||||
if (map.containsKey(18)) {
|
if (map.containsKey(18)) {
|
||||||
@ -262,7 +259,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
|||||||
input.goto(93 + l1)
|
input.goto(93 + l1)
|
||||||
input.readLVByteArray()//font
|
input.readLVByteArray()//font
|
||||||
input.skip(2)//2个0x00
|
input.skip(2)//2个0x00
|
||||||
message = input.readSections()
|
message = input.readMessageChain()
|
||||||
|
|
||||||
val map: Map<Int, ByteArray> = input.readTLVMap(true).withDefault { byteArrayOf() }
|
val map: Map<Int, ByteArray> = input.readTLVMap(true).withDefault { byteArrayOf() }
|
||||||
println(map.getValue(18))
|
println(map.getValue(18))
|
||||||
@ -278,64 +275,6 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DataInputStream.readSection(): Message? {
|
|
||||||
val messageType = this.readByte().toInt()
|
|
||||||
val sectionLength = this.readShort().toLong()//sectionLength: short
|
|
||||||
val sectionData = this.readNBytes(sectionLength)
|
|
||||||
return when (messageType) {
|
|
||||||
0x01 -> PlainText.PacketHelper.ofByteArray(sectionData)
|
|
||||||
0x02 -> Face.PacketHelper.ofByteArray(sectionData)
|
|
||||||
0x03 -> Image.PacketHelper.ofByteArray0x03(sectionData)
|
|
||||||
0x06 -> Image.PacketHelper.ofByteArray0x06(sectionData)
|
|
||||||
|
|
||||||
|
|
||||||
0x19 -> {//长文本
|
|
||||||
val value = readLVByteArray()
|
|
||||||
//todo 未知压缩算法
|
|
||||||
PlainText(String(value))
|
|
||||||
|
|
||||||
// PlainText(String(GZip.uncompress( value)))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
0x14 -> {//长文本
|
|
||||||
val value = readLVByteArray()
|
|
||||||
println(value.size)
|
|
||||||
println(value.toUHexString())
|
|
||||||
//todo 未知压缩算法
|
|
||||||
this.skip(7)//几个TLV
|
|
||||||
return PlainText(String(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
0x0E -> {
|
|
||||||
//null
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
println("未知的messageType=0x${messageType.toByte().toUHexString()}")
|
|
||||||
println("后文=${this.readAllBytes().toUHexString()}")
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun DataInputStream.readSections(): MessageChain {
|
|
||||||
val chain = MessageChain()
|
|
||||||
var got: Message? = null
|
|
||||||
do {
|
|
||||||
if (got != null) {
|
|
||||||
chain.concat(got)
|
|
||||||
}
|
|
||||||
if (this.available() == 0) {
|
|
||||||
return chain
|
|
||||||
}
|
|
||||||
got = this.readSection()
|
|
||||||
} while (got != null)
|
|
||||||
return chain
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
牛逼 (10404
|
牛逼 (10404
|
||||||
|
@ -34,11 +34,22 @@ class ClientSendFriendMessagePacket(
|
|||||||
writeRandom(2)
|
writeRandom(2)
|
||||||
writeTime()
|
writeTime()
|
||||||
writeHex("00 00" +
|
writeHex("00 00" +
|
||||||
"00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00")
|
"00 00 00 00")
|
||||||
//01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00
|
|
||||||
|
//消息过多要分包发送
|
||||||
|
//如果只有一个
|
||||||
|
writeByte(0x01)
|
||||||
|
writeByte(0)//第几个包
|
||||||
|
writeByte(0)
|
||||||
|
//如果大于一个,
|
||||||
|
//writeByte(0x02)//数量
|
||||||
|
//writeByte(0)//第几个包
|
||||||
|
//writeByte(0x91)//why?
|
||||||
|
|
||||||
|
writeHex("00 01 4D 53 47 00 00 00 00 00")
|
||||||
writeTime()
|
writeTime()
|
||||||
writeRandom(4)
|
writeRandom(4)
|
||||||
writeHex("00 00 00 00 09 00 86")
|
writeHex("00 00 00 00 09 00 86")//TIM最新 0C 00 86
|
||||||
writeHex(TIMProtocol.messageConst1)//... 85 E9 BB 91
|
writeHex(TIMProtocol.messageConst1)//... 85 E9 BB 91
|
||||||
writeZero(2)
|
writeZero(2)
|
||||||
|
|
||||||
@ -56,9 +67,5 @@ class ClientSendFriendMessagePacket(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
|
|
||||||
}
|
|
||||||
@PacketId("00 CD")
|
@PacketId("00 CD")
|
||||||
class ServerSendFriendMessageResponsePacket(input: DataInputStream) : ServerPacket(input)
|
class ServerSendFriendMessageResponsePacket(input: DataInputStream) : ServerPacket(input)
|
@ -69,7 +69,6 @@ fun DataOutputStream.writeVarInt(signedInt: Int) {
|
|||||||
this.writeUVarInt(encodeZigZag32(signedInt))
|
this.writeUVarInt(encodeZigZag32(signedInt))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun DataOutputStream.writeUVarInt(uint: UInt) {
|
fun DataOutputStream.writeUVarInt(uint: UInt) {
|
||||||
return writeUVarInt(uint.toLong())
|
return writeUVarInt(uint.toLong())
|
||||||
|
Loading…
Reference in New Issue
Block a user