比赛观战

This commit is contained in:
sk 2024-08-15 14:01:18 +08:00
parent 514d6fdf37
commit e93616dcc9
17 changed files with 1915 additions and 706 deletions

View File

@ -6,7 +6,7 @@
"VerifyClientVersion":true,
"SrvMaintain":false,
"WhiteHttpAddr": [],
"HundredScenePreCreate":true,
"HundredScenePreCreate":false,
"WriteEventLog": true,
"SpreadAccountQPT":100,
"FakeVerifyCode":"123456",

View File

@ -39,4 +39,5 @@ const (
ETCDKEY_RANK_TYPE = "/game/RankType" // 排行榜奖励配置
ETCDKEY_AWARD_CONFIG = "/game/awardlog_config" //获奖记录
ETCDKEY_GUIDE = "/game/guide_config" //新手引导配置
ETCDKEY_MatchAudience = "/game/match_audience" //比赛观众
)

View File

@ -135,6 +135,7 @@ type AllConfig struct {
*webapi.AwardLogConfig
// 新手引导配置
*webapi.GuideConfig
MatchAudience map[int32]*webapi.MatchAudience // 比赛观众列表
}
type GlobalConfig struct {
@ -163,6 +164,7 @@ func (cm *ConfigMgr) GetConfig(platform string) *AllConfig {
EntrySwitch: make(map[int32]*webapi.EntrySwitch),
ShopInfos: make(map[int32]*ShopInfo),
ChannelSwitch: make(map[int32]*webapi.ChannelSwitchConfig),
MatchAudience: make(map[int32]*webapi.MatchAudience),
}
cm.platform[platform] = c
}
@ -356,3 +358,18 @@ func (cm *ConfigMgr) GetSkinSkillMaxLevel(plt string, skinId int32) int32 {
}
return level
}
func (cm *ConfigMgr) AddMatchAudience(d *webapi.MatchAudience) {
cfg := cm.GetConfig(d.Platform)
cfg.MatchAudience[d.GetSnId()] = d
}
func (cm *ConfigMgr) DelMatchAudience(d *webapi.MatchAudience) {
delete(cm.GetConfig(d.Platform).MatchAudience, d.GetSnId())
}
// IsMatchAudience 是不是比赛场观众
func (cm *ConfigMgr) IsMatchAudience(plt string, snId int32) bool {
_, ok := cm.GetConfig(plt).MatchAudience[snId]
return ok
}

View File

