846 lines
26 KiB
Go
846 lines
26 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"math/rand"
|
|
"rocommon/service"
|
|
"rocommon/util"
|
|
"roserver/baseserver/model"
|
|
model2 "roserver/game/model"
|
|
"roserver/serverproto"
|
|
"sort"
|
|
"strconv"
|
|
)
|
|
|
|
type MakeNtfMsgFunc func(uid uint64) interface{}
|
|
|
|
type LiveRoomInterface interface {
|
|
Update(deltaMS uint32)
|
|
Join(uid uint64)
|
|
Leave(uid uint64)
|
|
GetReady(uid uint64) bool
|
|
IsReady(uid uint64) bool
|
|
SendGift(uid uint64, giftId uint32) int32
|
|
RoomId() uint32
|
|
Heart() int64
|
|
AddHeart() int64
|
|
RoomType() uint32
|
|
StageSec() uint32
|
|
StageTimerSec() uint32
|
|
Stage() uint32
|
|
HasPlayer(uid uint64) bool
|
|
IsFree(uid uint64) bool
|
|
GiftRecords() []*serverproto.LiveRoomPlayerInfo
|
|
GiftRank() []*serverproto.LiveRoomPlayerInfo
|
|
ChatRecords() []*serverproto.LiveRoomChatData
|
|
GetReadyPlayerInfoList(uid uint64) []*serverproto.LiveRoomPlayerInfo
|
|
SendChat(senderId uint64, chatContent string)
|
|
ShowSubmit(uid uint64, data []*serverproto.KeyValueType64) []*serverproto.KeyValueType64
|
|
RoomState() string
|
|
RoomUserNum() int32
|
|
RoomUserHeads() []string
|
|
}
|
|
|
|
// 被子类重载函数
|
|
type LiveRoomTemplate interface {
|
|
GetMaxReadyNum(roomType uint32)
|
|
GetCMDPlayDataList(readyUidList []uint64, uid uint64, cfg *serverproto.LiveRoomTalkCfg) []*serverproto.KeyValueType64
|
|
GetShowResultList(readyUidList []uint64, uid uint64) []*serverproto.LiveRoomPlayerInfo
|
|
GetShowRewardList(readyUidList []uint64, uid uint64) []*serverproto.KeyValueType64
|
|
HasShowData() bool
|
|
GetShowData(readyUidList []uint64, uid uint64) []*serverproto.KeyValueType64
|
|
HandleShowSubmit(uid uint64, data []*serverproto.KeyValueType64) []*serverproto.KeyValueType64
|
|
GetStageEnterParams(stage uint32) string
|
|
ReadyStart()
|
|
ShowStart()
|
|
CheckIfShowEnd() bool
|
|
ShowEnd()
|
|
HandlePlayCMD(cfg *serverproto.LiveRoomTalkCfg)
|
|
}
|
|
|
|
type TimelineFrame struct {
|
|
sn int32
|
|
talkCfgList []*serverproto.LiveRoomTalkCfg
|
|
}
|
|
type LiveRoomSubmitData struct {
|
|
uid uint64
|
|
data *serverproto.KeyValueType64
|
|
}
|
|
|
|
type LiveRoom struct {
|
|
roomId uint32
|
|
roomType uint32
|
|
uidList []uint64
|
|
readyUidList []uint64
|
|
chatSN uint64
|
|
updateCount uint64
|
|
stageTick int32
|
|
tickIntervalMS uint32 //1000ms, 100ms
|
|
stage uint32
|
|
roomCfg *serverproto.LiveRoomCfg
|
|
sumGiftPoint int32
|
|
giftRankResetTime uint64
|
|
giftRank []*serverproto.LiveRoomPlayerInfo
|
|
giftRecords []*serverproto.LiveRoomPlayerInfo
|
|
chatRecords []*serverproto.LiveRoomChatData
|
|
idleTimeline map[int32]*TimelineFrame
|
|
readyTimeline map[int32]*TimelineFrame
|
|
showTimeline map[int32]*TimelineFrame
|
|
resultTimeline map[int32]*TimelineFrame
|
|
roomStateData map[string]string
|
|
heart int64
|
|
|
|
submitDataList []*LiveRoomSubmitData
|
|
|
|
// 函数字段:模拟虚函数
|
|
VF_GetMaxReadyNum func(roomType uint32) int
|
|
VF_GetCMDPlayDataList func(readyUidList []uint64, uid uint64, cfg *serverproto.LiveRoomTalkCfg) []*serverproto.KeyValueType64
|
|
VF_GetShowResultList func(readyUidList []uint64, uid uint64) []*serverproto.LiveRoomPlayerInfo
|
|
VF_GetShowRewardList func(readyUidList []uint64, uid uint64) []*serverproto.KeyValueType64
|
|
VF_HasShowData func() bool
|
|
VF_GetShowData func(readyUidList []uint64, uid uint64) []*serverproto.KeyValueType64
|
|
VF_HandleShowSubmit func(uid uint64, data []*serverproto.KeyValueType64) []*serverproto.KeyValueType64
|
|
VF_GetStageEnterParams func(stage uint32) string
|
|
VF_ReadyStart func()
|
|
VF_ShowStart func()
|
|
VF_CheckIfShowEnd func() bool
|
|
VF_ShowEnd func()
|
|
VF_HandlePlayCMD func(cfg *serverproto.LiveRoomTalkCfg)
|
|
VF_GetRoomState func() string
|
|
}
|
|
|
|
func newLiveRoom(roomId uint32, roomType uint32, tickInterval uint32) LiveRoom {
|
|
liveRoom := LiveRoom{
|
|
roomId: roomId,
|
|
roomType: roomType,
|
|
uidList: make([]uint64, 0),
|
|
readyUidList: make([]uint64, 0),
|
|
chatSN: 0,
|
|
updateCount: 0,
|
|
stageTick: 0,
|
|
tickIntervalMS: tickInterval,
|
|
stage: LIVEROOM_STAGE_NULL,
|
|
roomCfg: serverproto.LiveRoomCfgLoader[int32(roomType)],
|
|
sumGiftPoint: 0,
|
|
heart: 0,
|
|
giftRank: make([]*serverproto.LiveRoomPlayerInfo, 0),
|
|
giftRecords: make([]*serverproto.LiveRoomPlayerInfo, 0),
|
|
chatRecords: make([]*serverproto.LiveRoomChatData, 0),
|
|
roomStateData: make(map[string]string),
|
|
}
|
|
liveRoom.BaseSetVF()
|
|
liveRoom.BaseInit()
|
|
return liveRoom
|
|
}
|
|
|
|
func (self *LiveRoom) BaseSetVF() {
|
|
self.VF_GetMaxReadyNum = self.GetMaxReadyNum
|
|
self.VF_GetCMDPlayDataList = self.GetCMDPlayDataList
|
|
self.VF_GetShowResultList = self.GetShowResultList
|
|
self.VF_GetShowRewardList = self.GetShowRewardList
|
|
self.VF_HasShowData = self.HasShowData
|
|
self.VF_GetShowData = self.GetShowData
|
|
self.VF_HandleShowSubmit = self.HandleShowSubmit
|
|
self.VF_GetStageEnterParams = self.GetStageEnterParams
|
|
self.VF_ReadyStart = self.ReadyStart
|
|
self.VF_ShowStart = self.ShowStart
|
|
self.VF_CheckIfShowEnd = self.CheckIfShowEnd
|
|
self.VF_ShowEnd = self.ShowEnd
|
|
self.VF_HandlePlayCMD = self.HandlePlayCMD
|
|
self.VF_GetRoomState = self.GetRoomState
|
|
}
|
|
|
|
/*----------------------------------- 重载函数 -----------------------------------*/
|
|
func (self *LiveRoom) GetMaxReadyNum(roomType uint32) int {
|
|
util.InfoF("LiveRoom: GetMaxReadyNum")
|
|
return 0
|
|
}
|
|
|
|
func (self *LiveRoom) GetCMDPlayDataList(readyUidList []uint64, uid uint64, cfg *serverproto.LiveRoomTalkCfg) []*serverproto.KeyValueType64 {
|
|
return nil
|
|
}
|
|
|
|
func (self *LiveRoom) GetShowResultList(readyUidList []uint64, uid uint64) []*serverproto.LiveRoomPlayerInfo {
|
|
return nil
|
|
}
|
|
|
|
func (self *LiveRoom) GetShowRewardList(readyUidList []uint64, uid uint64) []*serverproto.KeyValueType64 {
|
|
return nil
|
|
}
|
|
|
|
func (self *LiveRoom) HasShowData() bool {
|
|
return false
|
|
}
|
|
|
|
func (self *LiveRoom) GetShowData(readyUidList []uint64, uid uint64) []*serverproto.KeyValueType64 {
|
|
return nil
|
|
}
|
|
|
|
func (self *LiveRoom) HandleShowSubmit(uid uint64, data []*serverproto.KeyValueType64) []*serverproto.KeyValueType64 {
|
|
return nil
|
|
}
|
|
|
|
func (self *LiveRoom) GetStageEnterParams(stage uint32) string {
|
|
return ""
|
|
}
|
|
|
|
func (self *LiveRoom) ReadyStart() {}
|
|
func (self *LiveRoom) ShowStart() {}
|
|
func (self *LiveRoom) CheckIfShowEnd() bool {
|
|
return false
|
|
}
|
|
func (self *LiveRoom) ShowEnd() {}
|
|
|
|
func (self *LiveRoom) HandlePlayCMD(cfg *serverproto.LiveRoomTalkCfg) {}
|
|
func (self *LiveRoom) GetRoomState() string {
|
|
return MapToString(self.roomStateData)
|
|
}
|
|
|
|
/*----------------------------------- 内部函数 -----------------------------------*/
|
|
func (self *LiveRoom) BaseInit() {
|
|
self.idleTimeline = self.CreateTimeline(LIVEROOM_STAGE_IDLE)
|
|
self.readyTimeline = self.CreateTimeline(LIVEROOM_STAGE_READY)
|
|
self.showTimeline = self.CreateTimeline(LIVEROOM_STAGE_SHOW)
|
|
self.resultTimeline = self.CreateTimeline(LIVEROOM_STAGE_RESULT)
|
|
self.giftRankResetTime = util.GetCurrentTime()
|
|
time1 := self.CalcTimelineSec(self.idleTimeline)
|
|
time2 := self.CalcTimelineSec(self.readyTimeline)
|
|
time3 := self.CalcTimelineSec(self.showTimeline)
|
|
time4 := self.CalcTimelineSec(self.resultTimeline)
|
|
util.InfoF("GetTimelineTime: ", time1, time2, time3, time4)
|
|
|
|
heartStr, err := service.GetRedis().HGet(model.LiveRoomHeartPrefix, fmt.Sprintf("%d", self.roomType)).Result()
|
|
if err != nil {
|
|
util.InfoF("ERR: Redis HGet %s:%s err", model.LiveRoomHeartPrefix, fmt.Sprintf("%d", self.roomType))
|
|
}
|
|
heartNum, _ := strconv.ParseInt(heartStr, 10, 64)
|
|
self.heart = heartNum
|
|
|
|
self.ChangeStage(LIVEROOM_STAGE_IDLE)
|
|
}
|
|
|
|
func (self *LiveRoom) CreateTimeline(stage int32) map[int32]*TimelineFrame {
|
|
timeline := make(map[int32]*TimelineFrame, 0)
|
|
var currentSN int32 = 0
|
|
liveRoomTalkCfg := serverproto.LiveRoomTalkCfgLoader
|
|
for i := 1; i <= len(liveRoomTalkCfg); i++ {
|
|
cfg := liveRoomTalkCfg[int32(i)]
|
|
if uint32(cfg.Type) == self.roomType && cfg.Stage == stage {
|
|
if frame, exist := timeline[currentSN]; exist {
|
|
frame.talkCfgList = append(frame.talkCfgList, cfg)
|
|
} else {
|
|
newFrame := &TimelineFrame{sn: currentSN, talkCfgList: make([]*serverproto.LiveRoomTalkCfg, 0)}
|
|
newFrame.talkCfgList = append(newFrame.talkCfgList, cfg)
|
|
timeline[currentSN] = newFrame
|
|
}
|
|
currentSN += cfg.Time
|
|
}
|
|
}
|
|
return timeline
|
|
}
|
|
|
|
func (self *LiveRoom) CalcTimelineSec(timeline map[int32]*TimelineFrame) int32 {
|
|
var totalTime int32 = 0
|
|
for _, frame := range timeline {
|
|
totalTime += frame.talkCfgList[0].Time
|
|
}
|
|
return totalTime
|
|
}
|
|
|
|
func (self *LiveRoom) Update(deltaMS uint32) {
|
|
self.stageTick += 1
|
|
self.updateCount += 1
|
|
if self.updateCount*uint64(deltaMS) > math.MaxUint64-10000 {
|
|
self.updateCount = 1
|
|
}
|
|
if (self.updateCount*uint64(deltaMS))%uint64(self.tickIntervalMS) == 0 {
|
|
switch self.stage {
|
|
case LIVEROOM_STAGE_IDLE:
|
|
self.LIVEROOM_STAGE_IDLE_Update(self.tickIntervalMS)
|
|
case LIVEROOM_STAGE_READY:
|
|
self.LIVEROOM_STAGE_READY_Update(self.tickIntervalMS)
|
|
case LIVEROOM_STAGE_SHOW:
|
|
self.LIVEROOM_STAGE_SHOW_Update(self.tickIntervalMS)
|
|
case LIVEROOM_STAGE_RESULT:
|
|
self.LIVEROOM_STAGE_RESULT_Update(self.tickIntervalMS)
|
|
}
|
|
}
|
|
if model.IsDailyResetHour5(self.giftRankResetTime) {
|
|
self.giftRank = make([]*serverproto.LiveRoomPlayerInfo, 0)
|
|
self.giftRankResetTime = util.GetCurrentTime()
|
|
util.InfoF("ResetGiftRank: RoomType=%d, time=%d", self.roomType, self.giftRankResetTime)
|
|
}
|
|
if self.updateCount%300 == 0 {
|
|
ret, err := service.GetRedis().HSet(model.LiveRoomHeartPrefix, fmt.Sprintf("%d", self.roomType), fmt.Sprintf("%d", self.heart)).Result()
|
|
if err != nil {
|
|
util.InfoF("[LiveRoom] Update HSet: %v %v", err, ret)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (self *LiveRoom) ChangeStage(newStage uint32) {
|
|
// 1. Current Stage Exit
|
|
switch self.stage {
|
|
case LIVEROOM_STAGE_IDLE:
|
|
self.LIVEROOM_STAGE_IDLE_Exit()
|
|
case LIVEROOM_STAGE_READY:
|
|
self.LIVEROOM_STAGE_READY_Exit()
|
|
case LIVEROOM_STAGE_SHOW:
|
|
self.LIVEROOM_STAGE_SHOW_Exit()
|
|
case LIVEROOM_STAGE_RESULT:
|
|
self.LIVEROOM_STAGE_RESULT_Exit()
|
|
}
|
|
// 2. Next Stage Enter
|
|
switch newStage {
|
|
case LIVEROOM_STAGE_IDLE:
|
|
self.LIVEROOM_STAGE_IDLE_Enter()
|
|
case LIVEROOM_STAGE_READY:
|
|
self.LIVEROOM_STAGE_READY_Enter()
|
|
case LIVEROOM_STAGE_SHOW:
|
|
self.LIVEROOM_STAGE_SHOW_Enter()
|
|
case LIVEROOM_STAGE_RESULT:
|
|
self.LIVEROOM_STAGE_RESULT_Enter()
|
|
}
|
|
self.SendAllPlayers(func(uid uint64) interface{} {
|
|
return &serverproto.SCLiveRoomStageNtf{
|
|
Uid: uid,
|
|
RoomId: self.roomId,
|
|
Stage: newStage,
|
|
StageTimerSec: self.GetStageTimerSec(newStage),
|
|
StageParams: self.VF_GetStageEnterParams(newStage),
|
|
}
|
|
})
|
|
// 3. Update Current Stage
|
|
self.stage = newStage
|
|
self.stageTick = -1
|
|
}
|
|
|
|
func (self *LiveRoom) makeTalkParams(cfg *serverproto.LiveRoomTalkCfg, player string, gift int32, item int32) string {
|
|
actIdx := rand.Intn(len(cfg.Params1)) + 1
|
|
talkIdx := rand.Intn(len(cfg.Params2)) + 1
|
|
return fmt.Sprintf("act:%d;talk:%d;player:%s;gift:%d;item:%d", actIdx, talkIdx, player, gift, item)
|
|
}
|
|
|
|
func (self *LiveRoom) HandleCMD(sn int32, cfg *serverproto.LiveRoomTalkCfg) {
|
|
if self.roomId == 1 {
|
|
util.InfoF("LIVEROOM_CMD_TALK: roomId=%d, stage=%d, sn=%d, talkId=%d", self.roomId, self.stage, sn, cfg.Id)
|
|
}
|
|
|
|
switch cfg.CMD {
|
|
case LIVEROOM_CMD_TALK:
|
|
self.SendAllPlayers(func(uid uint64) interface{} {
|
|
return &serverproto.SCLiveRoomCMDTalkNtf{
|
|
Uid: uid,
|
|
RoomId: self.roomId,
|
|
TalkId: uint32(cfg.Id),
|
|
TalkParams: self.makeTalkParams(cfg, "nil", 0, 0),
|
|
}
|
|
})
|
|
case LIVEROOM_CMD_PLAY:
|
|
self.VF_HandlePlayCMD(cfg)
|
|
self.SendAllPlayers(func(uid uint64) interface{} {
|
|
return &serverproto.SCLiveRoomCMDPlayNtf{
|
|
Uid: uid,
|
|
RoomId: self.roomId,
|
|
PlayDataList: self.VF_GetCMDPlayDataList(self.readyUidList, uid, cfg),
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
/*----------------------------------- Stage: IDLE -----------------------------------*/
|
|
func (self *LiveRoom) LIVEROOM_STAGE_IDLE_Enter() {
|
|
//util.InfoF("LIVEROOM_STAGE_IDLE_Enter")
|
|
self.readyUidList = make([]uint64, 0)
|
|
self.submitDataList = make([]*LiveRoomSubmitData, 0)
|
|
self.roomStateData = make(map[string]string)
|
|
self.sumGiftPoint = 0
|
|
}
|
|
|
|
func (self *LiveRoom) LIVEROOM_STAGE_IDLE_Update(deltaMS uint32) {
|
|
if self.roomId == 1 {
|
|
util.InfoF("LIVEROOM_STAGE_IDLE_Update: roomId=%d, stageTick=%d", self.roomId, uint32(self.stageTick))
|
|
}
|
|
if self.stageTick >= self.CalcTimelineSec(self.idleTimeline) {
|
|
if self.sumGiftPoint >= serverproto.LiveRoomCfgLoader[int32(self.roomType)].MaxGiftPoint {
|
|
self.ChangeStage(LIVEROOM_STAGE_READY)
|
|
} else {
|
|
self.ChangeStage(LIVEROOM_STAGE_IDLE)
|
|
}
|
|
return
|
|
}
|
|
|
|
if frame, exist := self.idleTimeline[self.stageTick]; exist {
|
|
for i := 0; i < len(frame.talkCfgList); i++ {
|
|
cfg := frame.talkCfgList[i]
|
|
self.HandleCMD(frame.sn, cfg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (self *LiveRoom) LIVEROOM_STAGE_IDLE_Exit() {}
|
|
|
|
/*----------------------------------- Stage: READY -----------------------------------*/
|
|
func (self *LiveRoom) LIVEROOM_STAGE_READY_Enter() {
|
|
//util.InfoF("LIVEROOM_STAGE_READY_Enter")
|
|
self.VF_ReadyStart()
|
|
}
|
|
|
|
func (self *LiveRoom) LIVEROOM_STAGE_READY_Update(deltaMS uint32) {
|
|
if self.stageTick >= self.CalcTimelineSec(self.readyTimeline) {
|
|
if len(self.readyUidList) > 0 {
|
|
self.ChangeStage(LIVEROOM_STAGE_SHOW)
|
|
} else {
|
|
self.ChangeStage(LIVEROOM_STAGE_IDLE)
|
|
}
|
|
return
|
|
}
|
|
//util.InfoF("LIVEROOM_STAGE_READY_Update: Tick %d", uint32(self.stageTick))
|
|
if frame, exist := self.readyTimeline[self.stageTick]; exist {
|
|
for i := 0; i < len(frame.talkCfgList); i++ {
|
|
cfg := frame.talkCfgList[i]
|
|
self.HandleCMD(frame.sn, cfg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (self *LiveRoom) LIVEROOM_STAGE_READY_Exit() {}
|
|
|
|
/*----------------------------------- Stage: SHOW -----------------------------------*/
|
|
func (self *LiveRoom) LIVEROOM_STAGE_SHOW_Enter() {
|
|
//util.InfoF("LIVEROOM_STAGE_SHOW_Enter")
|
|
self.VF_ShowStart()
|
|
}
|
|
|
|
func (self *LiveRoom) LIVEROOM_STAGE_SHOW_Update(deltaMS uint32) {
|
|
if self.stageTick >= self.CalcTimelineSec(self.showTimeline) {
|
|
self.ChangeStage(LIVEROOM_STAGE_RESULT)
|
|
return
|
|
}
|
|
if self.VF_CheckIfShowEnd() {
|
|
self.ChangeStage(LIVEROOM_STAGE_RESULT)
|
|
return
|
|
}
|
|
//util.InfoF("LIVEROOM_STAGE_SHOW_Update: Tick %d", uint32(self.stageTick))
|
|
if frame, exist := self.showTimeline[self.stageTick]; exist {
|
|
for i := 0; i < len(frame.talkCfgList); i++ {
|
|
cfg := frame.talkCfgList[i]
|
|
self.HandleCMD(frame.sn, cfg)
|
|
}
|
|
}
|
|
|
|
if self.VF_HasShowData() {
|
|
self.ShowDataNtf()
|
|
}
|
|
}
|
|
|
|
func (self *LiveRoom) LIVEROOM_STAGE_SHOW_Exit() {
|
|
self.VF_ShowEnd()
|
|
}
|
|
|
|
/*----------------------------------- Stage: RESULT -----------------------------------*/
|
|
func (self *LiveRoom) LIVEROOM_STAGE_RESULT_Enter() {
|
|
//util.InfoF("LIVEROOM_STAGE_RESULT_Enter")
|
|
self.SendAllPlayers(func(currUid uint64) interface{} {
|
|
showResultList := self.VF_GetShowResultList(self.readyUidList, currUid)
|
|
showRewardList := self.VF_GetShowRewardList(self.readyUidList, currUid)
|
|
return &serverproto.SCLiveRoomResultNtf{
|
|
Uid: currUid,
|
|
RoomId: self.roomId,
|
|
PlayerResultList: showResultList,
|
|
PlayerRewardList: showRewardList,
|
|
}
|
|
})
|
|
}
|
|
|
|
func (self *LiveRoom) LIVEROOM_STAGE_RESULT_Update(deltaMS uint32) {
|
|
if self.stageTick >= self.CalcTimelineSec(self.resultTimeline) {
|
|
self.ChangeStage(LIVEROOM_STAGE_IDLE)
|
|
return
|
|
}
|
|
//util.InfoF("LIVEROOM_STAGE_RESULT_Update: Tick %d", uint32(self.stageTick))
|
|
if frame, exist := self.resultTimeline[self.stageTick]; exist {
|
|
for i := 0; i < len(frame.talkCfgList); i++ {
|
|
cfg := frame.talkCfgList[i]
|
|
self.HandleCMD(frame.sn, cfg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (self *LiveRoom) LIVEROOM_STAGE_RESULT_Exit() {}
|
|
|
|
func (self *LiveRoom) GetStageTimerSec(stage uint32) uint32 {
|
|
var timeline map[int32]*TimelineFrame
|
|
switch stage {
|
|
case LIVEROOM_STAGE_IDLE:
|
|
timeline = self.idleTimeline
|
|
case LIVEROOM_STAGE_READY:
|
|
timeline = self.readyTimeline
|
|
case LIVEROOM_STAGE_SHOW:
|
|
timeline = self.showTimeline
|
|
case LIVEROOM_STAGE_RESULT:
|
|
timeline = self.resultTimeline
|
|
}
|
|
return uint32(self.CalcTimelineSec(timeline))
|
|
}
|
|
|
|
func (self *LiveRoom) Join(uid uint64) {
|
|
if SliceIsExist(self.uidList, uid) == false {
|
|
self.uidList = append(self.uidList, uid)
|
|
}
|
|
player := RoomMgr.GetPlayer(uid)
|
|
player.LeaveRoom = false
|
|
player.WaitLeaveRoom = false
|
|
//self.SendChat(1000, fmt.Sprintf("玩家【%s】进入了直播间", player.Name))
|
|
}
|
|
|
|
func (self *LiveRoom) Leave(uid uint64) {
|
|
player := RoomMgr.GetPlayer(uid)
|
|
player.WaitLeaveRoom = true
|
|
self.uidList = SliceRemoveByValue(self.uidList, uid)
|
|
}
|
|
|
|
func (self *LiveRoom) IsReady(uid uint64) bool {
|
|
if SliceIsExist(self.readyUidList, uid) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (self *LiveRoom) GetReady(currUid uint64) bool {
|
|
if self.stage != LIVEROOM_STAGE_READY {
|
|
util.InfoF("[GetReady] ERR: current stage is not LIVEROOM_STAGE_READY")
|
|
return false
|
|
}
|
|
if SliceIsExist(self.readyUidList, currUid) {
|
|
util.InfoF("[GetReady] ERR: %s already getReady", currUid)
|
|
return false
|
|
}
|
|
if len(self.readyUidList) > self.VF_GetMaxReadyNum(self.roomType) {
|
|
util.InfoF("[GetReady] ERR: readyUidList=%d > GetMaxReadyNum", len(self.readyUidList))
|
|
return false
|
|
}
|
|
self.readyUidList = append(self.readyUidList, currUid)
|
|
|
|
self.SendAllPlayers(func(currUid uint64) interface{} {
|
|
// 给客户端显示自己和其他4个玩家的准备信息
|
|
maxCount := 5
|
|
readyPlayerInfoList := make([]*serverproto.LiveRoomPlayerInfo, 0)
|
|
if SliceIsExist(self.readyUidList, currUid) {
|
|
// 1. 添加当前玩家的信息
|
|
currPlayer := RoomMgr.GetPlayer(currUid)
|
|
readyPlayerInfoList = append(readyPlayerInfoList, &serverproto.LiveRoomPlayerInfo{
|
|
Uid: currUid,
|
|
Nickname: currPlayer.Name,
|
|
Level: currPlayer.Level,
|
|
HeadId: currPlayer.HeadId,
|
|
HeadTitle: currPlayer.HeadTitle,
|
|
})
|
|
// 2. 先添加其他准备玩家信息
|
|
for i := len(self.readyUidList) - 1; i >= 0; i-- {
|
|
tmpUid := self.readyUidList[i]
|
|
if tmpUid != currUid {
|
|
player := RoomMgr.GetPlayer(tmpUid)
|
|
readyPlayerInfoList = append(readyPlayerInfoList, &serverproto.LiveRoomPlayerInfo{
|
|
Uid: tmpUid,
|
|
Nickname: player.Name,
|
|
Level: player.Level,
|
|
HeadId: player.HeadId,
|
|
HeadTitle: player.HeadTitle,
|
|
})
|
|
if len(readyPlayerInfoList) > maxCount-1 {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for i := len(self.readyUidList) - 1; i >= 0; i-- {
|
|
tmpUid := self.readyUidList[i]
|
|
player := RoomMgr.GetPlayer(tmpUid)
|
|
readyPlayerInfoList = append(readyPlayerInfoList, &serverproto.LiveRoomPlayerInfo{
|
|
Uid: tmpUid,
|
|
Nickname: player.Name,
|
|
Level: player.Level,
|
|
HeadId: player.HeadId,
|
|
HeadTitle: player.HeadTitle,
|
|
})
|
|
if len(readyPlayerInfoList) > maxCount {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return &serverproto.SCLiveRoomGetReadyNtf{
|
|
Uid: currUid,
|
|
RoomId: self.roomId,
|
|
ReadyPlayerInfoList: readyPlayerInfoList,
|
|
}
|
|
})
|
|
|
|
if len(self.readyUidList) >= self.VF_GetMaxReadyNum(self.roomType) {
|
|
self.ChangeStage(LIVEROOM_STAGE_SHOW)
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (self *LiveRoom) RoomId() uint32 {
|
|
return self.roomId
|
|
}
|
|
|
|
func (self *LiveRoom) Heart() int64 { return self.heart }
|
|
|
|
func (self *LiveRoom) AddHeart() int64 {
|
|
self.heart = self.heart + 1
|
|
return self.heart
|
|
}
|
|
|
|
func (self *LiveRoom) RoomType() uint32 {
|
|
return self.roomType
|
|
}
|
|
|
|
func (self *LiveRoom) Stage() uint32 {
|
|
return self.stage
|
|
}
|
|
|
|
func (self *LiveRoom) StageTimerSec() uint32 {
|
|
return self.GetStageTimerSec(self.stage)
|
|
}
|
|
|
|
func (self *LiveRoom) StageSec() uint32 {
|
|
return self.GetStageTimerSec(self.stage) - uint32(self.stageTick)
|
|
}
|
|
|
|
func (self *LiveRoom) HasPlayer(uid uint64) bool {
|
|
for i := 0; i < len(self.uidList); i++ {
|
|
if uid == self.uidList[i] {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (self *LiveRoom) RoomState() string {
|
|
return self.VF_GetRoomState()
|
|
}
|
|
|
|
func (self *LiveRoom) IsFree(uid uint64) bool {
|
|
if len(self.uidList) > LIVEROOM_MAX_PLAYER_NUM {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (self *LiveRoom) GetReadyPlayerInfoList(uid uint64) []*serverproto.LiveRoomPlayerInfo {
|
|
readyPlayerInfoList := make([]*serverproto.LiveRoomPlayerInfo, 0)
|
|
if self.stage == LIVEROOM_STAGE_READY {
|
|
if SliceIsExist(self.readyUidList, uid) {
|
|
readyPlayerInfoList = append(readyPlayerInfoList, MakeLiveRoomPlayerInfo(uid))
|
|
}
|
|
for _, readyUid := range self.readyUidList {
|
|
if len(readyPlayerInfoList) < 5 {
|
|
readyPlayerInfoList = append(readyPlayerInfoList, MakeLiveRoomPlayerInfo(readyUid))
|
|
}
|
|
}
|
|
}
|
|
return readyPlayerInfoList
|
|
}
|
|
|
|
func (self *LiveRoom) GiftRank() []*serverproto.LiveRoomPlayerInfo {
|
|
return self.giftRank
|
|
}
|
|
|
|
func (self *LiveRoom) GiftRecords() []*serverproto.LiveRoomPlayerInfo {
|
|
//sort.Slice(self.giftRank, func(i, j int) bool {
|
|
// return self.giftRank[i].Data > self.giftRank[j].Data
|
|
//})
|
|
//topCount := 10
|
|
//var rank []*serverproto.LiveRoomPlayerInfo
|
|
//if len(self.giftRank) >= topCount {
|
|
// rank = self.giftRank[:topCount]
|
|
//} else {
|
|
// rank = self.giftRank
|
|
//}
|
|
//return rank
|
|
return self.giftRecords
|
|
}
|
|
|
|
func (self *LiveRoom) ChatRecords() []*serverproto.LiveRoomChatData {
|
|
return self.chatRecords
|
|
}
|
|
|
|
func (self *LiveRoom) RoomUserNum() int32 {
|
|
return int32(len(self.uidList))
|
|
}
|
|
|
|
func (self *LiveRoom) RoomUserHeads() []string {
|
|
heads := make([]string, 0)
|
|
for _, uid := range self.uidList {
|
|
player := RoomMgr.GetPlayer(uid)
|
|
heads = append(heads, player.HeadId)
|
|
if len(heads) > 3 {
|
|
break
|
|
}
|
|
}
|
|
return heads
|
|
}
|
|
|
|
func (self *LiveRoom) RecordChatData(chatSN uint64, chatData *serverproto.LiveRoomChatData) {
|
|
var maxChatRecordNum int = 10
|
|
self.chatRecords = append(self.chatRecords, chatData)
|
|
if len(self.chatRecords) > maxChatRecordNum {
|
|
self.chatRecords = self.chatRecords[1:]
|
|
}
|
|
}
|
|
|
|
func (self *LiveRoom) ShowDataNtf() {
|
|
self.SendAllPlayers(func(uid uint64) interface{} {
|
|
showData := self.VF_GetShowData(self.readyUidList, uid)
|
|
return &serverproto.SCLiveRoomShowDataNtf{
|
|
Uid: uid,
|
|
RoomId: self.roomId,
|
|
ShowDataList: showData,
|
|
}
|
|
})
|
|
}
|
|
|
|
func (self *LiveRoom) SendChat(senderId uint64, chatContent string) {
|
|
senderPlayer := RoomMgr.GetPlayer(senderId)
|
|
self.chatSN = self.chatSN + 1
|
|
if self.chatSN >= math.MaxUint64-100 {
|
|
self.chatSN = 1
|
|
}
|
|
chatData := &serverproto.LiveRoomChatData{
|
|
SN: self.chatSN,
|
|
PlayerInfo: &serverproto.LiveRoomPlayerInfo{
|
|
Uid: senderId,
|
|
Nickname: senderPlayer.Name,
|
|
Level: senderPlayer.Level,
|
|
VipLevel: senderPlayer.VipLevel,
|
|
HeadId: senderPlayer.HeadId,
|
|
HeadTitle: 1,
|
|
},
|
|
ChatContent: chatContent,
|
|
}
|
|
self.RecordChatData(self.chatSN, chatData)
|
|
self.SendAllPlayers(func(uid uint64) interface{} {
|
|
return &serverproto.SCLiveRoomChatNtf{
|
|
Uid: uid,
|
|
RoomId: self.roomId,
|
|
ChatData: chatData,
|
|
}
|
|
})
|
|
}
|
|
|
|
func (self *LiveRoom) AddItemList(uid uint64, items []*serverproto.KeyValueType, from int32, notify bool) {
|
|
SendToAllGame(&serverproto.SSGameRoleAddItemListReq{
|
|
Uid: uid,
|
|
ItemList: items,
|
|
From: from,
|
|
Notify: notify,
|
|
})
|
|
}
|
|
|
|
func (self *LiveRoom) DeleteItemList(uid uint64, items []*serverproto.KeyValueType, from int32, notify bool) {
|
|
SendToAllGame(&serverproto.SSGameRoleDeleteItemListReq{
|
|
Uid: uid,
|
|
ItemList: items,
|
|
From: from,
|
|
Notify: notify,
|
|
})
|
|
}
|
|
|
|
func (self *LiveRoom) ShowSubmit(uid uint64, data []*serverproto.KeyValueType64) []*serverproto.KeyValueType64 {
|
|
return self.VF_HandleShowSubmit(uid, data)
|
|
}
|
|
|
|
func (self *LiveRoom) SendGift(uid uint64, giftId uint32) int32 {
|
|
player := RoomMgr.GetPlayer(uid)
|
|
|
|
giftCfg := serverproto.LiveRoomGiftCfgLoader[int32(giftId)]
|
|
costItemId, costItemNum := model.Str2Res(giftCfg.Price)
|
|
if player.GameChipNum < uint32(costItemNum) {
|
|
util.InfoF("[SendGift] Err: GameChipNum=%d < CostItemNum=%d", player.GameChipNum, costItemNum)
|
|
return int32(serverproto.ErrorCode_ERROR_RES_NOT_ENOUGH)
|
|
}
|
|
rewardItemId, _ := RollForRateCfg(giftCfg.RewardItems)
|
|
util.InfoF("[SendGift] RollForRateCfg rewardItemId = %d", rewardItemId)
|
|
giftRewardStatus := 0
|
|
if rewardItemId != -1 {
|
|
giftRewardStatus = 1
|
|
addItems := make([]*serverproto.KeyValueType, 0)
|
|
addItems = append(addItems, &serverproto.KeyValueType{Key: int32(rewardItemId), Value: 1})
|
|
self.AddItemList(uid, addItems, int32(model2.AddFrom_LiveRoom_Gift), true)
|
|
}
|
|
|
|
costItems := make([]*serverproto.KeyValueType, 0)
|
|
costItems = append(costItems, &serverproto.KeyValueType{Key: int32(costItemId), Value: costItemNum})
|
|
self.DeleteItemList(uid, costItems, int32(model2.AddFrom_LiveRoom_Gift), true)
|
|
|
|
sendGiftInfo := &serverproto.LiveRoomPlayerInfo{
|
|
Uid: uid,
|
|
Nickname: player.Name,
|
|
HeadId: player.HeadId,
|
|
Level: player.Level,
|
|
VipLevel: player.VipLevel,
|
|
Data: fmt.Sprintf("gift:%d;status:%d", giftId, giftRewardStatus),
|
|
}
|
|
self.giftRecords = append(self.giftRecords, sendGiftInfo)
|
|
if len(self.giftRecords) > 10 {
|
|
self.giftRecords = self.giftRecords[1:]
|
|
}
|
|
|
|
isFind := false
|
|
currGiftPoint := giftCfg.GiftPoint
|
|
self.sumGiftPoint += int32(currGiftPoint)
|
|
for _, v := range self.giftRank {
|
|
if v.Uid == player.Uid {
|
|
giftNum, _ := strconv.Atoi(v.Data)
|
|
giftNum += int(currGiftPoint)
|
|
isFind = true
|
|
break
|
|
}
|
|
}
|
|
if isFind == false {
|
|
playerInfo := MakeLiveRoomPlayerInfo(uid)
|
|
playerInfo.Data = string(currGiftPoint)
|
|
self.giftRank = append(self.giftRank, playerInfo)
|
|
}
|
|
sort.Slice(self.giftRank, func(i, j int) bool {
|
|
val1, _ := strconv.Atoi(self.giftRank[i].Data)
|
|
val2, _ := strconv.Atoi(self.giftRank[j].Data)
|
|
return val1 > val2
|
|
})
|
|
if len(self.giftRank) > 20 {
|
|
self.giftRank = self.giftRank[1:]
|
|
}
|
|
|
|
sendGiftTalkCfg := serverproto.LiveRoomTalkCfgLoader[LIVEROOM_TYPE_SEND_GIFT]
|
|
self.SendAllPlayers(func(uid uint64) interface{} {
|
|
return &serverproto.SCLiveRoomCMDTalkNtf{
|
|
Uid: uid,
|
|
RoomId: self.roomId,
|
|
TalkId: uint32(sendGiftTalkCfg.Id),
|
|
TalkParams: self.makeTalkParams(sendGiftTalkCfg, player.Name, int32(giftId), int32(rewardItemId)),
|
|
}
|
|
})
|
|
self.SendAllPlayers(func(uid uint64) interface{} {
|
|
return &serverproto.SCLiveRoomSendGiftNtf{
|
|
Uid: uid,
|
|
RoomId: self.roomId,
|
|
SendGiftInfo: sendGiftInfo,
|
|
}
|
|
})
|
|
|
|
self.SendChat(1000, fmt.Sprintf("玩家【%s】向主播打赏了【%s】", player.Name, giftCfg.Name))
|
|
return 0
|
|
}
|
|
|
|
func (self *LiveRoom) SendAllPlayers(makeNtfMsgFunc MakeNtfMsgFunc) {
|
|
for i := 0; i < len(self.uidList); i++ {
|
|
uid := self.uidList[i]
|
|
ntfMsg := makeNtfMsgFunc(uid)
|
|
SendToAllGame(ntfMsg)
|
|
}
|
|
}
|