package group_m import ( "context" "encoding/json" "git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/resource/redisCli" "git.hilo.cn/hilo-common/rpc" "hilo-group/_const/enum/group_e" "hilo-group/_const/redis_key" "hilo-group/domain/model/noble_m" "hilo-group/domain/model/res_m" "hilo-group/domain/model/user_m" "time" ) //麦位,要发送的麦位信息 type MicSystemMsg struct { GroupUid string //房间ID Source string Target string MsgId group_e.TypeSignalMsg Content string //要发送的内容 } type MicContent struct { //GroupId GroupId string `json:"groupId"` //麦位 I int `json:"i"` //锁,是否有锁 true:锁了, false:没锁 Lock bool `json:"lock"` //个人静音 true:静音,false:没有静音 Forbid bool `json:"forbid"` //麦位静音 true:静音,false:没有静音 MicForbid bool `json:"micForbid"` //如果 空字符串 则代表这个位置上没有人 ExternalId string `json:"externalId"` //声网agoraId 如果 0 则代表这个位置上没有人 AgoraId uint32 `json:"agoraId"` //服务器记录的时间戳 Timestamp int64 `json:"timestamp"` //用户 User *MicUserData `json:"user"` } type MicUserData struct { Id uint64 `json:"id,omitempty"` ExternalId string `json:"externalId"` Avatar string `json:"avatar"` Nick string `json:"nick"` Sex uint8 `json:"sex"` Code string `json:"code"` IsVip bool `json:"isVip"` NobleLeave uint16 `json:"noble"` // 当前的贵族等级 HeadwearPicUrl string `json:"headwearPicUrl"` HeadwearEffectUrl string `json:"headwearEffectUrl"` HeadwearReverseEffectUrl string `json:"headwearReverseEffectUrl"` // 反转svga效果 SvipLevel int `json:"svipLevel"` Svip rpc.CvSvip `json:"svip"` MicEffect string `json:"micEffect"` //mic位置特效svga HeadwearIcon string `json:"headwearIcon"` //头饰里面的小头像 } type MicNumChangeContent struct { MicOn bool `json:"micOn"` MicNumType group_e.GroupMicNumType `json:"micNumType"` Timestamp int64 `json:"timestamp"` } func MicGroupKickOutRPush(model *domain.Model, groupUid string, userExternalId string, beKickExternalId string, beKickuserId uint64) { model.Log.Infof("MicChangeRPush MicGroupKickOutRPush begin groupUuid:%v", groupUid) txGroupId, err := ToTxGroupId(model, groupUid) if err != nil { model.Log.Errorf("MicChangeRPush MicGroupKickOutRPush ToTxGroupId err:%+v, groupUid:%v", err, groupUid) } r := MicNumChangeContent{ Timestamp: time.Now().Unix(), } buf, err := json.Marshal(r) if err != nil { model.Log.Errorf("MicChangeRPush MicGroupKickOutRPush Content json.Marshal err:%+v", err) } str, err := json.Marshal(MicSystemMsg{ GroupUid: txGroupId, Source: userExternalId, Target: beKickExternalId, MsgId: group_e.GroupKickOut, Content: string(buf), }) if err != nil { model.Log.Errorf("MicChangeRPush MicGroupKickOutRPush Marshal MicSystemMsg err:%+v, groupUuid:%v, micContent:%+v", err, groupUid, string(str)) return } // socket通知被拉黑者退房 rpc.SendQuitRoom(beKickuserId, 2, txGroupId) if n, err := redisCli.GetClusterRedis().RPush(context.Background(), redis_key.GetMicInfoChange(), string(str)).Result(); err != nil || n == 0 { model.Log.Errorf("MicChangeRPush MicGroupKickOutRPush err:%+v, groupUuid:%v, micContent:%+v", err, groupUid, string(str)) return } else { model.Log.Infof("MicChangeRPush MicGroupKickOutRPush success groupUuid:%v, micContent:%+v", groupUid, string(str)) } model.Log.Infof("MicChangeRPush MicGroupKickOutRPush end groupUuid:%v, micContent:%v", groupUid, string(str)) } func MicSocketMicOutRPush(model *domain.Model, groupUid string, userExternalId string) { model.Log.Infof("MicChangeRPush MicSocketMicOutRPush begin groupUuid:%v", groupUid) txGroupId, err := ToTxGroupId(model, groupUid) if err != nil { model.Log.Errorf("MicChangeRPush MicSocketMicOutRPush ToTxGroupId err:%+v, groupUid:%v", err, groupUid) } r := MicNumChangeContent{ Timestamp: time.Now().Unix(), } buf, err := json.Marshal(r) if err != nil { model.Log.Errorf("MicChangeRPush MicSocketMicOutRPush Content json.Marshal err:%+v", err) } str, err := json.Marshal(MicSystemMsg{ GroupUid: txGroupId, Source: userExternalId, MsgId: group_e.GroupSocketMicOutSignal, Content: string(buf), }) if err != nil { model.Log.Errorf("MicChangeRPush MicSocketMicOutRPush Marshal MicSystemMsg err:%+v, groupUuid:%v, micContent:%+v", err, groupUid, string(str)) return } if n, err := redisCli.GetClusterRedis().RPush(context.Background(), redis_key.GetMicInfoChange(), string(str)).Result(); err != nil || n == 0 { model.Log.Errorf("MicChangeRPush MicSocketMicOutRPush err:%+v, groupUuid:%v, micContent:%+v", err, groupUid, string(str)) return } else { model.Log.Infof("MicChangeRPush MicSocketMicOutRPush success groupUuid:%v, micContent:%+v", groupUid, string(str)) } model.Log.Infof("MicChangeRPush MicSocketMicOutRPush end groupUuid:%v, micContent:%v", groupUid, string(str)) } func MicNumChangeRPush(model *domain.Model, groupUid string, micNumType group_e.GroupMicNumType, micOn bool) { model.Log.Infof("MicChangeRPush MicNumChangeRPush begin groupUuid:%v, micNumType:%v", groupUid, micNumType) txGroupId, err := ToTxGroupId(model, groupUid) if err != nil { model.Log.Errorf("MicChangeRPush MicNumChangeRPush ToTxGroupId err:%+v, groupUid:%v", err, txGroupId) } r := MicNumChangeContent{ MicOn: micOn, MicNumType: micNumType, Timestamp: time.Now().Unix(), } buf, err := json.Marshal(r) if err != nil { model.Log.Errorf("MicChangeRPush MicNumChangeRPush Content json.Marshal err:%+v", err) } str, err := json.Marshal(MicSystemMsg{ GroupUid: txGroupId, MsgId: group_e.GroupMicChangeSignal, Content: string(buf), }) if err != nil { model.Log.Errorf("MicChangeRPush MicNumChangeRPush Marshal MicSystemMsg err:%+v, groupUuid:%v, micContent:%+v", err, groupUid, string(str)) return } if n, err := redisCli.GetClusterRedis().RPush(context.Background(), redis_key.GetMicInfoChange(), string(str)).Result(); err != nil || n == 0 { model.Log.Errorf("MicChangeRPush MicNumChangeRPush err:%+v, groupUuid:%v, micContent:%+v", err, groupUid, string(str)) return } else { model.Log.Infof("MicChangeRPush MicNumChangeRPush success groupUuid:%v, micContent:%+v", groupUid, string(str)) } model.Log.Infof("MicChangeRPush MicNumChangeRPush end groupUuid:%v, micContent:%v", groupUid, string(str)) } func MicEmptyRPush(model *domain.Model, groupUid string, i int) { model.Log.Infof("MicChangeRPush MicEmptyRPush begin groupUuid:%v, i:%v", groupUid, i) txGroupId, err := ToTxGroupId(model, groupUid) if err != nil { model.Log.Errorf("MicChangeRPush MicEmptyRPush ToTxGroupId err:%+v, groupUid:%v", err, txGroupId) } micContent, err := json.Marshal(MicContent{ GroupId: txGroupId, I: i, Lock: false, Forbid: false, ExternalId: "", AgoraId: 0, Timestamp: time.Now().UnixNano(), User: nil, }) if err != nil { model.Log.Errorf("MicChangeRPush MicEmptyRPush Marshal MicSystemMsg err:%+v, groupUuid:%v, i:%v, micContent:%+v", err, groupUid, i, string(micContent)) return } str, err := json.Marshal(MicSystemMsg{ GroupUid: txGroupId, MsgId: group_e.GroupMicChange, Content: string(micContent), }) if err != nil { model.Log.Errorf("MicChangeRPush MicEmptyRPush Marshal MicSystemMsg err:%+v, groupUuid:%v, i:%v, micContent:%+v", err, groupUid, i, string(micContent)) return } if n, err := redisCli.GetClusterRedis().RPush(context.Background(), redis_key.GetMicInfoChange(), string(str)).Result(); err != nil || n == 0 { model.Log.Errorf("MicChangeRPush MicEmptyRPush err:%+v, groupUuid:%v, i:%v, micContent:%+v", err, groupUid, i, string(micContent)) return } else { model.Log.Infof("MicChangeRPush MicEmptyRPush success groupUuid:%v, i:%v, micContent:%+v", micContent, groupUid, i, string(micContent)) } model.Log.Infof("MicChangeRPush MicEmptyRPush end groupUuid:%v, i:%v, micContent:%v", groupUid, i, string(micContent)) } //将麦位信息推送到redis 队列中 func MicChangeRPush(model *domain.Model, groupUid string, i int) { model.Log.Infof("MicChangeRPush MicChangeRPush begin groupUuid:%v, i:%v", groupUid, i) txGroupId, err := ToTxGroupId(model, groupUid) if err != nil { model.Log.Errorf("MicChangeRPush MicChangeRPush ToTxGroupId err:%+v, groupUid:%v", err, txGroupId) } micContent, err := getMicIContent(model, groupUid, i) if err != nil { model.Log.Errorf("MicChangeRPush MicChangeRPush getMicIContent err:%+v, groupUuid:%v, i:%v, micContent:%+v", err, groupUid, i, micContent) return } micContentStr, err := json.Marshal(micContent) if err != nil { model.Log.Errorf("MicChangeRPush MicChangeRPush Marshal err:%+v, groupUuid:%v, i:%v, micContent:%+v", err, groupUid, i, string(micContentStr)) return } str, err := json.Marshal(MicSystemMsg{ GroupUid: txGroupId, Content: string(micContentStr), MsgId: group_e.GroupMicChange, }) if err != nil { model.Log.Errorf("MicChangeRPush MicChangeRPush Marshal MicSystemMsg err:%+v, groupUuid:%v, i:%v, micContent:%+v", err, groupUid, i, string(micContentStr)) return } if n, err := redisCli.GetClusterRedis().RPush(context.Background(), redis_key.GetMicInfoChange(), string(str)).Result(); err != nil || n == 0 { model.Log.Errorf("MicChangeRPush MicChangeRPush err:%+v, groupUuid:%v, i:%v, micContent:%+v", err, groupUid, i, string(micContentStr)) return } else { model.Log.Infof("MicChangeRPush MicChangeRPush success groupUuid:%v, i:%v, micContent:%+v", groupUid, i, string(micContentStr)) } model.Log.Infof("MicChangeRPush MicChangeRPush end groupUuid:%v, i:%v, micContent:%+v", groupUid, i, micContent) } func MicAllRPush(model *domain.Model, groupUid string, externalId string) error { model.Log.Infof("MicChangeRPush MicAllRPush begin groupUuid:%v, externalId:%v", groupUid, externalId) txGroupId, err := ToTxGroupId(model, groupUid) if err != nil { model.Log.Errorf("MicChangeRPush MicChangeRPush ToTxGroupId err:%+v, groupUid:%v", err, txGroupId) } // micContents, err := GetMicAllContent(model, groupUid) if err != nil { model.Log.Errorf("MicChangeRPush MicAllRPush GetMicAllContent err:%+v, micContents:%v groupUuid:%v, externalId:%v", err, micContents, groupUid, externalId) return err } for _, micContent := range micContents { //麦上是默认值,就不用推 if micContent.Forbid == false && micContent.User == nil && micContent.AgoraId == 0 && micContent.Lock == false && micContent.ExternalId == "" && micContent.MicForbid == false { model.Log.Infof("MicChangeRPush MicAllRPush default micContent:%v, groupUuid:%v, externalId:%v, micContent:%+v", micContent, groupUid, externalId, micContent) continue } micContentStr, err := json.Marshal(micContent) if err != nil { model.Log.Errorf("MicChangeRPush MicAllRPush Marshal micContent err:%+v, groupUuid:%v, externalId:%v, micContent:%+v", err, groupUid, externalId, string(micContentStr)) continue } str, err := json.Marshal(MicSystemMsg{ GroupUid: txGroupId, Target: externalId, Content: string(micContentStr), MsgId: group_e.GroupMicChange, }) if err != nil { model.Log.Errorf("MicChangeRPush MicAllRPush Marshal MicSystemMsg err:%+v, groupUuid:%v, externalId:%v, micContent:%+v", err, groupUid, externalId, string(micContentStr)) continue } if n, err := redisCli.GetClusterRedis().RPush(context.Background(), redis_key.GetMicInfoChange(), string(str)).Result(); err != nil || n == 0 { model.Log.Errorf("MicChangeRPush MicAllRPush err:%+v, groupUuid:%v, externalId:%v, micContent:%+v", err, groupUid, externalId, string(micContentStr)) continue } else { model.Log.Infof("MicChangeRPush MicAllRPush success micContent:%v, groupUuid:%v, externalId:%v, micContent:%+v", micContent, groupUid, externalId, string(micContentStr)) } } model.Log.Infof("MicChangeRPush MicAllRPush end groupUuid:%v, externalId:%v", groupUid, externalId) return nil } // 通用麦位信息推送 func MicRPush(model *domain.Model, txGroupId string, msg GroupSystemMsg) error { model.Log.Infof("MicRPush begin msg:%v", msg) str, err := json.Marshal(MicSystemMsg{ GroupUid: txGroupId, Source: msg.Source, MsgId: msg.MsgId, Content: msg.Content, }) if err != nil { model.Log.Errorf("MicRPush Marshal MicSystemMsg err:%+v, txGroupId:%v, micContent:%+v", err, txGroupId, string(str)) return err } if n, err := redisCli.GetClusterRedis().RPush(context.Background(), redis_key.GetMicInfoChange(), string(str)).Result(); err != nil || n == 0 { model.Log.Errorf("MicRPush err:%+v, txGroupId:%v, micContent:%+v", err, txGroupId, string(str)) return err } model.Log.Infof("MicRPush end txGroupId:%v, micContent:%v", txGroupId, string(str)) return nil } //得使用旧的imGroupId func GetMicAllContent(model *domain.Model, groupUid string) ([]MicContent, error) { txGroupId, err := ToTxGroupId(model, groupUid) if err != nil { return nil, err } micNumType, err := GetMicNumType(model, groupUid) if err != nil { return nil, err } mics, micUsers, err := GetAllMic(groupUid, micNumType) micUserMap := map[int]MicUser{} for i, r := range micUsers { micUserMap[r.I] = micUsers[i] } userIds := make([]uint64, 0, len(micUsers)) for _, r := range micUsers { userIds = append(userIds, r.UserId) if r.CpUserId > 0 { userIds = append(userIds, r.CpUserId) } } model.Log.Infof("MicChangeRPush getMicAllContent groupUid:%v, userIds:%+v", groupUid, userIds) micUserDataMap, err := getMicUserDatas(model, userIds) if err != nil { return nil, err } micContents := make([]MicContent, 0, len(mics)) for _, r := range mics { var micEffect string cpUserId := micUserMap[r.I].CpUserId micUserData := micUserDataMap[micUserMap[r.I].UserId] if cpUserId > 0 { micEffect = "https://image.whoisamy.shop/hilo/resource/svga/mic_effect_cp.svga" micUserData.MicEffect = micEffect } micContents = append(micContents, MicContent{ GroupId: txGroupId, I: r.I, Lock: r.Lock, MicForbid: r.MicForbid, Forbid: micUserMap[r.I].Forbid, ExternalId: micUserMap[r.I].ExternalId, AgoraId: uint32(micUserMap[r.I].UserId), Timestamp: time.Now().UnixNano(), User: micUserData, }) } return micContents, nil } //得使用旧的imGroupId func getMicIContent(model *domain.Model, groupId string, i int) (MicContent, error) { txGroupId, err := ToTxGroupId(model, groupId) if err != nil { return MicContent{}, err } mic, err := GetMic(model, groupId, i) if err != nil { return MicContent{}, err } micUser, err := GetMicUser(model, groupId, i) if err != nil { return MicContent{}, err } if micUser == nil { return MicContent{ GroupId: txGroupId, I: mic.I, Lock: mic.Lock, Forbid: false, MicForbid: mic.MicForbid, ExternalId: "", AgoraId: 0, Timestamp: time.Now().UnixNano(), User: nil, }, nil } else { micUserData, err := getMicUserData(model, micUser.UserId) if err != nil { return MicContent{}, err } var micEffect string if micUser.CpUserId > 0 { micEffect = "https://image.whoisamy.shop/hilo/resource/svga/mic_effect_cp.svga" micUserData.MicEffect = micEffect } return MicContent{ GroupId: txGroupId, I: mic.I, Lock: mic.Lock, Forbid: micUser.Forbid, MicForbid: mic.MicForbid, ExternalId: micUser.ExternalId, AgoraId: uint32(micUser.UserId), Timestamp: time.Now().UnixNano(), User: micUserData, }, nil } } func getMicUserDatas(model *domain.Model, userIds []uint64) (map[uint64]*MicUserData, error) { userMap, err := user_m.GetUserMapByIds(model, userIds) if err != nil { return nil, err } vipMap, err := user_m.BatchGetVips(userIds) if err != nil { return nil, err } nobleMap, err := noble_m.BatchGetNobleLevel(model.Db, userIds) if err != nil { return nil, err } headwearMap, err := user_m.BatchGetUserHeadwearUsing(model, userIds) if err != nil { return nil, err } // resHeadwearIds := make([]uint64, 0, len(headwearMap)) for _, value := range headwearMap { resHeadwearIds = append(resHeadwearIds, value.HeadwearId) } // resHeadwearMap, err := res_m.BatchGetHeadwearByIds(model, resHeadwearIds) if err != nil { return nil, err } svips, _ := rpc.MGetUserSvip(model, userIds) cpRelations, _ := rpc.MGetUserCpRelations(model, userIds) micUserDataMap := map[uint64]*MicUserData{} for _, id := range userIds { user, flag := userMap[id] if !flag { model.Log.Errorf("MicChangeRPush getMicUserDatas id:%v noexit", id) } vipTime, vipFlag := vipMap[id] if vipTime == nil { vipFlag = false } var headwearPicUrl string var headwearEffectUrl string var headwearReverseEffectUrl string if headwearUser, flag := headwearMap[id]; flag { headwearPicUrl = resHeadwearMap[headwearUser.HeadwearId].PicUrl headwearEffectUrl = resHeadwearMap[headwearUser.HeadwearId].EffectUrl headwearReverseEffectUrl = resHeadwearMap[headwearUser.HeadwearId].ReverseEffectUrl } micUserDataMap[id] = &MicUserData{ Id: user.ID, ExternalId: user.ExternalId, Avatar: user.Avatar, Nick: user.Nick, Sex: user.Sex, Code: user.Code, IsVip: vipFlag, NobleLeave: nobleMap[id], HeadwearPicUrl: headwearPicUrl, HeadwearEffectUrl: headwearEffectUrl, HeadwearReverseEffectUrl: headwearReverseEffectUrl, SvipLevel: svips[id].SvipLevel, Svip: rpc.CopySimpleSvip(svips[id]), HeadwearIcon: cpRelations[user.ID].CpUserAvatar, } } return micUserDataMap, nil } func getMicUserData(model *domain.Model, userId uint64) (*MicUserData, error) { user, err := user_m.GetUser(model, userId) if err != nil { return nil, err } flag, _, err := user_m.IsVip(userId) if err != nil { return nil, err } nobleLeave, err := noble_m.GetNobleLevel(model.Db, userId) if err != nil { return nil, err } svip, _ := rpc.GetUserSvip(model, userId) var headwearPicUrl string var headwearEffectUrl string var headwearReverseEffectUrl string headwear, err := user_m.GetUserHeadwearUsing(model, userId) if err != nil { return nil, err } if headwear != nil { resHeadwear, err := res_m.GetHeadwearById(model, headwear.HeadwearId) if err != nil { return nil, err } headwearPicUrl = resHeadwear.PicUrl headwearEffectUrl = resHeadwear.EffectUrl headwearReverseEffectUrl = resHeadwear.ReverseEffectUrl } var headwearIcon string if cpRelation, _ := rpc.GetUserCpRelation(model, userId); len(cpRelation.CpUserAvatar) > 0 { headwearIcon = cpRelation.CpUserAvatar } return &MicUserData{ Id: user.ID, ExternalId: user.ExternalId, Avatar: user.Avatar, Nick: user.Nick, Sex: user.Sex, Code: user.Code, IsVip: flag, NobleLeave: nobleLeave, HeadwearPicUrl: headwearPicUrl, HeadwearEffectUrl: headwearEffectUrl, HeadwearReverseEffectUrl: headwearReverseEffectUrl, SvipLevel: svip.SvipLevel, Svip: rpc.CopySimpleSvip(svip), HeadwearIcon: headwearIcon, }, nil }