@ -66,7 +66,7 @@
- 2720~2739
#### tournament锦标赛
- 2740~2759
- 2740~2779
#### RankMatch 排位赛
- 2780~2800

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,10 @@ enum TOURNAMENTID{
PACKET_TM_SCTMSeasonRank = 2754;//
PACKET_TM_CSTMSeasonAward = 2755;//
PACKET_TM_SCTMSeasonAward = 2756;//
PACKET_TM_CSMatchList = 2757;//
PACKET_TM_SCMatchList = 2758;//
PACKET_TM_CSRoomList = 2759; //
PACKET_TM_SCRoomList = 2760; //
}
//
//PACKET_TM_CSTMInfo
@ -65,6 +69,7 @@ message TMInfo{
repeated string OnChannelName = 21;//
int32 ShowId = 22; //
int32 AwardNum = 23; //
int32 AudienceSwitch = 27; // 1 2
}
message MatchTypeInfo{
@ -187,4 +192,57 @@ message CSTMSeasonAward {
message SCTMSeasonAward {
int32 Lv = 1;//
int32 Code = 2;//0 1
}
//PACKET_TM_CSMatchList
message CSMatchList{
int64 MatchId = 1; // id 0
int32 Tp = 2; // 0 1
}
message MatchPlayer{
int32 SnId = 1; // id
string Name = 2; //
string HeadUrl = 3;//
int32 UseRoleId = 4;//使id
int32 UseSkinId = 5; // id
int32 Rank = 6;//
int32 Score = 7;//
}
message MatchInfo{
int64 MatchId = 1; // id
int64 InstanceId = 2; // id
string Name = 3; //
int32 Round = 4; //
int32 TotalRound = 5; //
int32 RemainNum = 6; //
repeated MatchPlayer Players = 7; //
}
message SCTMMatchList{
repeated MatchInfo List = 1;
int64 MatchId = 2;
int32 Tp = 3;
}
//PACKET_TM_CSRoomList
message CSRoomList{
int64 Id = 1; // id 0
int32 Tp = 2; // 0 1
}
message MatchRoom{
int64 RoomId = 1; // id
int64 MatchId = 2; // id
int64 InstanceId = 3; // id
int32 Round = 4; //
int32 TotalRound = 5; //
repeated MatchPlayer Players = 7; //
}
message SCRoomList{
repeated MatchRoom List = 1;
int64 Id = 2;
int32 Tp = 3;
}

File diff suppressed because it is too large Load Diff

View File

@ -490,6 +490,7 @@ message GameMatchDate {
int32 CardType = 24; //
int32 ShowId = 25; //
int32 AwardNum = 26; //
int32 AudienceSwitch = 27; // 1 2
}
// etcd /game/game_match
@ -889,4 +890,11 @@ message GuideConfig {
string Platform = 1; //
int32 On = 2; // 1 2
int32 Skip = 3; // 1 2
}
// etcd /game/match_audience
message MatchAudience {
string Platform = 1; //
int32 SnId = 2; // ID
int64 Ts = 3; //
}

View File

@ -203,9 +203,15 @@ func (this *CSAudienceEnterRoomHandler) Process(s *netlib.Session, packetid int,
logger.Logger.Trace("CSAudienceEnterRoomHandler scene == nil")
goto failed
}
if scene.IsMatchScene() {
if !scene.CanAudience() {
code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
logger.Logger.Tracef("CSAudienceEnterRoomHandler scene.IsMatchScene() %v", scene.sceneId)
logger.Logger.Tracef("CSAudienceEnterRoomHandler scene.CanAudience() %v", scene.sceneId)
goto failed
}
if scene.IsMatchScene() && !PlatformMgrSingleton.IsMatchAudience(p.Platform, p.SnId) {
code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
logger.Logger.Tracef("CSAudienceEnterRoomHandler scene.IsMatchAudience() %v", scene.sceneId)
goto failed
}
if p.scene != nil {

View File

@ -1,11 +1,11 @@
package main
import (
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib"
"mongo.games.com/game/common"
"mongo.games.com/game/protocol/tournament"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib"
"sort"
)
func CSTMInfo(s *netlib.Session, packetid int, data interface{}, sid int64) error {
@ -94,9 +94,135 @@ func CSSignRace(s *netlib.Session, packetid int, data interface{}, sid int64) er
return nil
}
func CSMatchList(s *netlib.Session, packetId int, data interface{}, sid int64) error {
logger.Logger.Trace("CSMatchList ", data)
msg, ok := data.(*tournament.CSMatchList)
if !ok {
return nil
}
p := PlayerMgrSington.GetPlayer(sid)
if p == nil {
logger.Logger.Warnf("CSMatchList p == nil.")
return nil
}
pack := &tournament.SCTMMatchList{
MatchId: msg.GetMatchId(),
Tp: msg.GetTp(),
}
audience := msg.GetTp() == 1
list := TournamentMgr.GetTmMatch(p.Platform, int32(msg.GetMatchId()), p.LastChannel, audience, 0)
// 开始时间排序
sort.Slice(list, func(i, j int) bool {
return list[i].StartTime < list[j].StartTime
})
for _, v := range list {
round := TournamentMgr.GetRound(v.SortId)
d := &tournament.MatchInfo{
MatchId: int64(v.TMId),
InstanceId: v.SortId,
Name: v.gmd.MatchName,
Round: round,
TotalRound: v.GetTotalRound(),
RemainNum: TournamentMgr.GetRemainNum(v.SortId),
}
for _, v := range TournamentMgr.GetRemainPlayer(v.SortId) {
var name, headUrl string
p := PlayerMgrSington.GetPlayerBySnId(v.SnId)
if p != nil {
name = p.Name
headUrl = p.HeadUrl
}
d.Players = append(d.Players, &tournament.MatchPlayer{
SnId: v.SnId,
Name: name,
HeadUrl: headUrl,
UseRoleId: v.RoleId,
UseSkinId: v.SkinId,
Rank: v.Rank,
Score: v.Grade,
})
}
sort.Slice(d.Players, func(i, j int) bool {
if d.Players[i].Score > d.Players[j].Score {
return true
}
if d.Players[i].Score < d.Players[j].Score {
return false
}
return d.Players[i].SnId < d.Players[j].SnId
})
pack.List = append(pack.List, d)
}
p.SendToClient(int(tournament.TOURNAMENTID_PACKET_TM_SCMatchList), pack)
logger.Logger.Tracef("SCMatchList %v", pack)
return nil
}
func CSRoomList(s *netlib.Session, packetId int, data interface{}, sid int64) error {
logger.Logger.Trace("CSRoomList ", data)
msg, ok := data.(*tournament.CSRoomList)
if !ok {
return nil
}
p := PlayerMgrSington.GetPlayer(sid)
if p == nil {
logger.Logger.Warnf("CSRoomList p == nil.")
return nil
}
pack := &tournament.SCRoomList{
Id: msg.GetId(),
Tp: msg.GetTp(),
}
audience := msg.GetTp() == 1
scenes := TournamentMgr.GetTmRoom(p.Platform, 0, p.LastChannel, audience, msg.GetId())
for _, v := range scenes {
tm := TournamentMgr.GetTm(v.matchId)
if tm == nil {
continue
}
room := &tournament.MatchRoom{
RoomId: int64(v.sceneId),
MatchId: int64(tm.TMId),
InstanceId: tm.SortId,
Round: TournamentMgr.GetRound(tm.SortId),
TotalRound: tm.GetTotalRound(),
}
for _, v := range v.players {
if v.matchCtx == nil {
continue
}
d := &tournament.MatchPlayer{
SnId: v.matchCtx.copySnid,
Name: v.Name,
HeadUrl: v.HeadUrl,
UseRoleId: v.matchCtx.copyRoleId,
UseSkinId: v.matchCtx.copySkinId,
Rank: v.matchCtx.rank,
Score: v.matchCtx.grade,
}
room.Players = append(room.Players, d)
}
pack.List = append(pack.List, room)
}
p.SendToClient(int(tournament.TOURNAMENTID_PACKET_TM_SCRoomList), pack)
logger.Logger.Tracef("SCRoomList %v", pack)
return nil
}
func init() {
// 比赛信息列表
// 比赛配置列表
common.Register(int(tournament.TOURNAMENTID_PACKET_TM_CSTMInfo), tournament.CSTMInfo{}, CSTMInfo)
// 比赛报名
common.Register(int(tournament.TOURNAMENTID_PACKET_TM_CSSignRace), tournament.CSSignRace{}, CSSignRace)
// 比赛中比赛列表
common.Register(int(tournament.TOURNAMENTID_PACKET_TM_CSMatchList), tournament.CSMatchList{}, CSMatchList)
// 比赛中房间列表
common.Register(int(tournament.TOURNAMENTID_PACKET_TM_CSRoomList), tournament.CSRoomList{}, CSRoomList)
}

View File

@ -148,6 +148,7 @@ func (csm *CoinSceneMgr) PlayerEnter(p *Player, id int32, roomId int32, exclude
}
// AudienceEnter 观众进入房间
// id 场次id
func (csm *CoinSceneMgr) AudienceEnter(p *Player, id int32, roomId int32, exclude []int32, ischangeroom bool) hall_proto.OpResultCode {
//多平台支持
platform := p.GetPlatform()

View File

@ -90,6 +90,8 @@ func init() {
etcd.Register(etcd.ETCDKEY_AWARD_CONFIG, webapi.AwardLogConfig{}, platformConfigEvent)
// 新手引导
etcd.Register(etcd.ETCDKEY_GUIDE, webapi.GuideConfig{}, platformConfigEvent)
// 比赛观众
etcd.Register(etcd.ETCDKEY_MatchAudience, webapi.MatchAudience{}, handlerEvent)
}
func platformConfigEvent(ctx context.Context, completeKey string, isInit bool, event *clientv3.Event, data interface{}) {
@ -397,6 +399,13 @@ func handlerEvent(ctx context.Context, completeKey string, isInit bool, event *c
if isInit || event.Type == clientv3.EventTypePut {
ActMgrSington.AddGiveConfig(config, config.Platform)
}
case *webapi.MatchAudience:
switch event.Type {
case clientv3.EventTypePut:
PlatformMgrSingleton.AddMatchAudience(config)
case clientv3.EventTypeDelete:
PlatformMgrSingleton.DelMatchAudience(config)
}
default:
logger.Logger.Errorf("etcd completeKey:%s, Not processed", completeKey)

View File

@ -97,7 +97,6 @@ func (ms *MatchSceneMgr) MatchStart(tm *TmMatch) {
}
// 填充机器人
if scene != nil && !scene.IsFull() {
tm.RobotGradesDecline(1)
needRobotNum := scene.playerNum - len(scene.players)
logger.Logger.Trace("MatchStart 填充机器人", needRobotNum)
pack := &server.WGInviteMatchRob{

View File

@ -1024,6 +1024,7 @@ func (this *Scene) GetSceneName() string {
}
return "[unknow scene name]"
}
func (this *Scene) RandRobotCnt() {
if len(this.paramsEx) > 0 {
gps := PlatformMgrSingleton.GetGameFree(this.limitPlatform.IdStr, this.paramsEx[0])
@ -1263,3 +1264,17 @@ func (this *Scene) TryForceDelectMatchInfo() {
}
}
}
// CanAudience 是否允许观战
func (this *Scene) CanAudience() bool {
switch {
case this.matchId > 0: // 比赛场
tm := TournamentMgr.GetTm(this.matchId)
if tm != nil {
return tm.gmd.GetAudienceSwitch() == 1
}
return false
default:
return true
}
}

View File

@ -115,6 +115,19 @@ func (m *SceneMgr) GetScenesByGameFreeId(gameFreeId int32) []*Scene {
return scenes
}
func (m *SceneMgr) GetMatchRoom(sortId int64) []*Scene {
var scenes []*Scene
for _, value := range m.scenes {
if value.matchId == sortId {
s := m.GetScene(value.sceneId)
if s != nil {
scenes = append(scenes, value)
}
}
}
return scenes
}
// MarshalAllRoom 获取房间列表
func (m *SceneMgr) MarshalAllRoom(platform string, groupId, gameId int, gameMode, clubId, sceneMode, sceneId int,
gameFreeId, snId int32, start, end, pageSize int32) ([]*webapi2.RoomInfo, int32, int32) {

View File

@ -74,6 +74,8 @@ func (tm *TmMatch) Start() {
tm.BroadcastMessage(int(tournament.TOURNAMENTID_PACKET_TM_SCTMStart), pack)
logger.Logger.Trace("SCTMStart ", pack)
tm.RobotGradesDecline(1)
//创建房间
timer.StartTimer(timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool {
MatchSceneMgrSingleton.MatchStart(tm)
@ -87,6 +89,10 @@ func (tm *TmMatch) Stop() {
logger.Logger.Trace("(this *TmMatch) Stop()")
}
func (tm *TmMatch) GetTotalRound() int32 {
return int32(len(tm.gmd.GetMatchPromotion()) - 1)
}
func (tm *TmMatch) BroadcastMessage(packetId int, rawPack interface{}) {
mgs := make(map[*netlib.Session][]*srvproto.MCSessionUnion)
for _, tmp := range tm.TmPlayer {

View File

@ -170,6 +170,94 @@ func (this *Tournament) getRoundPlayer(sortId int64, round int32) *PlayerRoundIn
return v
}
// GetRemainNum 剩余比赛人数
func (this *Tournament) GetRemainNum(sortId int64) int32 {
tm := this.GetTm(sortId)
if tm == nil {
return 0
}
round := this.GetRound(sortId)
l := tm.gmd.GetMatchPromotion()
if round <= int32(len(l)) {
return l[round-1]
}
return 0
}
type MatchPlayerInfo struct {
SnId int32
RoleId int32
SkinId int32
Rank int32
Grade int32
}
// GetRemainPlayer 未淘汰的人
func (this *Tournament) GetRemainPlayer(sortId int64) []*MatchPlayerInfo {
tm := this.GetTm(sortId)
if tm == nil {
return nil
}
round := this.GetRound(sortId)
useRobot := this.IsRobotOn(tm.gmd)
var ret []*MatchPlayerInfo
realPlayer := func() {
for _, v := range tm.TmPlayer {
p := PlayerMgrSington.GetPlayerBySnId(v.SnId)
if p != nil {
ret = append(ret, &MatchPlayerInfo{
SnId: v.SnId,
RoleId: p.GetRoleId(),
SkinId: p.Skin.ModId,
Grade: 1000,
})
}
}
}
robotPlayer := func(n int) {
for _, v := range tm.robotGrades[n] {
ret = append(ret, &MatchPlayerInfo{
SnId: v.copySnid,
RoleId: v.copyRoleId,
SkinId: v.CopySkinId,
Grade: v.grade,
})
}
}
if round <= 1 {
if useRobot {
robotPlayer(0)
realPlayer()
} else {
realPlayer()
}
} else {
if useRobot {
robotPlayer(int(round - 1))
} else {
if this.roundPlayers[sortId] != nil {
d := this.roundPlayers[sortId][round-1]
if d != nil {
for _, v := range d.ranks {
ret = append(ret, &MatchPlayerInfo{
SnId: v.copySnid,
RoleId: v.copyRoleId,
SkinId: v.copySkinId,
Grade: v.grade,
})
}
}
}
}
}
return ret
}
// GetSignUpPlayers 获取报名人员
// id 比赛配置id
func (this *Tournament) GetSignUpPlayers(platform string, id int32) map[int32]*TmPlayer {
@ -1513,6 +1601,72 @@ func (this *Tournament) GetSCTMInfosPack(platform, channelName string) *tourname
return pack
}
// GetTmMatch 查询比赛中的比赛
func (this *Tournament) GetTmMatch(plt string, matchId int32, channelName string, audience bool, sortId int64) []*TmMatch {
matches := this.GetAllMatchInfo(plt)
if matches == nil {
return nil
}
var ids []int32
for id, info := range matches {
if info == nil || info.MatchSwitch != 1 {
continue
}
if matchId > 0 && id != matchId {
continue
}
if channelName != "" && !common.InMatchChannel(info.OnChannelName, channelName) {
continue
}
if info.GetAudienceSwitch() == 1 != audience {
continue
}
ids = append(ids, id)
}
var ret []*TmMatch
if sortId > 0 {
for _, v := range ids {
d := this.matches[v]
if d != nil {
r, ok := d[sortId]
if ok && r != nil {
return []*TmMatch{r}
}
}
}
return ret
}
for _, v := range ids {
for _, vv := range this.matches[v] {
ret = append(ret, vv)
}
}
return ret
}
func (this *Tournament) GetTmRoom(plt string, matchId int32, channelName string, audience bool, sortId int64) []*Scene {
tm := this.GetTmMatch(plt, matchId, channelName, audience, sortId)
sort.Slice(tm, func(i, j int) bool {
return tm[i].SortId < tm[j].SortId
})
var ret []*Scene
for _, v := range tm {
d := SceneMgrSingleton.GetMatchRoom(v.SortId)
sort.Slice(d, func(i, j int) bool {
return d[i].createTime.Before(d[j].createTime)
})
ret = append(ret, d...)
}
return ret
}
func (this *Tournament) MakeMatchLog(platform string, tmId int32, sortId int64) *model.MatchLog {
gameMatchDate := this.GetMatchInfo(platform, tmId, sortId)
if gameMatchDate == nil {
@ -1780,3 +1934,11 @@ func (this *Tournament) GetMatchAwardNum(platform string, id int32) int32 {
}
return num
}
func (this *Tournament) GetRound(sortId int64) int32 {
d, ok := this.roundPlayers[sortId]
if !ok || d == nil {
return 1
}
return int32(len(d))
}