package user import ( "bet24.com/log" "bet24.com/redis" "bet24.com/servers/common" "bet24.com/servers/micros/audioroom/handler/config" IRoomMgr "bet24.com/servers/micros/audioroom/handler/interface" pb "bet24.com/servers/micros/audioroom/proto" "bet24.com/servers/micros/audioroom/transaction/database" money "bet24.com/servers/micros/money/proto" "encoding/json" "fmt" "strconv" "sync" "time" ) const user_Seconds = 600 // 过期时长(秒) type UserRoom struct { roomMgr IRoomMgr.RoomMgr userId int // 用户Id roomId int // 在线房间 joinList []pb.UserRoomInfo // 加入列表(房间id) attentionList []int // 关注列表(房间id) browseList []int // 浏览列表(房间id) timeStamp int // 时间戳(用于清理过期数据) contributeList []*pb.UserContribute // 用户贡献 taskList map[int][]*pb.UserRoomTask // 房间任务 lock *sync.RWMutex } func NewUserRoom(userId int, mgr IRoomMgr.RoomMgr) *UserRoom { u := new(UserRoom) u.userId = userId u.roomMgr = mgr u.lock = &sync.RWMutex{} u.taskList = make(map[int][]*pb.UserRoomTask) u.timeStamp = common.GetTimeStamp() + user_Seconds log.Debug("room.newUserRoom userId=%d", userId) go func() { // 获取加入房间列表 u.loadJoinList() // 获取浏览房间列表 u.loadBrowseList() // 获取关注房间列表 u.loadAttentionList() // 获取贡献列表 u.loadContribute() }() return u } // 判断是否过期 func (this *UserRoom) IsExpire() bool { if this.timeStamp >= common.GetTimeStamp() { //log.Debug("user_room.checkExpire userId=%d 有效期时间 %s", this.userId, time.Unix(int64(this.timeStamp), 0).Format(common.Layout)) return false } // 判断是否在房间内 if this.GetOnlineRoom() > 0 { //log.Debug("user_room.checkExpire userId=%d 已失效,房间(roomId=%d)内活动,有效期时间 %s", // this.userId, this.roomId, time.Unix(int64(this.timeStamp), 0).Format(common.Layout)) return false } log.Debug("user_room.checkExpire userId=%d 过期用户清理", this.userId) return true } // 更新时间戳 func (this *UserRoom) UpdateTimeStamp() { this.timeStamp = common.GetTimeStamp() + user_Seconds return } // 获取在线房间 func (this *UserRoom) GetOnlineRoom() int { return this.roomId } // 设置在线房间 func (this *UserRoom) SetOnlineRoom(roomId int) { this.roomId = roomId return } // 加载加入列表 func (this *UserRoom) loadJoinList() { // 数据库取数据 this.joinList = database.GetUserJoin(this.userId) } // 加载浏览房间列表 func (this *UserRoom) loadBrowseList() { // 数据库取数据 this.browseList = database.GetUserBrowse(this.userId) } // 加载关注房间列表 func (this *UserRoom) loadAttentionList() { // 数据库取数据 this.attentionList = database.GetUserAttention(this.userId) } // 获取加入房间列表 func (this *UserRoom) GetJoinList() []int { var list []int for _, v := range this.joinList { list = append(list, v.RoomId) } return list } // 获取房间信息 func (this *UserRoom) UserRoomInfo(roomId int) *pb.UserRoomInfo { for i, v := range this.joinList { if v.RoomId == roomId { return &this.joinList[i] } } return nil } // 获取关注房间列表 func (this *UserRoom) GetAttentionList() []int { return this.attentionList } // 获取浏览房间列表 func (this *UserRoom) GetBrowseList() []int { return this.browseList } // 加入 func (this *UserRoom) AddJoin(roomId, roleId int, isFree bool, ipAddress string) int { // 判断是否已加入 for _, v := range this.joinList { if v.RoomId == roomId { return 13 } } // 不是免费,需要扣除钻石 if !isFree { room := this.roomMgr.GetRoomInfo(roomId) if room == nil { log.Debug("user_room.addJoin roomId=%d roleId=%d isFree=%v ipAddress=%s room is not exist", roomId, roleId, isFree, ipAddress) return 11 } // 有会费 if room.JoinFee > 0 { // 上交入会费 ret := money.ReduceChip(this.userId, room.JoinFee, common.LOGTYPE_AUDIOROOM_JOIN_DEL, "语音房", "会费扣减钻石", ipAddress) if ret != 1 { return 12 } cfg := config.Mgr.GetRoomConfig() // 计算会费收益 send := int(float64(room.JoinFee) * (1.00 - float64(cfg.JoinFee.Tax)/100.00)) money.GiveChip(room.UserId, send, common.LOGTYPE_AUDIOROOM_JOIN_SEND, "语音房", "收益加钻石", ipAddress) // 收集点数 go this.roomMgr.AddCollect(this.userId, roomId, room.JoinFee) } } info := pb.UserRoomInfo{ UserId: this.userId, RoomId: roomId, RoleId: roleId, Level: 1, Exps: 0, Crdate: common.GetNowTimeStr(), } this.joinList = append(this.joinList, info) // DB: 存入数据库 go database.SaveUserRoom(this.userId, info.RoomId, info.RoleId, info.Crdate) // 删除关注 this.DelAttention(info.RoomId) return 1 } // 取消加入 func (this *UserRoom) DelJoin(roomId int) int { log.Debug("user_room userId=%d roomId=%d", this.userId, roomId) for i := 0; i < len(this.joinList); i++ { if this.joinList[i].RoomId != roomId { continue } // 删除 this.joinList = append(this.joinList[:i], this.joinList[i+1:]...) // 删除任务 this.DelTask(roomId) // 删除贡献 this.DelContribute(roomId) // DB: 存入数据库 go func(userId, roomId int) { // 取消加入 database.DelUserRoom(userId, roomId) // 添加关注 this.AddAttention(roomId) }(this.userId, roomId) return 1 } return 11 } // 关注 func (this *UserRoom) AddAttention(roomId int) int { // 判断是否已关注 for _, v := range this.attentionList { if v == roomId { return 11 } } this.attentionList = append(this.attentionList, roomId) // DB: 存入数据库 buf, _ := json.Marshal(this.attentionList) go database.SaveUserAttention(this.userId, string(buf)) return 1 } // 取消关注 func (this *UserRoom) DelAttention(roomId int) int { for i := 0; i < len(this.attentionList); i++ { if this.attentionList[i] != roomId { continue } // 删除 this.attentionList = append(this.attentionList[:i], this.attentionList[i+1:]...) // DB: 存入数据库 buf, _ := json.Marshal(this.attentionList) go database.SaveUserAttention(this.userId, string(buf)) break } return 1 } // 是否关注房间 func (this *UserRoom) IsAttention(roomId int) int { for _, v := range this.attentionList { if v == roomId { return 1 } } return 11 } // 加入浏览列表 func (this *UserRoom) AddBrowse(roomId int) { // log.Debug("user_room.addBrowse userId=%d roomId=%d", this.userId, roomId) if len(this.browseList) >= 50 { this.browseList = this.browseList[1:] } for i := 0; i < len(this.browseList); i++ { if this.browseList[i] != roomId { continue } // 删除 this.browseList = append(this.browseList[:i], this.browseList[i+1:]...) break } this.browseList = append(this.browseList, roomId) // DB:写入数据库 buf, _ := json.Marshal(this.browseList) go database.SaveUserBrowse(this.userId, string(buf)) return } // redis key func (this *UserRoom) getRedisKey(userId int, code string) string { return fmt.Sprintf("%s:join:%d:%s", "audioroom", userId, code) } // 发送邀请加入 func (this *UserRoom) InviteJoin(toUserId, roomId int) int { code := strconv.Itoa(common.GetTimeStamp()) key := this.getRedisKey(toUserId, code) value, _ := json.Marshal(struct { RoomId int RoleId int }{ RoomId: roomId, RoleId: pb.Role_Member, }) redis.String_SetEx(key, string(value), user_Seconds) // 发送邀请通知 go this.inviteJoinNotify(toUserId, roomId, code) return 1 } // 接受邀请加入 func (this *UserRoom) AcceptJoin(code, ipAddress string) (int, int) { key := this.getRedisKey(this.userId, code) value, ok := redis.String_Get(key) if !ok { return -1, 0 } var v struct { RoomId int RoleId int } err := json.Unmarshal([]byte(value), &v) if err != nil { log.Error("acceptJoin json unmarshal userId=%d code=%s err ==> %v", this.userId, code, err) return -2, 0 } // 加入语音房 if retCode := this.AddJoin(v.RoomId, v.RoleId, true, ipAddress); retCode != 1 { return -3, 0 } return v.RoomId, v.RoleId } // 打印用户 func (this *UserRoom) DumpUser() { log.Debug("用户[%d]信息,在线房间[%d]过期时间[%s]:", this.userId, this.roomId, time.Unix(int64(this.timeStamp), 0).Format(common.Layout)) log.Debug("加入列表打印(%d)个:", len(this.joinList)) for _, info := range this.joinList { log.Debug(" %+v", info) } log.Debug("++++++++++++++++++++++++++++++++++++++++++++++") log.Debug("关注列表打印(%d)个:", len(this.attentionList)) for _, info := range this.attentionList { log.Debug(" %+v", info) } log.Debug("**********************************************") log.Debug("浏览列表打印(%d)个:", len(this.browseList)) for _, info := range this.browseList { log.Debug(" %+v", info) } log.Debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") log.Debug("用户贡献列表打印(%d)个:", len(this.contributeList)) for _, info := range this.contributeList { log.Debug(" %+v", info) } log.Debug("################################################") }