github.com/Mrs4s/MiraiGo@v0.0.0-20240226124653-54bdd873e3fe/client/builders.go (about)

     1  package client
     2  
     3  import (
     4  	"crypto/md5"
     5  	"fmt"
     6  	"math/rand"
     7  	"time"
     8  
     9  	"github.com/Mrs4s/MiraiGo/binary"
    10  	"github.com/Mrs4s/MiraiGo/binary/jce"
    11  	"github.com/Mrs4s/MiraiGo/client/internal/network"
    12  	"github.com/Mrs4s/MiraiGo/client/internal/oicq"
    13  	"github.com/Mrs4s/MiraiGo/client/pb"
    14  	"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
    15  	"github.com/Mrs4s/MiraiGo/client/pb/msg"
    16  	"github.com/Mrs4s/MiraiGo/client/pb/oidb"
    17  	"github.com/Mrs4s/MiraiGo/client/pb/profilecard"
    18  	"github.com/Mrs4s/MiraiGo/client/pb/structmsg"
    19  	"github.com/Mrs4s/MiraiGo/internal/proto"
    20  	"github.com/Mrs4s/MiraiGo/internal/tlv"
    21  	"github.com/Mrs4s/MiraiGo/wrapper"
    22  )
    23  
    24  var (
    25  	syncConst1 = rand.Int63()
    26  	syncConst2 = rand.Int63()
    27  )
    28  
    29  func buildCode2DRequestPacket(seq uint32, j uint64, cmd uint16, bodyFunc func(writer *binary.Writer)) []byte {
    30  	return binary.NewWriterF(func(w *binary.Writer) {
    31  		w.WriteByte(2)
    32  		pos := w.FillUInt16()
    33  		w.WriteUInt16(cmd)
    34  		w.Write(make([]byte, 21))
    35  		w.WriteByte(3)
    36  		w.WriteUInt16(0)
    37  		w.WriteUInt16(50) // version
    38  		w.WriteUInt32(seq)
    39  		w.WriteUInt64(j)
    40  		bodyFunc(w)
    41  		w.WriteByte(3)
    42  		w.WriteUInt16At(pos, uint16(w.Len()))
    43  	})
    44  }
    45  
    46  func (c *QQClient) buildLoginPacket() (uint16, []byte) {
    47  	seq := c.nextSeq()
    48  	t := &oicq.TLV{
    49  		Command: 9,
    50  		List: [][]byte{
    51  			tlv.T18(16, uint32(c.Uin)),
    52  			tlv.T1(uint32(c.Uin), c.Device().IpAddress),
    53  			tlv.T106(uint32(c.Uin), 0, c.version().AppId, c.version().SSOVersion, c.PasswordMd5, true, c.Device().Guid, c.Device().TgtgtKey, 0),
    54  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
    55  			tlv.T100(c.version().SSOVersion, c.version().SubAppId, c.version().MainSigMap),
    56  			tlv.T107(0),
    57  			tlv.T142(c.version().ApkId),
    58  			tlv.T144(
    59  				[]byte(c.Device().IMEI),
    60  				c.Device().GenDeviceInfoData(),
    61  				c.Device().OSType,
    62  				c.Device().Version.Release,
    63  				c.Device().SimInfo,
    64  				c.Device().APN,
    65  				false, true, false, tlv.GuidFlag(),
    66  				c.Device().Model,
    67  				c.Device().Guid,
    68  				c.Device().Brand,
    69  				c.Device().TgtgtKey,
    70  			),
    71  			tlv.T145(c.Device().Guid),
    72  			tlv.T147(16, []byte(c.version().SortVersionName), c.version().ApkSign),
    73  			/*
    74  				if (miscBitMap & 0x80) != 0{
    75  					w.Write(tlv.T166(1))
    76  				}
    77  			*/
    78  			tlv.T154(seq),
    79  			tlv.T141(c.Device().SimInfo, c.Device().APN),
    80  			tlv.T8(2052),
    81  			tlv.T511([]string{
    82  				"tenpay.com", "openmobile.qq.com", "docs.qq.com", "connect.qq.com",
    83  				"qzone.qq.com", "vip.qq.com", "gamecenter.qq.com", "qun.qq.com", "game.qq.com",
    84  				"qqweb.qq.com", "office.qq.com", "ti.qq.com", "mail.qq.com", "mma.qq.com",
    85  			}),
    86  			tlv.T187(c.Device().MacAddress),
    87  			tlv.T188(c.Device().AndroidId),
    88  		},
    89  	}
    90  	if len(c.Device().IMSIMd5) != 0 {
    91  		t.Append(tlv.T194(c.Device().IMSIMd5))
    92  	}
    93  	if c.AllowSlider {
    94  		t.Append(tlv.T191(0x82))
    95  	}
    96  	if len(c.Device().WifiBSSID) != 0 && len(c.Device().WifiSSID) != 0 {
    97  		t.Append(tlv.T202(c.Device().WifiBSSID, c.Device().WifiSSID))
    98  	}
    99  	t.Append(
   100  		tlv.T177(c.version().BuildTime, c.version().SdkVersion),
   101  		tlv.T516(),
   102  		tlv.T521(0),
   103  		tlv.T525(tlv.T536([]byte{0x01, 0x00})),
   104  	)
   105  	if wrapper.DandelionEnergy != nil {
   106  		if t544 := tlv.T544v2(uint64(c.Uin), "810_9", 9, c.version().SdkVersion, c.Device().Guid, c.version().SortVersionName, wrapper.DandelionEnergy); t544 != nil {
   107  			t.Append(t544)
   108  		}
   109  	}
   110  	if c.Device().QImei16 != "" {
   111  		t.Append(tlv.T545([]byte(c.Device().QImei16)))
   112  	} else {
   113  		t.Append(tlv.T545([]byte(c.Device().IMEI)))
   114  	}
   115  	req := c.buildOicqRequestPacket(c.Uin, 0x0810, t)
   116  	r := network.Request{
   117  		Type:        network.RequestTypeLogin,
   118  		EncryptType: network.EncryptTypeEmptyKey,
   119  		SequenceID:  int32(seq),
   120  		Uin:         c.Uin,
   121  		CommandName: "wtlogin.login",
   122  		Body:        req,
   123  	}
   124  	return seq, c.transport.PackPacket(&r)
   125  }
   126  
   127  func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
   128  	seq := c.nextSeq()
   129  	req := c.buildOicqRequestPacket(c.Uin, 0x0810, &oicq.TLV{
   130  		Command: 20,
   131  		List: [][]byte{
   132  			tlv.T8(2052),
   133  			tlv.T104(c.sig.T104),
   134  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
   135  			tlv.T401(c.sig.G),
   136  		},
   137  	})
   138  	r := network.Request{
   139  		Type:        network.RequestTypeLogin,
   140  		EncryptType: network.EncryptTypeEmptyKey,
   141  		SequenceID:  int32(seq),
   142  		Uin:         c.Uin,
   143  		CommandName: "wtlogin.login",
   144  		Body:        req,
   145  	}
   146  	return seq, c.transport.PackPacket(&r)
   147  }
   148  
   149  func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (uint16, []byte) {
   150  	// old := c.version()
   151  	// watch := auth.AndroidWatch.Version()
   152  	// c.transport.Version = watch
   153  	seq := c.nextSeq()
   154  	req := oicq.Message{
   155  		Command:          0x0812,
   156  		EncryptionMethod: oicq.EM_ECDH,
   157  		Body: binary.NewWriterF(func(w *binary.Writer) {
   158  			code2dPacket := buildCode2DRequestPacket(0, 0, 0x31, func(w *binary.Writer) {
   159  				w.WriteUInt16(0)  // const
   160  				w.WriteUInt32(16) // app id
   161  				w.WriteUInt64(0)  // const
   162  				w.WriteByte(8)    // const
   163  				w.WriteBytesShort(EmptyBytes)
   164  
   165  				w.WriteUInt16(6)
   166  				w.Write(tlv.T16(c.transport.Version.SSOVersion, 16, c.transport.Version.AppId, c.Device().Guid, []byte(c.transport.Version.ApkId), []byte(c.transport.Version.SortVersionName), c.transport.Version.ApkSign))
   167  				w.Write(tlv.T1B(0, 0, size, margin, 72, ecLevel, 2))
   168  				w.Write(tlv.T1D(c.transport.Version.MiscBitmap))
   169  				w.Write(tlv.T1F(false, c.Device().OSType, []byte("7.1.2"), []byte("China Mobile GSM"), c.Device().APN, 2))
   170  				w.Write(tlv.T33(c.Device().Guid))
   171  				w.Write(tlv.T35(8))
   172  			})
   173  			w.WriteByte(0x0)
   174  			w.WriteUInt16(uint16(len(code2dPacket)) + 4)
   175  			w.WriteUInt32(16)
   176  			w.WriteUInt32(0x72)
   177  			w.WriteHex("000000")
   178  			w.WriteUInt32(uint32(time.Now().Unix()))
   179  			w.Write(code2dPacket)
   180  		}),
   181  	}
   182  	r := network.Request{
   183  		Type:        network.RequestTypeLogin,
   184  		EncryptType: network.EncryptTypeEmptyKey,
   185  		SequenceID:  int32(seq),
   186  		Uin:         0,
   187  		CommandName: "wtlogin.trans_emp",
   188  		Body:        c.oicq.Marshal(&req),
   189  	}
   190  	payload := c.transport.PackPacket(&r)
   191  	// c.transport.Version = old
   192  	return seq, payload
   193  }
   194  
   195  func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
   196  	// old := c.version()
   197  	// c.transport.Version = auth.AndroidWatch.Version()
   198  	seq := c.nextSeq()
   199  	req := oicq.Message{
   200  		Command:          0x0812,
   201  		EncryptionMethod: oicq.EM_ECDH,
   202  		Body: binary.NewWriterF(func(w *binary.Writer) {
   203  			code2dPacket := buildCode2DRequestPacket(1, 0, 0x12, func(w *binary.Writer) {
   204  				w.WriteUInt16(5)  // const
   205  				w.WriteByte(1)    // const
   206  				w.WriteUInt32(8)  // product type
   207  				w.WriteUInt32(16) // app id
   208  				w.WriteBytesShort(sig)
   209  				w.WriteUInt64(0) // const
   210  				w.WriteByte(8)   // const
   211  				w.WriteBytesShort(EmptyBytes)
   212  				w.WriteUInt16(0) // const
   213  			})
   214  			w.WriteByte(0x0)
   215  			w.WriteUInt16(uint16(len(code2dPacket)) + 4)
   216  			w.WriteUInt32(16)
   217  			w.WriteUInt32(0x72)
   218  			w.WriteHex("000000")
   219  			w.WriteUInt32(uint32(time.Now().Unix()))
   220  			w.Write(code2dPacket)
   221  		}),
   222  	}
   223  	r := network.Request{
   224  		Type:        network.RequestTypeLogin,
   225  		EncryptType: network.EncryptTypeEmptyKey,
   226  		SequenceID:  int32(seq),
   227  		Uin:         0,
   228  		CommandName: "wtlogin.trans_emp",
   229  		Body:        c.oicq.Marshal(&req),
   230  	}
   231  	payload := c.transport.PackPacket(&r)
   232  	// c.transport.Version = old
   233  	return seq, payload
   234  }
   235  
   236  func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []byte) {
   237  	seq := c.nextSeq()
   238  	t := &oicq.TLV{
   239  		Command: 9,
   240  		List: [][]byte{
   241  			tlv.T18(16, uint32(c.Uin)),
   242  			tlv.T1(uint32(c.Uin), c.Device().IpAddress),
   243  			tlv.T(0x106, t106),
   244  			// tlv.T106(uint32(c.Uin), 0, c.version.AppId, c.version.SSOVersion, c.PasswordMd5, true, c.device.Guid, c.device.TgtgtKey, 0),
   245  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
   246  			tlv.T100(c.version().SSOVersion, c.version().SubAppId, c.version().MainSigMap),
   247  			tlv.T107(0),
   248  			tlv.T142(c.version().ApkId),
   249  			tlv.T144(
   250  				[]byte(c.Device().IMEI),
   251  				c.Device().GenDeviceInfoData(),
   252  				c.Device().OSType,
   253  				c.Device().Version.Release,
   254  				c.Device().SimInfo,
   255  				c.Device().APN,
   256  				false, true, false, tlv.GuidFlag(),
   257  				c.Device().Model,
   258  				c.Device().Guid,
   259  				c.Device().Brand,
   260  				c.Device().TgtgtKey,
   261  			),
   262  			tlv.T145(c.Device().Guid),
   263  			tlv.T147(16, []byte(c.version().SortVersionName), c.version().ApkSign),
   264  			tlv.T(0x16a, t16a),
   265  			tlv.T154(seq),
   266  			tlv.T141(c.Device().SimInfo, c.Device().APN),
   267  			tlv.T8(2052),
   268  			tlv.T511([]string{
   269  				"tenpay.com", "openmobile.qq.com", "docs.qq.com", "connect.qq.com",
   270  				"qzone.qq.com", "vip.qq.com", "gamecenter.qq.com", "qun.qq.com", "game.qq.com",
   271  				"qqweb.qq.com", "office.qq.com", "ti.qq.com", "mail.qq.com", "mma.qq.com",
   272  			}),
   273  			tlv.T187(c.Device().MacAddress),
   274  			tlv.T188(c.Device().AndroidId),
   275  			tlv.T194(c.Device().IMSIMd5),
   276  			tlv.T191(0x00),
   277  			tlv.T202(c.Device().WifiBSSID, c.Device().WifiSSID),
   278  			tlv.T177(c.version().BuildTime, c.version().SdkVersion),
   279  			tlv.T516(),
   280  			tlv.T521(8),
   281  			// tlv.T525(tlv.T536([]byte{0x01, 0x00})),
   282  			tlv.T(0x318, t318),
   283  		},
   284  	}
   285  	req := c.buildOicqRequestPacket(c.Uin, 0x0810, t)
   286  	r := network.Request{
   287  		Type:        network.RequestTypeLogin,
   288  		EncryptType: network.EncryptTypeEmptyKey,
   289  		SequenceID:  int32(seq),
   290  		Uin:         c.Uin,
   291  		CommandName: "wtlogin.login",
   292  		Body:        req,
   293  	}
   294  	return seq, c.transport.PackPacket(&r)
   295  }
   296  
   297  func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byte) {
   298  	seq := c.nextSeq()
   299  	t := &oicq.TLV{
   300  		Command: 2,
   301  		List: [][]byte{
   302  			tlv.T2(result, sign),
   303  			tlv.T8(2052),
   304  			tlv.T104(c.sig.T104),
   305  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
   306  		},
   307  	}
   308  	if c.sig.T547 != nil {
   309  		t.Append(tlv.T(0x547, c.sig.T547))
   310  	}
   311  	if wrapper.DandelionEnergy != nil {
   312  		if t544 := tlv.T544(uint64(c.Uin), "810_2", 2, c.version().SdkVersion, c.Device().Guid, c.version().SortVersionName, wrapper.DandelionEnergy); t544 != nil {
   313  			t.Append(t544)
   314  		}
   315  	}
   316  	req := c.buildOicqRequestPacket(c.Uin, 0x0810, t)
   317  	r := network.Request{
   318  		Type:        network.RequestTypeLogin,
   319  		EncryptType: network.EncryptTypeEmptyKey,
   320  		SequenceID:  int32(seq),
   321  		Uin:         c.Uin,
   322  		CommandName: "wtlogin.login",
   323  		Body:        req,
   324  	}
   325  	return seq, c.transport.PackPacket(&r)
   326  }
   327  
   328  func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) {
   329  	seq := c.nextSeq()
   330  	req := c.buildOicqRequestPacket(c.Uin, 0x0810, &oicq.TLV{
   331  		Command: 8,
   332  		List: [][]byte{
   333  			tlv.T8(2052),
   334  			tlv.T104(c.sig.T104),
   335  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
   336  			tlv.T174(c.sig.T174),
   337  			tlv.T17A(9),
   338  			tlv.T197(),
   339  		},
   340  	})
   341  	r := network.Request{
   342  		Type:        network.RequestTypeLogin,
   343  		EncryptType: network.EncryptTypeEmptyKey,
   344  		SequenceID:  int32(seq),
   345  		Uin:         c.Uin,
   346  		CommandName: "wtlogin.login",
   347  		Body:        req,
   348  	}
   349  	return seq, c.transport.PackPacket(&r)
   350  }
   351  
   352  func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) {
   353  	seq := c.nextSeq()
   354  	t := &oicq.TLV{
   355  		Command: 7,
   356  		List: [][]byte{
   357  			tlv.T8(2052),
   358  			tlv.T104(c.sig.T104),
   359  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
   360  			tlv.T174(c.sig.T174),
   361  			tlv.T17C(code),
   362  			tlv.T401(c.sig.G),
   363  			tlv.T198(),
   364  		},
   365  	}
   366  	if wrapper.DandelionEnergy != nil {
   367  		if t544 := tlv.T544(uint64(c.Uin), "810_7", 7, c.version().SdkVersion, c.Device().Guid, c.version().SortVersionName, wrapper.DandelionEnergy); t544 != nil {
   368  			t.Append(t544)
   369  		}
   370  	}
   371  	req := c.buildOicqRequestPacket(c.Uin, 0x0810, t)
   372  	r := network.Request{
   373  		Type:        network.RequestTypeLogin,
   374  		EncryptType: network.EncryptTypeEmptyKey,
   375  		SequenceID:  int32(seq),
   376  		Uin:         c.Uin,
   377  		CommandName: "wtlogin.login",
   378  		Body:        req,
   379  	}
   380  	return seq, c.transport.PackPacket(&r)
   381  }
   382  
   383  func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) {
   384  	seq := c.nextSeq()
   385  	t := &oicq.TLV{
   386  		Command: 2,
   387  		List: [][]byte{
   388  			tlv.T193(ticket),
   389  			tlv.T8(2052),
   390  			tlv.T104(c.sig.T104),
   391  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
   392  		},
   393  	}
   394  	if c.sig.T547 != nil {
   395  		t.Append(tlv.T(0x547, c.sig.T547))
   396  	}
   397  	if wrapper.DandelionEnergy != nil {
   398  		if t544 := tlv.T544(uint64(c.Uin), "810_2", 2, c.version().SdkVersion, c.Device().Guid, c.version().SortVersionName, wrapper.DandelionEnergy); t544 != nil {
   399  			t.Append(t544)
   400  		}
   401  	}
   402  	req := c.buildOicqRequestPacket(c.Uin, 0x0810, t)
   403  	r := network.Request{
   404  		Type:        network.RequestTypeLogin,
   405  		EncryptType: network.EncryptTypeEmptyKey,
   406  		SequenceID:  int32(seq),
   407  		Uin:         c.Uin,
   408  		CommandName: "wtlogin.login",
   409  		Body:        req,
   410  	}
   411  	return seq, c.transport.PackPacket(&r)
   412  }
   413  
   414  func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
   415  	seq := c.nextSeq()
   416  	t := &oicq.TLV{
   417  		Command: 15,
   418  		List: [][]byte{
   419  			tlv.T18(16, uint32(c.Uin)),
   420  			tlv.T1(uint32(c.Uin), c.Device().IpAddress),
   421  			tlv.T(0x106, c.sig.EncryptedA1),
   422  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
   423  			tlv.T100(c.version().SSOVersion, 2, c.version().MainSigMap),
   424  			tlv.T107(0),
   425  			tlv.T108(c.sig.Ksid),
   426  			tlv.T144(
   427  				c.Device().AndroidId,
   428  				c.Device().GenDeviceInfoData(),
   429  				c.Device().OSType,
   430  				c.Device().Version.Release,
   431  				c.Device().SimInfo,
   432  				c.Device().APN,
   433  				false, true, false, tlv.GuidFlag(),
   434  				c.Device().Model,
   435  				c.Device().Guid,
   436  				c.Device().Brand,
   437  				c.Device().TgtgtKey,
   438  			),
   439  			tlv.T142(c.version().ApkId),
   440  			tlv.T145(c.Device().Guid),
   441  			tlv.T16A(c.sig.SrmToken),
   442  			tlv.T154(seq),
   443  			tlv.T141(c.Device().SimInfo, c.Device().APN),
   444  			tlv.T8(2052),
   445  			tlv.T511([]string{
   446  				"tenpay.com", "openmobile.qq.com", "docs.qq.com", "connect.qq.com",
   447  				"qzone.qq.com", "vip.qq.com", "qun.qq.com", "game.qq.com", "qqweb.qq.com",
   448  				"office.qq.com", "ti.qq.com", "mail.qq.com", "qzone.com", "mma.qq.com",
   449  			}),
   450  			tlv.T147(16, []byte(c.version().SortVersionName), c.version().ApkSign),
   451  			tlv.T177(c.version().BuildTime, c.version().SdkVersion),
   452  			tlv.T400(c.sig.G, c.Uin, c.Device().Guid, c.sig.Dpwd, 1, 16, c.sig.RandSeed),
   453  			tlv.T187(c.Device().MacAddress),
   454  			tlv.T188(c.Device().AndroidId),
   455  			tlv.T194(c.Device().IMSIMd5),
   456  			tlv.T202(c.Device().WifiBSSID, c.Device().WifiSSID),
   457  			tlv.T516(),
   458  			tlv.T521(0),
   459  			tlv.T525(tlv.T536([]byte{0x01, 0x00})),
   460  		},
   461  	}
   462  
   463  	if wrapper.DandelionEnergy != nil {
   464  		if t544 := tlv.T544v2(uint64(c.Uin), "810_f", 15, c.version().SdkVersion, c.Device().Guid, c.version().SortVersionName, wrapper.DandelionEnergy); t544 != nil {
   465  			t.Append(t544)
   466  		}
   467  	}
   468  
   469  	if c.Device().QImei16 != "" {
   470  		t.Append(tlv.T545([]byte(c.Device().QImei16)))
   471  	} else {
   472  		t.Append(tlv.T545([]byte(c.Device().IMEI)))
   473  	}
   474  	m := oicq.Message{
   475  		Uin:              uint32(c.Uin),
   476  		Command:          0x810,
   477  		EncryptionMethod: oicq.EM_ST,
   478  		Body:             t.Marshal(),
   479  	}
   480  	req := network.Request{
   481  		Type:        network.RequestTypeSimple,
   482  		EncryptType: network.EncryptTypeEmptyKey,
   483  		Uin:         c.Uin,
   484  		SequenceID:  int32(seq),
   485  		CommandName: "wtlogin.exchange_emp",
   486  		Body:        c.oicq.Marshal(&m),
   487  	}
   488  	return seq, c.transport.PackPacket(&req)
   489  }
   490  
   491  func (c *QQClient) buildRequestChangeSigPacket(changeD2 bool) (uint16, []byte) {
   492  	seq := c.nextSeq()
   493  	t := &oicq.TLV{
   494  		Command: 11,
   495  		List: [][]byte{
   496  			tlv.T100(c.version().SSOVersion, 100, c.version().MainSigMap),
   497  			tlv.T10A(c.sig.TGT),
   498  			tlv.T116(c.version().MiscBitmap, c.version().SubSigmap),
   499  			tlv.T108(c.sig.Ksid),
   500  		},
   501  	}
   502  	if !changeD2 {
   503  		t.Command = 10
   504  	}
   505  	var key []byte
   506  	if changeD2 {
   507  		h := md5.Sum(c.sig.D2Key)
   508  		key = h[:]
   509  	} else {
   510  		key = c.sig.TGTKey
   511  	}
   512  	t.Append(
   513  		tlv.T144(
   514  			c.Device().AndroidId,
   515  			c.Device().GenDeviceInfoData(),
   516  			c.Device().OSType,
   517  			c.Device().Version.Release,
   518  			c.Device().SimInfo,
   519  			c.Device().APN,
   520  			false, true, false, tlv.GuidFlag(),
   521  			c.Device().Model,
   522  			c.Device().Guid,
   523  			c.Device().Brand,
   524  			key,
   525  		),
   526  		tlv.T112(c.Uin),
   527  	)
   528  	if changeD2 {
   529  		t.Append(tlv.T143(c.sig.D2))
   530  	} else {
   531  		t.Append(tlv.T145(c.Device().Guid))
   532  	}
   533  	t.Append(
   534  		tlv.T142(c.version().ApkId),
   535  		tlv.T154(seq),
   536  		tlv.T18(16, uint32(c.Uin)),
   537  		tlv.T141(c.Device().SimInfo, c.Device().APN),
   538  		tlv.T8(2052),
   539  		tlv.T147(16, []byte(c.version().SortVersionName), c.version().ApkSign),
   540  		tlv.T177(c.version().BuildTime, c.version().SdkVersion),
   541  		tlv.T187(c.Device().MacAddress),
   542  		tlv.T188(c.Device().AndroidId),
   543  		tlv.T194(c.Device().IMSIMd5),
   544  		tlv.T511([]string{
   545  			"tenpay.com", "openmobile.qq.com", "docs.qq.com", "connect.qq.com",
   546  			"qzone.qq.com", "vip.qq.com", "qun.qq.com", "game.qq.com", "qqweb.qq.com",
   547  			"office.qq.com", "ti.qq.com", "mail.qq.com", "qzone.com", "mma.qq.com",
   548  		}),
   549  		tlv.T202(c.Device().WifiBSSID, c.Device().WifiSSID),
   550  	)
   551  	if wrapper.DandelionEnergy != nil && t.Command == 10 {
   552  		if t544 := tlv.T544v2(uint64(c.Uin), "810_a", 10, c.version().SdkVersion, c.Device().Guid, c.version().SortVersionName, wrapper.DandelionEnergy); t544 != nil {
   553  			t.Append(t544)
   554  		}
   555  	}
   556  	req := c.buildOicqRequestPacket(c.Uin, 0x0810, t)
   557  	req2 := network.Request{
   558  		Type:        network.RequestTypeLogin,
   559  		EncryptType: network.EncryptTypeEmptyKey,
   560  		SequenceID:  int32(seq),
   561  		Uin:         c.Uin,
   562  		CommandName: "wtlogin.exchange_emp",
   563  		Body:        req,
   564  	}
   565  	return seq, c.transport.PackPacket(&req2)
   566  }
   567  
   568  // StatSvc.register
   569  func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
   570  	seq := c.nextSeq()
   571  	svc := &jce.SvcReqRegister{
   572  		ConnType:     0,
   573  		Uin:          c.Uin,
   574  		Bid:          1 | 2 | 4,
   575  		Status:       11,
   576  		KickPC:       0,
   577  		KickWeak:     0,
   578  		IOSVersion:   int64(c.Device().Version.SDK),
   579  		NetType:      1,
   580  		RegType:      0,
   581  		Guid:         c.Device().Guid,
   582  		IsSetStatus:  0,
   583  		LocaleId:     2052,
   584  		DevName:      string(c.Device().Model),
   585  		DevType:      string(c.Device().Model),
   586  		OSVer:        string(c.Device().Version.Release),
   587  		OpenPush:     1,
   588  		LargeSeq:     1551,
   589  		OldSSOIp:     0,
   590  		NewSSOIp:     31806887127679168,
   591  		ChannelNo:    "",
   592  		CPID:         0,
   593  		VendorName:   string(c.Device().VendorName),
   594  		VendorOSName: string(c.Device().VendorOSName),
   595  		B769:         []byte{0x0A, 0x04, 0x08, 0x2E, 0x10, 0x00, 0x0A, 0x05, 0x08, 0x9B, 0x02, 0x10, 0x00},
   596  		SetMute:      0,
   597  	}
   598  	b := append([]byte{0x0A}, svc.ToBytes()...)
   599  	b = append(b, 0x0B)
   600  	buf := &jce.RequestDataVersion3{
   601  		Map: map[string][]byte{"SvcReqRegister": b},
   602  	}
   603  	pkt := &jce.RequestPacket{
   604  		IVersion:     3,
   605  		SServantName: "PushService",
   606  		SFuncName:    "SvcReqRegister",
   607  		SBuffer:      buf.ToBytes(),
   608  		Context:      make(map[string]string),
   609  		Status:       make(map[string]string),
   610  	}
   611  
   612  	r := network.Request{
   613  		Type:        network.RequestTypeLogin,
   614  		EncryptType: network.EncryptTypeD2Key,
   615  		SequenceID:  int32(seq),
   616  		Uin:         c.Uin,
   617  		CommandName: "StatSvc.register",
   618  		Body:        pkt.ToBytes(),
   619  	}
   620  	return seq, c.transport.PackPacket(&r)
   621  }
   622  
   623  func (c *QQClient) buildStatusSetPacket(status, extStatus int32) (uint16, []byte) {
   624  	svc := &jce.SvcReqRegister{
   625  		ConnType:        0,
   626  		Uin:             c.Uin,
   627  		Bid:             7,
   628  		Status:          status,
   629  		KickPC:          0,
   630  		KickWeak:        0,
   631  		Timestamp:       time.Now().Unix(),
   632  		IOSVersion:      int64(c.Device().Version.SDK),
   633  		NetType:         1,
   634  		RegType:         0,
   635  		Guid:            c.Device().Guid,
   636  		IsSetStatus:     1,
   637  		LocaleId:        2052,
   638  		DevName:         string(c.Device().Model),
   639  		DevType:         string(c.Device().Model),
   640  		OSVer:           string(c.Device().Version.Release),
   641  		OpenPush:        1,
   642  		LargeSeq:        1551,
   643  		ExtOnlineStatus: int64(extStatus),
   644  	}
   645  	buf := &jce.RequestDataVersion3{
   646  		Map: map[string][]byte{"SvcReqRegister": packUniRequestData(svc.ToBytes())},
   647  	}
   648  	pkt := &jce.RequestPacket{
   649  		IVersion:     3,
   650  		SServantName: "PushService",
   651  		SFuncName:    "SvcReqRegister",
   652  		SBuffer:      buf.ToBytes(),
   653  		Context:      make(map[string]string),
   654  		Status:       make(map[string]string),
   655  	}
   656  	return c.uniPacket("StatSvc.SetStatusFromClient", pkt.ToBytes())
   657  }
   658  
   659  // ConfigPushSvc.PushResp
   660  func (c *QQClient) buildConfPushRespPacket(t int32, pktSeq int64, jceBuf []byte) (uint16, []byte) {
   661  	req := jce.NewJceWriter()
   662  	req.WriteInt32(t, 1)
   663  	req.WriteInt64(pktSeq, 2)
   664  	req.WriteBytes(jceBuf, 3)
   665  	buf := &jce.RequestDataVersion3{
   666  		Map: map[string][]byte{"PushResp": packUniRequestData(req.Bytes())},
   667  	}
   668  	pkt := &jce.RequestPacket{
   669  		IVersion:     3,
   670  		SServantName: "QQService.ConfigPushSvc.MainServant",
   671  		SFuncName:    "PushResp",
   672  		SBuffer:      buf.ToBytes(),
   673  		Context:      make(map[string]string),
   674  		Status:       make(map[string]string),
   675  	}
   676  	return c.uniPacket("ConfigPushSvc.PushResp", pkt.ToBytes())
   677  }
   678  
   679  // friendlist.getFriendGroupList
   680  func (c *QQClient) buildFriendGroupListRequestPacket(friendStartIndex, friendListCount, groupStartIndex, groupListCount int16) (uint16, []byte) {
   681  	d50, _ := proto.Marshal(&pb.D50ReqBody{
   682  		Appid:                   1002,
   683  		ReqMusicSwitch:          1,
   684  		ReqMutualmarkAlienation: 1,
   685  		ReqKsingSwitch:          1,
   686  		ReqMutualmarkLbsshare:   1,
   687  	})
   688  	req := &jce.FriendListRequest{
   689  		Reqtype: 3,
   690  		IfReflush: func() byte {
   691  			if friendStartIndex <= 0 {
   692  				return 0
   693  			}
   694  			return 1
   695  		}(),
   696  		Uin:         c.Uin,
   697  		StartIndex:  friendStartIndex,
   698  		FriendCount: friendListCount,
   699  		GroupId:     0,
   700  		IfGetGroupInfo: func() byte {
   701  			if groupListCount <= 0 {
   702  				return 0
   703  			}
   704  			return 1
   705  		}(),
   706  		GroupStartIndex: byte(groupStartIndex),
   707  		GroupCount:      byte(groupListCount),
   708  		IfGetMSFGroup:   0,
   709  		IfShowTermType:  1,
   710  		Version:         27,
   711  		UinList:         nil,
   712  		AppType:         0,
   713  		IfGetDOVId:      0,
   714  		IfGetBothFlag:   0,
   715  		D50:             d50,
   716  		D6B:             EmptyBytes,
   717  		SnsTypeList:     []int64{13580, 13581, 13582},
   718  	}
   719  	buf := &jce.RequestDataVersion3{
   720  		Map: map[string][]byte{"FL": packUniRequestData(req.ToBytes())},
   721  	}
   722  	pkt := &jce.RequestPacket{
   723  		IVersion:     3,
   724  		CPacketType:  0x003,
   725  		IRequestId:   1921334514,
   726  		SServantName: "mqq.IMService.FriendListServiceServantObj",
   727  		SFuncName:    "GetFriendListReq",
   728  		SBuffer:      buf.ToBytes(),
   729  		Context:      make(map[string]string),
   730  		Status:       make(map[string]string),
   731  	}
   732  	return c.uniPacket("friendlist.getFriendGroupList", pkt.ToBytes())
   733  }
   734  
   735  // SummaryCard.ReqSummaryCard
   736  func (c *QQClient) buildSummaryCardRequestPacket(target int64) (uint16, []byte) {
   737  	seq := c.nextSeq()
   738  	packBusinessBuf := func(t int32, buf []byte) []byte {
   739  		return binary.NewWriterF(func(w *binary.Writer) {
   740  			comm, _ := proto.Marshal(&profilecard.BusiComm{
   741  				Ver:      proto.Int32(1),
   742  				Seq:      proto.Int32(int32(seq)),
   743  				Fromuin:  proto.Some(c.Uin),
   744  				Touin:    proto.Some(target),
   745  				Service:  proto.Some(t),
   746  				Platform: proto.Int32(2),
   747  				Qqver:    proto.String("8.4.18.4945"),
   748  				Build:    proto.Int32(4945),
   749  			})
   750  			w.WriteByte(40)
   751  			w.WriteUInt32(uint32(len(comm)))
   752  			w.WriteUInt32(uint32(len(buf)))
   753  			w.Write(comm)
   754  			w.Write(buf)
   755  			w.WriteByte(41)
   756  		})
   757  	}
   758  	gate, _ := proto.Marshal(&profilecard.GateVaProfileGateReq{
   759  		UCmd:           proto.Int32(3),
   760  		StPrivilegeReq: &profilecard.GatePrivilegeBaseInfoReq{UReqUin: proto.Some(target)},
   761  		StGiftReq:      &profilecard.GateGetGiftListReq{Uin: proto.Int32(int32(target))},
   762  		StVipCare:      &profilecard.GateGetVipCareReq{Uin: proto.Some(target)},
   763  		OidbFlag: []*profilecard.GateOidbFlagInfo{
   764  			{
   765  				Fieled: proto.Int32(42334),
   766  			},
   767  			{
   768  				Fieled: proto.Int32(42340),
   769  			},
   770  			{
   771  				Fieled: proto.Int32(42344),
   772  			},
   773  			{
   774  				Fieled: proto.Int32(42354),
   775  			},
   776  		},
   777  	})
   778  	/*
   779  		e5b, _ := proto.Marshal(&oidb.DE5BReqBody{
   780  			Uin:                   proto.Uint64(uint64(target)),
   781  			MaxCount:              proto.Uint32(10),
   782  			ReqAchievementContent: proto.Bool(false),
   783  		})
   784  		ec4, _ := proto.Marshal(&oidb.DEC4ReqBody{
   785  			Uin:       proto.Uint64(uint64(target)),
   786  			QuestNum:  proto.Uint64(10),
   787  			FetchType: proto.Uint32(1),
   788  		})
   789  	*/
   790  	req := &jce.SummaryCardReq{
   791  		Uin:              target,
   792  		ComeFrom:         31,
   793  		GetControl:       69181,
   794  		AddFriendSource:  3001,
   795  		SecureSig:        []byte{0x00},
   796  		ReqMedalWallInfo: 0,
   797  		Req0x5ebFieldId:  []int64{27225, 27224, 42122, 42121, 27236, 27238, 42167, 42172, 40324, 42284, 42326, 42325, 42356, 42363, 42361, 42367, 42377, 42425, 42505, 42488},
   798  		ReqServices:      [][]byte{packBusinessBuf(16, gate)},
   799  		ReqNearbyGodInfo: 1,
   800  		ReqExtendCard:    1,
   801  	}
   802  	head := jce.NewJceWriter()
   803  	head.WriteInt32(2, 0)
   804  	buf := &jce.RequestDataVersion3{Map: map[string][]byte{
   805  		"ReqHead":        packUniRequestData(head.Bytes()),
   806  		"ReqSummaryCard": packUniRequestData(req.ToBytes()),
   807  	}}
   808  	pkt := &jce.RequestPacket{
   809  		IVersion:     3,
   810  		SServantName: "SummaryCardServantObj",
   811  		SFuncName:    "ReqSummaryCard",
   812  		SBuffer:      buf.ToBytes(),
   813  		Context:      make(map[string]string),
   814  		Status:       make(map[string]string),
   815  	}
   816  	return seq, c.uniPacketWithSeq(seq, "SummaryCard.ReqSummaryCard", pkt.ToBytes())
   817  }
   818  
   819  // friendlist.delFriend
   820  func (c *QQClient) buildFriendDeletePacket(target int64) (uint16, []byte) {
   821  	req := &jce.DelFriendReq{
   822  		Uin:     c.Uin,
   823  		DelUin:  target,
   824  		DelType: 2,
   825  		Version: 1,
   826  	}
   827  	buf := &jce.RequestDataVersion3{
   828  		Map: map[string][]byte{"DF": packUniRequestData(req.ToBytes())},
   829  	}
   830  	pkt := &jce.RequestPacket{
   831  		IVersion:     3,
   832  		IRequestId:   c.nextPacketSeq(),
   833  		SServantName: "mqq.IMService.FriendListServiceServantObj",
   834  		SFuncName:    "DelFriendReq",
   835  		SBuffer:      buf.ToBytes(),
   836  		Context:      make(map[string]string),
   837  		Status:       make(map[string]string),
   838  	}
   839  	return c.uniPacket("friendlist.delFriend", pkt.ToBytes())
   840  }
   841  
   842  // friendlist.GetTroopListReqV2
   843  func (c *QQClient) buildGroupListRequestPacket(vecCookie []byte) (uint16, []byte) {
   844  	req := &jce.TroopListRequest{
   845  		Uin:              c.Uin,
   846  		GetMSFMsgFlag:    1,
   847  		Cookies:          vecCookie,
   848  		GroupInfo:        []int64{},
   849  		GroupFlagExt:     1,
   850  		Version:          7,
   851  		CompanyId:        0,
   852  		VersionNum:       1,
   853  		GetLongGroupName: 1,
   854  	}
   855  	buf := &jce.RequestDataVersion3{
   856  		Map: map[string][]byte{"GetTroopListReqV2Simplify": packUniRequestData(req.ToBytes())},
   857  	}
   858  	pkt := &jce.RequestPacket{
   859  		IVersion:     3,
   860  		CPacketType:  0x00,
   861  		IRequestId:   c.nextPacketSeq(),
   862  		SServantName: "mqq.IMService.FriendListServiceServantObj",
   863  		SFuncName:    "GetTroopListReqV2Simplify",
   864  		SBuffer:      buf.ToBytes(),
   865  		Context:      make(map[string]string),
   866  		Status:       make(map[string]string),
   867  	}
   868  	return c.uniPacket("friendlist.GetTroopListReqV2", pkt.ToBytes())
   869  }
   870  
   871  // friendlist.GetTroopMemberListReq
   872  func (c *QQClient) buildGroupMemberListRequestPacket(groupUin, groupCode, nextUin int64) (uint16, []byte) {
   873  	req := &jce.TroopMemberListRequest{
   874  		Uin:       c.Uin,
   875  		GroupCode: groupCode,
   876  		NextUin:   nextUin,
   877  		GroupUin:  groupUin,
   878  		Version:   2,
   879  	}
   880  	b := append([]byte{0x0A}, req.ToBytes()...)
   881  	b = append(b, 0x0B)
   882  	buf := &jce.RequestDataVersion3{
   883  		Map: map[string][]byte{"GTML": b},
   884  	}
   885  	pkt := &jce.RequestPacket{
   886  		IVersion:     3,
   887  		IRequestId:   c.nextPacketSeq(),
   888  		SServantName: "mqq.IMService.FriendListServiceServantObj",
   889  		SFuncName:    "GetTroopMemberListReq",
   890  		SBuffer:      buf.ToBytes(),
   891  		Context:      make(map[string]string),
   892  		Status:       make(map[string]string),
   893  	}
   894  	return c.uniPacket("friendlist.GetTroopMemberListReq", pkt.ToBytes())
   895  }
   896  
   897  // group_member_card.get_group_member_card_info
   898  func (c *QQClient) buildGroupMemberInfoRequestPacket(groupCode, uin int64) (uint16, []byte) {
   899  	req := &pb.GroupMemberReqBody{
   900  		GroupCode:       groupCode,
   901  		Uin:             uin,
   902  		NewClient:       true,
   903  		ClientType:      1,
   904  		RichCardNameVer: 1,
   905  	}
   906  	payload, _ := proto.Marshal(req)
   907  	return c.uniPacket("group_member_card.get_group_member_card_info", payload)
   908  }
   909  
   910  // MessageSvc.PbGetMsg
   911  func (c *QQClient) buildGetMessageRequestPacket(flag msg.SyncFlag, msgTime int64) (uint16, []byte) {
   912  	cook := c.sig.SyncCookie
   913  	if cook == nil {
   914  		cook, _ = proto.Marshal(&msg.SyncCookie{
   915  			Time:   proto.Some(msgTime),
   916  			Ran1:   proto.Int64(758330138),
   917  			Ran2:   proto.Int64(2480149246),
   918  			Const1: proto.Int64(1167238020),
   919  			Const2: proto.Int64(3913056418),
   920  			Const3: proto.Int64(0x1D),
   921  		})
   922  	}
   923  	req := &msg.GetMessageRequest{
   924  		SyncFlag:           proto.Some(flag),
   925  		SyncCookie:         cook,
   926  		LatestRambleNumber: proto.Int32(20),
   927  		OtherRambleNumber:  proto.Int32(3),
   928  		OnlineSyncFlag:     proto.Int32(1),
   929  		ContextFlag:        proto.Int32(1),
   930  		MsgReqType:         proto.Int32(1),
   931  		PubaccountCookie:   EmptyBytes,
   932  		MsgCtrlBuf:         EmptyBytes,
   933  		ServerBuf:          EmptyBytes,
   934  	}
   935  	payload, _ := proto.Marshal(req)
   936  	return c.uniPacket("MessageSvc.PbGetMsg", payload)
   937  }
   938  
   939  // MessageSvc.PbDeleteMsg
   940  func (c *QQClient) buildDeleteMessageRequestPacket(msg []*pb.MessageItem) (uint16, []byte) {
   941  	req := &pb.DeleteMessageRequest{Items: msg}
   942  	payload, _ := proto.Marshal(req)
   943  	return c.uniPacket("MessageSvc.PbDeleteMsg", payload)
   944  }
   945  
   946  // OnlinePush.RespPush
   947  func (c *QQClient) buildDeleteOnlinePushPacket(uin int64, svrip int32, pushToken []byte, seq uint16, delMsg []jce.PushMessageInfo) []byte {
   948  	req := &jce.SvcRespPushMsg{Uin: uin, Svrip: svrip, PushToken: pushToken, DelInfos: []jce.IJceStruct{}}
   949  	for _, m := range delMsg {
   950  		req.DelInfos = append(req.DelInfos, &jce.DelMsgInfo{
   951  			FromUin:    m.FromUin,
   952  			MsgSeq:     m.MsgSeq,
   953  			MsgCookies: m.MsgCookies,
   954  			MsgTime:    m.MsgTime,
   955  		})
   956  	}
   957  	b := packUniRequestData(req.ToBytes())
   958  	buf := &jce.RequestDataVersion3{
   959  		Map: map[string][]byte{"resp": b},
   960  	}
   961  	pkt := &jce.RequestPacket{
   962  		IVersion:     3,
   963  		IRequestId:   int32(seq),
   964  		SServantName: "OnlinePush",
   965  		SFuncName:    "SvcRespPushMsg",
   966  		SBuffer:      buf.ToBytes(),
   967  		Context:      make(map[string]string),
   968  		Status:       make(map[string]string),
   969  	}
   970  	return c.uniPacketWithSeq(seq, "OnlinePush.RespPush", pkt.ToBytes())
   971  }
   972  
   973  // LongConn.OffPicUp
   974  func (c *QQClient) buildOffPicUpPacket(target int64, md5 []byte, size int32) (uint16, []byte) {
   975  	req := &cmd0x352.ReqBody{
   976  		Subcmd: proto.Uint32(1),
   977  		TryupImgReq: []*cmd0x352.D352TryUpImgReq{
   978  			{
   979  				SrcUin:       proto.Uint64(uint64(c.Uin)),
   980  				DstUin:       proto.Uint64(uint64(target)),
   981  				FileMd5:      md5,
   982  				FileSize:     proto.Uint64(uint64(size)),
   983  				FileName:     []byte(fmt.Sprintf("%x.jpg", md5)),
   984  				SrcTerm:      proto.Uint32(5),
   985  				PlatformType: proto.Uint32(9),
   986  				BuType:       proto.Uint32(1),
   987  				PicOriginal:  proto.Bool(true),
   988  				PicType:      proto.Uint32(1000),
   989  				BuildVer:     []byte("8.2.7.4410"),
   990  				FileIndex:    EmptyBytes,
   991  				SrvUpload:    proto.Uint32(1),
   992  				TransferUrl:  EmptyBytes,
   993  			},
   994  		},
   995  	}
   996  	payload, _ := proto.Marshal(req)
   997  	return c.uniPacket("LongConn.OffPicUp", payload)
   998  }
   999  
  1000  // ProfileService.Pb.ReqSystemMsgNew.Friend
  1001  func (c *QQClient) buildSystemMsgNewFriendPacket() (uint16, []byte) {
  1002  	req := &structmsg.ReqSystemMsgNew{
  1003  		MsgNum:    20,
  1004  		Version:   1000,
  1005  		Checktype: 2,
  1006  		Flag: &structmsg.FlagInfo{
  1007  			FrdMsgDiscuss2ManyChat:       1,
  1008  			FrdMsgGetBusiCard:            1,
  1009  			FrdMsgNeedWaitingMsg:         1,
  1010  			FrdMsgUint32NeedAllUnreadMsg: 1,
  1011  			GrpMsgMaskInviteAutoJoin:     1,
  1012  		},
  1013  		FriendMsgTypeFlag: 1,
  1014  	}
  1015  	payload, _ := proto.Marshal(req)
  1016  	return c.uniPacket("ProfileService.Pb.ReqSystemMsgNew.Friend", payload)
  1017  }
  1018  
  1019  // friendlist.ModifyGroupCardReq
  1020  func (c *QQClient) buildEditGroupTagPacket(groupCode, memberUin int64, newTag string) (uint16, []byte) {
  1021  	req := &jce.ModifyGroupCardRequest{
  1022  		GroupCode: groupCode,
  1023  		UinInfo: []jce.IJceStruct{
  1024  			&jce.UinInfo{
  1025  				Uin:  memberUin,
  1026  				Flag: 31,
  1027  				Name: newTag,
  1028  			},
  1029  		},
  1030  	}
  1031  	buf := &jce.RequestDataVersion3{Map: map[string][]byte{"MGCREQ": packUniRequestData(req.ToBytes())}}
  1032  	pkt := &jce.RequestPacket{
  1033  		IVersion:     3,
  1034  		IRequestId:   c.nextPacketSeq(),
  1035  		SServantName: "mqq.IMService.FriendListServiceServantObj",
  1036  		SFuncName:    "ModifyGroupCardReq",
  1037  		SBuffer:      buf.ToBytes(),
  1038  		Context:      map[string]string{},
  1039  		Status:       map[string]string{},
  1040  	}
  1041  	return c.uniPacket("friendlist.ModifyGroupCardReq", pkt.ToBytes())
  1042  }
  1043  
  1044  // OidbSvc.0x8fc_2
  1045  func (c *QQClient) buildEditSpecialTitlePacket(groupCode, memberUin int64, newTitle string) (uint16, []byte) {
  1046  	body := &oidb.D8FCReqBody{
  1047  		GroupCode: proto.Some(groupCode),
  1048  		MemLevelInfo: []*oidb.D8FCMemberInfo{
  1049  			{
  1050  				Uin:                    proto.Some(memberUin),
  1051  				UinName:                []byte(newTitle),
  1052  				SpecialTitle:           []byte(newTitle),
  1053  				SpecialTitleExpireTime: proto.Int32(-1),
  1054  			},
  1055  		},
  1056  	}
  1057  	b, _ := proto.Marshal(body)
  1058  	payload := c.packOIDBPackage(2300, 2, b)
  1059  	return c.uniPacket("OidbSvc.0x8fc_2", payload)
  1060  }
  1061  
  1062  // OidbSvc.0x89a_0
  1063  func (c *QQClient) buildGroupOperationPacket(body *oidb.D89AReqBody) (uint16, []byte) {
  1064  	b, _ := proto.Marshal(body)
  1065  	payload := c.packOIDBPackage(2202, 0, b)
  1066  	return c.uniPacket("OidbSvc.0x89a_0", payload)
  1067  }
  1068  
  1069  // OidbSvc.0x89a_0
  1070  func (c *QQClient) buildGroupNameUpdatePacket(groupCode int64, newName string) (uint16, []byte) {
  1071  	body := &oidb.D89AReqBody{
  1072  		GroupCode: groupCode,
  1073  		StGroupInfo: &oidb.D89AGroupinfo{
  1074  			IngGroupName: []byte(newName),
  1075  		},
  1076  	}
  1077  	return c.buildGroupOperationPacket(body)
  1078  }
  1079  
  1080  // OidbSvc.0x89a_0
  1081  func (c *QQClient) buildGroupMuteAllPacket(groupCode int64, mute bool) (uint16, []byte) {
  1082  	shutUpTime := int32(0)
  1083  	if mute {
  1084  		shutUpTime = 268435455
  1085  	}
  1086  	body := &oidb.D89AReqBody{
  1087  		GroupCode: groupCode,
  1088  		StGroupInfo: &oidb.D89AGroupinfo{
  1089  			ShutupTime: proto.Some(shutUpTime),
  1090  		},
  1091  	}
  1092  	return c.buildGroupOperationPacket(body)
  1093  }
  1094  
  1095  // OidbSvc.0x8a0_0
  1096  func (c *QQClient) buildGroupKickPacket(groupCode int64, kickMsg string, block bool, memberUins ...int64) (uint16, []byte) {
  1097  	flagBlock := 0
  1098  	if block {
  1099  		flagBlock = 1
  1100  	}
  1101  	msgKickList := make([]*oidb.D8A0KickMemberInfo, 0, len(memberUins))
  1102  	for _, memberUin := range memberUins {
  1103  		msgKickList = append(msgKickList, &oidb.D8A0KickMemberInfo{
  1104  			OptUint32Operate:   5,
  1105  			OptUint64MemberUin: memberUin,
  1106  			OptUint32Flag:      int32(flagBlock),
  1107  		})
  1108  	}
  1109  	body := &oidb.D8A0ReqBody{
  1110  		OptUint64GroupCode: groupCode,
  1111  		MsgKickList:        msgKickList,
  1112  		KickMsg:            []byte(kickMsg),
  1113  	}
  1114  	b, _ := proto.Marshal(body)
  1115  	payload := c.packOIDBPackage(2208, 0, b)
  1116  	return c.uniPacket("OidbSvc.0x8a0_0", payload)
  1117  }
  1118  
  1119  // OidbSvc.0x570_8
  1120  func (c *QQClient) buildGroupMutePacket(groupCode, memberUin int64, time uint32) (uint16, []byte) {
  1121  	b, cl := binary.OpenWriterF(func(w *binary.Writer) {
  1122  		w.WriteUInt32(uint32(groupCode))
  1123  		w.WriteByte(32)
  1124  		w.WriteUInt16(1)
  1125  		w.WriteUInt32(uint32(memberUin))
  1126  		w.WriteUInt32(time)
  1127  	})
  1128  	payload := c.packOIDBPackage(1392, 8, b)
  1129  	cl()
  1130  	return c.uniPacket("OidbSvc.0x570_8", payload)
  1131  }
  1132  
  1133  // OidbSvc.0xed3
  1134  func (c *QQClient) buildGroupPokePacket(groupCode, target int64) (uint16, []byte) {
  1135  	body := &oidb.DED3ReqBody{
  1136  		ToUin:     target,
  1137  		GroupCode: groupCode,
  1138  	}
  1139  	b, _ := proto.Marshal(body)
  1140  	payload := c.packOIDBPackage(3795, 1, b)
  1141  	return c.uniPacket("OidbSvc.0xed3", payload)
  1142  }
  1143  
  1144  // OidbSvc.0xed3
  1145  func (c *QQClient) buildFriendPokePacket(target int64) (uint16, []byte) {
  1146  	body := &oidb.DED3ReqBody{
  1147  		ToUin:  target,
  1148  		AioUin: target,
  1149  	}
  1150  	b, _ := proto.Marshal(body)
  1151  	payload := c.packOIDBPackage(3795, 1, b)
  1152  	return c.uniPacket("OidbSvc.0xed3", payload)
  1153  }
  1154  
  1155  // OidbSvc.0x55c_1
  1156  func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool) (uint16, []byte) {
  1157  	b, cl := binary.OpenWriterF(func(w *binary.Writer) {
  1158  		w.WriteUInt32(uint32(groupCode))
  1159  		w.WriteUInt32(uint32(member))
  1160  		w.WriteBool(flag)
  1161  	})
  1162  	payload := c.packOIDBPackage(1372, 1, b)
  1163  	cl()
  1164  	return c.uniPacket("OidbSvc.0x55c_1", payload)
  1165  }
  1166  
  1167  // ProfileService.GroupMngReq
  1168  func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) {
  1169  	jw := jce.NewJceWriter()
  1170  	jw.WriteInt32(2, 0)
  1171  	jw.WriteInt64(c.Uin, 1)
  1172  	b, cl := binary.OpenWriterF(func(w *binary.Writer) {
  1173  		w.WriteUInt32(uint32(c.Uin))
  1174  		w.WriteUInt32(uint32(groupCode))
  1175  	})
  1176  	jw.WriteBytes(b, 2)
  1177  	cl()
  1178  	buf := &jce.RequestDataVersion3{Map: map[string][]byte{"GroupMngReq": packUniRequestData(jw.Bytes())}}
  1179  	pkt := &jce.RequestPacket{
  1180  		IVersion:     3,
  1181  		IRequestId:   c.nextPacketSeq(),
  1182  		SServantName: "KQQ.ProfileService.ProfileServantObj",
  1183  		SFuncName:    "GroupMngReq",
  1184  		SBuffer:      buf.ToBytes(),
  1185  		Context:      map[string]string{},
  1186  		Status:       map[string]string{},
  1187  	}
  1188  	return c.uniPacket("ProfileService.GroupMngReq", pkt.ToBytes())
  1189  }
  1190  
  1191  /* this function is unused
  1192  // LightAppSvc.mini_app_info.GetAppInfoById
  1193  func (c *QQClient) buildAppInfoRequestPacket(id string) (uint16, []byte) {
  1194  	seq := c.nextSeq()
  1195  	req := &qweb.GetAppInfoByIdReq{
  1196  		AppId:           id,
  1197  		NeedVersionInfo: 1,
  1198  	}
  1199  	b, _ := proto.Marshal(req)
  1200  	body := &qweb.QWebReq{
  1201  		Seq:        proto.Int64(1),
  1202  		Qua:        proto.String("V1_AND_SQ_8.4.8_1492_YYB_D"),
  1203  		device: proto.String(c.getWebDeviceInfo()),
  1204  		BusiBuff:   b,
  1205  		TraceId:    proto.String(fmt.Sprintf("%v_%v_%v", c.Uin, time.Now().Format("0102150405"), rand.Int63())),
  1206  	}
  1207  	payload, _ := proto.Marshal(body)
  1208  	packet := packets.BuildUniPacket(c.Uin, seq, "LightAppSvc.mini_app_info.GetAppInfoById", 1, c.SessionId, EmptyBytes, c.sigInfo.d2Key, payload)
  1209  	return seq, packet
  1210  }
  1211  */
  1212  
  1213  func (c *QQClient) buildWordSegmentationPacket(data []byte) (uint16, []byte) {
  1214  	payload := c.packOIDBPackageProto(3449, 1, &oidb.D79ReqBody{
  1215  		Uin:     uint64(c.Uin),
  1216  		Content: data,
  1217  		Qua:     []byte("and_537065262_8.4.5"),
  1218  	})
  1219  	return c.uniPacket("OidbSvc.0xd79", payload)
  1220  }
  1221  
  1222  type ProfileDetailUpdate map[uint16][]byte
  1223  
  1224  func NewProfileDetailUpdate() ProfileDetailUpdate {
  1225  	return map[uint16][]byte{}
  1226  }
  1227  
  1228  func (p ProfileDetailUpdate) Nick(value string) ProfileDetailUpdate {
  1229  	p[20002] = []byte(value)
  1230  	return p
  1231  }
  1232  
  1233  func (p ProfileDetailUpdate) Email(value string) ProfileDetailUpdate {
  1234  	p[20011] = []byte(value)
  1235  	return p
  1236  }
  1237  
  1238  func (p ProfileDetailUpdate) PersonalNote(value string) ProfileDetailUpdate {
  1239  	p[20019] = []byte(value)
  1240  	return p
  1241  }
  1242  
  1243  func (p ProfileDetailUpdate) Company(value string) ProfileDetailUpdate {
  1244  	p[24008] = []byte(value)
  1245  	return p
  1246  }
  1247  
  1248  func (p ProfileDetailUpdate) College(value string) ProfileDetailUpdate {
  1249  	p[20021] = []byte(value)
  1250  	return p
  1251  }
  1252  
  1253  // OidbSvc.0x4ff_9_IMCore
  1254  func (c *QQClient) buildUpdateProfileDetailPacket(profileRecord map[uint16][]byte) (uint16, []byte) {
  1255  	b, cl := binary.OpenWriterF(func(w *binary.Writer) {
  1256  		w.WriteUInt32(uint32(c.Uin))
  1257  		w.WriteByte(0)
  1258  		w.WriteUInt16(uint16(len(profileRecord)))
  1259  		for tag, value := range profileRecord {
  1260  			w.WriteUInt16(tag)
  1261  			w.WriteUInt16(uint16(len(value)))
  1262  			w.Write(value)
  1263  		}
  1264  	})
  1265  	payload := c.packOIDBPackage(1279, 9, b)
  1266  	cl()
  1267  	return c.uniPacket("OidbSvc.0x4ff_9_IMCore", payload)
  1268  }
  1269  
  1270  // OidbSvc.0x568_22
  1271  func (c *QQClient) buildSetGroupAnonymous(groupCode int64, enable bool) (uint16, []byte) {
  1272  	var t byte = 0
  1273  	if enable {
  1274  		t = 1
  1275  	}
  1276  	b, cl := binary.OpenWriterF(func(w *binary.Writer) {
  1277  		w.WriteUInt32(uint32(groupCode))
  1278  		w.WriteByte(t)
  1279  	})
  1280  	payload := c.packOIDBPackage(1384, 22, b)
  1281  	cl()
  1282  	return c.uniPacket("OidbSvc.0x568_22", payload)
  1283  }