dto-room.go
3.79 KB
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
120
121
122
123
124
125
126
127
128
129
130
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
}