package roomrank import ( "apigame/service-common/svconst" "apigame/service-common/svmysql" "apigame/util/util-lx/lxalilog" "encoding/json" "fmt" "github.com/samber/lo" ) // Room 房间排行持久数据 type Room struct { Id int64 `gorm:"column:id;primaryKey;comment:房间唯一ID"` TopType int `gorm:"comment:排行榜类型"` ActivityId int64 `gorm:"comment:活动ID"` ActivityTime int64 `gorm:"comment:当前活动周期时间"` ConfigId int `gorm:"comment:房间配置ID"` Details *RoomDetails `gorm:"-"` // 详情 DetailsText string `gorm:"comment:详情封装"` Closed bool `gorm:"comment:房间已关闭"` ResetRobotTime int64 `gorm:"comment:上次刷新机器人时间"` HasSettle bool `gorm:"comment:是否结算"` CreateTime int64 `gorm:"comment:创建时间戳"` UpdateTime int64 `gorm:"comment:修改时间戳"` } func (d *Room) MysqlInfo(suffix string) *svmysql.MysqlInfo { tableName := svconst.MYSQL_TABLE_S_ROOMRANK_ROOM tableName = fmt.Sprintf("%s_%s_%d_%d", tableName, suffix, d.TopType, d.ActivityId) return &svmysql.MysqlInfo{ DbMysql: svconst.DbCommon, TableName: tableName, } } // RoomPlayer 房间玩家 type RoomPlayer struct { Uid int64 // 玩家唯一ID Name string // 玩家名字 Icon string // 玩家头像 Score int64 // 玩家排行分数 JoinTime int64 // 加入时间不改命名 改成最后更新分数的时间 UserType int // 用户类型 -1=原生配置机器人 RobotConfigId int // 0=玩家 } // RoomDetails 详情 type RoomDetails struct { Players []*RoomPlayer // 房间玩家列表 IndexNames []int // 房间玩家名字列表 } // Encode 打包数据 func (d *Room) Encode() { details, err := json.Marshal(d.Details) if err != nil { lxalilog.Errors(err, "Player Encode Error", d.Id, d.ActivityId) return } d.DetailsText = string(details) } // Decode 分包数据 func (d *Room) Decode() { d.Details = &RoomDetails{ Players: make([]*RoomPlayer, 0), IndexNames: make([]int, 0), } err := json.Unmarshal([]byte(d.DetailsText), d.Details) if err != nil { lxalilog.Errors(err, "Player Decode Error", d.Id, d.ActivityId) return } } // FindPlayer 找到玩家排名和积分 -1=没找到 func (d *Room) FindPlayer(playerUid int64) (int, int64) { count := len(d.Details.Players) if count > 0 { for i := 0; i < count; i++ { p := d.Details.Players[i] if p.Uid == playerUid { return i, p.Score } } } return -1, 0 } func (d *Room) GetPlayerTypeCount(userType int) int { return lo.CountBy(d.Details.Players, func(p *RoomPlayer) bool { return p.UserType == userType }) } /* 排名规则 降序 - 如果是玩家之间的分数相同,则先达到该分数的玩家排名靠前 - 如果是机器人之间的分数相同,则按照计算的处理先后顺序进行排序,或者随机排序,因为不重要 - 如果是玩家和机器人之间的分数相同,则玩家排名永远高于机器人排名 */ func (d *RoomDetails) Len() int { return len(d.Players) } func (d *RoomDetails) Less(i, j int) bool { if d.Players[i].Score != d.Players[j].Score { return d.Players[i].Score > d.Players[j].Score } // 如果是玩家和机器人之间的分数相同,则玩家排名永远高于机器人排名 if d.Players[i].RobotConfigId != d.Players[j].RobotConfigId { return d.Players[i].RobotConfigId < d.Players[j].RobotConfigId } // 如果是玩家之间的分数相同,则先达到该分数的玩家排名靠前 if d.Players[i].RobotConfigId == 0 && d.Players[j].RobotConfigId == 0 { return d.Players[i].JoinTime < d.Players[j].JoinTime } return d.Players[i].Score > d.Players[j].Score } func (d *RoomDetails) Swap(i, j int) { d.Players[i], d.Players[j] = d.Players[j], d.Players[i] } func (d *RoomPlayer) IsRobot() bool { return d.RobotConfigId != 0 }