coder.go 4.14 KB
Newer Older
hujiebin's avatar
hujiebin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
package common

import (
	"encoding/binary"
	"errors"
	"fmt"
	"hash/crc32"
	"time"
)

const (
	MsgTypeLogin = 1 + iota
	MsgTypeLoginRsp
	MsgTypeHeartBeat
	MsgTypeHeartBeatRsp
	MsgTypeKickUser
	MsgTypeBiz = 7
	MsgTypeBizRsp
)

const (
	MsgTypeMatchSuccess = 100 + iota
	MsgTypeMatchConfirm
	MsgTypeCallReady
	MsgTypeAddTimeGift
	MsgTypeAddTimeFree
)

const (
	MsgTypeRecallWindow             = 109
	MsgTypeVideo                    = 110 // 1v1视频-v1-黄钻
	MsgTypeVideoCallReady           = 111
	MsgTypeLikeEach                 = 112
	MsgTypeLikeMe                   = 113
	MsgTypeDailyInAppDiamond        = 114
	MsgTypeGlobalGiftBanner         = 115 // 礼物横幅
	MsgTypeGlobalGiftBannerRsp      = 116
	MsgTypeLuckyWheel               = 117 //已丢弃
	MsgTypeLuckyWheelBanner         = 118
	MsgTypeDiamondChange            = 119 // Kludge:事实上是通用的钻石变更通知了
	MsgTypeConfigChange             = 120 // 配置变更通知
	MsgTypeGlobalRocketNotice       = 121 // 火箭全局横幅
	MsgTypeGroupChatNotice          = 122 // 群发消息弹窗
	MsgTypeGlobalBroadcast          = 123 // 群发消息弹窗
	MsgMicTaskFinish                = 124 // 麦上任务完成
	MsgFruitMachine                 = 125 // 水果机开奖
	MsgTypeNobleChange              = 126 // 贵族变更
	MsgTypeJoinGroup                = 127 // 加入群组成功
	MsgTypeVideoTimeMinuteSuccess   = 128 // 1对1视频加时成功
	MsgTypeVideoTimeMinuteCheck     = 129 // 1对1视频加时检查
	MsgTypeVideoMiss                = 130 // 1对1视频错过
	MsgTypeRoomGroupActivity        = 131 // 进房,群组活动推送
	MsgTypeVideoV2                  = 132 // 1v1视频-v2-粉钻
	MsgTypeVideoV2TimeMinuteCheck   = 133 // 1v1视频-v2-加时检查
	MsgTypeVideoV2CallReady         = 134 // 1v1视频-v2-callReady
	MsgTypeVideoV2TimeMinuteSuccess = 135 // 1v1视频-v2-加时成功
	MsgTypeMatchV2Success           = 140 // 匹配-v2-成功
	MsgTypeMatchV2Confirm           = 141 // 匹配-v2-确认
	MsgTypeMatchV2CallReady         = 142 // 匹配-v2-callReady
	MsgTypeMatchV2AddTimeGift       = 143 // 匹配-v2-送礼加时长
)

const (
	RoomBannerChange  = 1 // 房间banner变更
	GiftConfigChange  = 2 // 礼物配置变更
	OpenScreenChange  = 3 // 开屏配置变更
	MatchConfigChange = 4 // 匹配配置发生了变化
)

func EncodeMessage(msgType uint32, serialNum uint64, userdata []byte) []byte {
	msg := make([]byte, 26)
	dataLen := len(userdata)
	binary.BigEndian.PutUint16(msg, 1)
	binary.BigEndian.PutUint32(msg[2:], msgType)
	binary.BigEndian.PutUint64(msg[6:], serialNum)
	binary.BigEndian.PutUint64(msg[14:], uint64(time.Now().UnixNano()/1000))
	binary.BigEndian.PutUint32(msg[22:], uint32(dataLen))

	msg = append(msg, userdata...)

	checkSum := crc32.ChecksumIEEE(msg)
	msg = append(msg, 0, 0, 0, 0)
	binary.BigEndian.PutUint32(msg[26+dataLen:], checkSum)
	return msg
}

func DecodeMessage(message []byte) (uint32, uint64, uint64, []byte, error) {
	length := len(message)

	// 保证消息至少有26bytes
	if length >= 26 {
		//version := binary.BigEndian.Uint16(message[0:2])
		msgType := binary.BigEndian.Uint32(message[2:6])
		msgId := binary.BigEndian.Uint64(message[6:14])
		timeStamp := binary.BigEndian.Uint64(message[14:22])
		dataLen := binary.BigEndian.Uint32(message[22:26])
		//log.Printf("DecodeMessage version = %d, msgType = %d, msgId = %d, timeStamp = %d, dataLen = %d\n", version, msgType, msgId, timeStamp, dataLen)

		// 保证ws消息至少有msgLen长
		if uint32(length) >= dataLen+30 {
			pbData := message[26 : dataLen+26]
			checksum := binary.BigEndian.Uint32(message[dataLen+26 : dataLen+30])

			//fmt.Printf("pbData size = %d, checksum = %d\n", len(pbData), checksum)
			myCheckSum := crc32.ChecksumIEEE(message[0 : dataLen+26])
			if checksum != myCheckSum {
				return 0, msgId, timeStamp, nil, errors.New("checksum error")
			}

			return msgType, msgId, timeStamp, pbData, nil
		} else {
			fmt.Printf("payload too short length = %d, msgType = %d\n", length, msgType)
			return 0, msgId, timeStamp, nil, errors.New("payload too short")
		}
	} else {
		fmt.Printf("message too short for header %d\n ", length)
		return 0, 0, 0, nil, errors.New("message too short")
	}
}