From a97f15d68970b4097d4f4ab10184ed992d9a873f Mon Sep 17 00:00:00 2001 From: chenweijian <820961417@qq.com> Date: Wed, 16 Aug 2023 14:21:02 +0800 Subject: [PATCH] Feature/dominoes --- cron/cron.go | 1 + cron/group_cron/create_group.go | 32 ++++++++ domain/cache/game_c/game.go | 17 +++-- domain/model/game_m/game.go | 5 +- domain/model/group_m/groupInfo.go | 1 + domain/model/group_m/micData.go | 4 +- domain/model/group_m/room.go | 2 +- domain/service/group_s/group_op.go | 118 +++++++++++++++++++++++++++++ route/group_r/group_info.go | 6 +- route/group_r/group_op.go | 12 ++- route/group_r/group_setting.go | 5 ++ route/router.go | 4 +- 12 files changed, 190 insertions(+), 17 deletions(-) create mode 100644 cron/group_cron/create_group.go diff --git a/cron/cron.go b/cron/cron.go index b9c89c2..d10deb0 100644 --- a/cron/cron.go +++ b/cron/cron.go @@ -18,4 +18,5 @@ func Init() { group_cron.GroupPowerMonthRankAct() group_cron.GroupInEventInit() // 进房事件 group_cron.GroupPowerGradeExp() // 家族升级 + group_cron.CreateGroup() // } diff --git a/cron/group_cron/create_group.go b/cron/group_cron/create_group.go new file mode 100644 index 0000000..8bbf7c7 --- /dev/null +++ b/cron/group_cron/create_group.go @@ -0,0 +1,32 @@ +package group_cron + +import ( + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/config" + "github.com/robfig/cron" + "hilo-group/_const/enum/group_e" + "hilo-group/domain/service/group_s" +) + +func CreateGroup() { + if !config.IsMaster() { + return + } + c := cron.New() + spec := "0 15 15 16 8 ?" + _ = c.AddFunc(spec, func() { + var model = domain.CreateModelNil() + userId := uint64(7687) + num := 20 + if config.AppIsRelease() { + userId = 8350311 + num = 1000 + } + err := group_s.NewGroupService(model.MyContext).CreateGroupMulByUid(userId, num, group_e.TwoMicNumType) + if err != nil { + model.Log.Errorf("CreateGroupMulByUid fail:%v", err) + } + }) + + c.Start() +} diff --git a/domain/cache/game_c/game.go b/domain/cache/game_c/game.go index 67298ee..53212d2 100644 --- a/domain/cache/game_c/game.go +++ b/domain/cache/game_c/game.go @@ -9,15 +9,18 @@ import ( ) type gameAutoJoinMsg struct { - TraceId string - Token string - EnterType string - GameCode string + TraceId string + Token string + EnterType string + GameCode string + Is1V1 string + GameMode string + Is1V1Robot string } -func SetAutoMathEnterRoom(userId uint64, imGroupId, traceId, token, enterType, gameCode string) error { +func SetAutoMathEnterRoom(userId uint64, imGroupId, traceId, token, enterType, gameCode, is1V1, gameMode, is1V1Robot string) error { key := game_e.GetAutoMathEnterRoom(userId, imGroupId) - info := gameAutoJoinMsg{traceId, token, enterType, gameCode} + info := gameAutoJoinMsg{traceId, token, enterType, gameCode, is1V1, gameMode, is1V1Robot} data, err := json.Marshal(info) if err != nil { return err @@ -26,7 +29,7 @@ func SetAutoMathEnterRoom(userId uint64, imGroupId, traceId, token, enterType, g if err != nil { return err } - redisCli.GetRedis().Expire(context.Background(), key, time.Second*3) + redisCli.GetRedis().Expire(context.Background(), key, time.Second*10) return nil } diff --git a/domain/model/game_m/game.go b/domain/model/game_m/game.go index 7e0afb7..241b22c 100644 --- a/domain/model/game_m/game.go +++ b/domain/model/game_m/game.go @@ -29,8 +29,9 @@ type GameInfo struct { } type GameConfig struct { - Ludo *GameConfigDiamond `json:"ludo"` - Uno *GameConfigDiamond `json:"uno"` + Ludo *GameConfigDiamond `json:"ludo"` + Uno *GameConfigDiamond `json:"uno"` + Domino *GameConfigDiamond `json:"domino"` } type GameConfigDiamond struct { diff --git a/domain/model/group_m/groupInfo.go b/domain/model/group_m/groupInfo.go index c01a323..6bcee9e 100644 --- a/domain/model/group_m/groupInfo.go +++ b/domain/model/group_m/groupInfo.go @@ -47,6 +47,7 @@ type GroupInfo struct { CreatedTime time.Time `gorm:"->"` UpdatedTime time.Time `gorm:"->"` VisitCount int64 `gorm:"-"` // 热度 + IsGameRoom uint8 // 是否1v1游戏房 } func GenerateGroupCode(n uint16) string { diff --git a/domain/model/group_m/micData.go b/domain/model/group_m/micData.go index 546458d..6fa6cdf 100644 --- a/domain/model/group_m/micData.go +++ b/domain/model/group_m/micData.go @@ -68,7 +68,7 @@ type MicNumChangeContent struct { Timestamp int64 `json:"timestamp"` } -func MicGroupKickOutRPush(model *domain.Model, groupUid string, userExternalId string, beKickExternalId string) { +func MicGroupKickOutRPush(model *domain.Model, groupUid string, userExternalId string, beKickExternalId string, beKickuserId uint64) { model.Log.Infof("MicChangeRPush MicGroupKickOutRPush begin groupUuid:%v", groupUid) txGroupId, err := ToTxGroupId(model, groupUid) @@ -94,6 +94,8 @@ func MicGroupKickOutRPush(model *domain.Model, groupUid string, userExternalId s model.Log.Errorf("MicChangeRPush MicGroupKickOutRPush Marshal MicSystemMsg err:%+v, groupUuid:%v, micContent:%+v", err, groupUid, string(str)) return } + // socket通知被拉黑者退房 + rpc.SendQuitRoom(beKickuserId, 2, txGroupId) if n, err := redisCli.GetRedis().RPush(context.Background(), redis_key.GetMicInfoChange(), string(str)).Result(); err != nil || n == 0 { model.Log.Errorf("MicChangeRPush MicGroupKickOutRPush err:%+v, groupUuid:%v, micContent:%+v", err, groupUid, string(str)) return diff --git a/domain/model/group_m/room.go b/domain/model/group_m/room.go index 363ca95..24131ac 100644 --- a/domain/model/group_m/room.go +++ b/domain/model/group_m/room.go @@ -208,7 +208,7 @@ func RoomLivingLeaveByKick(model *domain.Model, groupUuid string, beKickuserId u Target: beKickExternalId, }, false)*/ - MicGroupKickOutRPush(model, groupUuid, userExternalId, beKickExternalId) + MicGroupKickOutRPush(model, groupUuid, userExternalId, beKickExternalId, beKickuserId) return roomLivingLeave(model, beKickuserId, groupUuid) } diff --git a/domain/service/group_s/group_op.go b/domain/service/group_s/group_op.go index 447925e..2670ae9 100644 --- a/domain/service/group_s/group_op.go +++ b/domain/service/group_s/group_op.go @@ -17,7 +17,9 @@ import ( "git.hilo.cn/hilo-common/utils" "gorm.io/gorm" "hilo-group/_const/enum/group_e" + "hilo-group/_const/enum/msg_e" "hilo-group/_const/redis_key" + "hilo-group/_const/redis_key/group_k" "hilo-group/common" "hilo-group/cv/property_cv" "hilo-group/domain/cache/group_c" @@ -32,6 +34,7 @@ import ( "hilo-group/myerr" "hilo-group/myerr/bizerr" "strconv" + "strings" "time" ) @@ -509,3 +512,118 @@ func dealActDataAfterEnterRoom(myContext *mycontext.MyContext, userId, rideId ui go rpc.AddActPoint(domain.CreateModelContext(myContext), userId, 5, roomId) } } + +// 创建房间,慎用 +func (s *GroupService) CreateGroupMulByUid(userId uint64, num int, micNumType group_e.GroupMicNumType) error { + model := domain.CreateModel(s.svc.CtxAndDb) + + if lock := redisCli.Lock(group_k.GetGroupLockKey(userId), time.Second*5); !lock { + return bizerr.ReqTooFrequent + } + + user, err := user_m.GetUser(model, userId) + if err != nil { + model.Log.Errorf("CreateGroupMulByUid err:%v", err) + return err + } + + // 强行修正为英语,以保证建群成功 + user.Language = utils.DEFAULT_LANG + + // 群组的头像默认为用户头像,群组的名称默认为用户昵称,群简介默认为“s%的群组”,群公告默认为“欢迎来到Hilo” + name := "" + text := res_m.ResMultiText{MsgId: msg_e.MSG_ID_GROUP_NAME, Language: user.Language} + if text.Get(model.Db) == nil { + name = strings.ReplaceAll(text.Content, "{nick}", user.Nick) + } + + introduction := "" + text2 := res_m.ResMultiText{MsgId: msg_e.MSG_ID_GROUP_INTRODUCTION, Language: user.Language} + if text2.Get(model.Db) == nil { + introduction = strings.ReplaceAll(text2.Content, "{nick}", user.Nick) + } + + notification := "" + text3 := res_m.ResMultiText{MsgId: msg_e.MSG_ID_GROUP_NOTIFICATION, Language: user.Language} + if text3.Get(model.Db) == nil { + notification = strings.ReplaceAll(text3.Content, "{nick}", user.Nick) + } + + faceUrl := user.Avatar + + for idx := 0; idx < num; idx++ { + code := group_m.GenerateGroupCode(group_e.GROUP_DEFAULT_CODE_LENGTH) + i := 0 + for ; i < group_e.CREATE_GROUP_MAX_ATTEMPT; i++ { + success, err := res_m.CheckCode(model, code) + if err != nil || !success { + break + } + r, err := group_m.FindGroupByCode(model, code) + if err == nil && r == nil { + break + } + code = group_m.GenerateGroupCode(group_e.GROUP_DEFAULT_CODE_LENGTH) + } + + if i >= group_e.CREATE_GROUP_MAX_ATTEMPT { + return myerr.NewSysError("Failed in generating groupId") + } + + groupId := group_e.OverseaGroupNamePrefix + code + groupId, err = tencentyun.CreateGroup(name, groupId) + if err != nil { + model.Log.Errorf("CreateGroupMulByUid err:%v", err) + return err + } + + channelId := utils.GetUUID() + _, _, err = agora.CreateGroupAgora(channelId, uint32(userId)) + + if err != nil { + // 回滚,删除刚刚建立的TX群组 + tencentyun.DestroyGroup(groupId, false) + model.Log.Errorf("CreateGroupMulByUid err:%v", err) + return err + } + + roomType := group_e.OverseaRoom + g := group_m.GroupInfo{ + ImGroupId: groupId, + TxGroupId: groupId, + Type: uint16(roomType), + Code: code, + OriginCode: code, + Owner: userId, + Name: name, + Introduction: introduction, + Notification: notification, + FaceUrl: faceUrl, + Country: user.Country, + ChannelId: channelId, + MicOn: true, + LoadHistory: false, + MicNumType: micNumType, + TouristMic: 1, + TouristSendMsg: 1, + TouristSendPic: 1, + IsGameRoom: 1, + } + if err := s.CreateGroup(userId, &g); err != nil { + // 回滚,删除刚刚建立的TX群组 + tencentyun.DestroyGroup(groupId, false) + model.Log.Errorf("CreateGroupMulByUid err:%v", err) + return err + } + + gm := group_m.GroupMember{ + GroupId: groupId, + UserId: userId, + } + if err = gm.Create(model.Db); err != nil { + model.Log.Warnf("Failed to set GroupMember +%v", gm) + } + time.Sleep(time.Millisecond * 30) + } + return nil +} diff --git a/route/group_r/group_info.go b/route/group_r/group_info.go index 197c129..a71b61b 100644 --- a/route/group_r/group_info.go +++ b/route/group_r/group_info.go @@ -457,7 +457,11 @@ func GetRoomInfo(c *gin.Context) (*mycontext.MyContext, error) { ThemeUrl: themeUrl, ThemeType: themeType, Role: group_e.GROUP_VISITOR, - GameConfig: &game_m.GameConfig{Ludo: &game_m.GameConfigDiamond{Diamond: game_e.GameLudoDiamondList}, Uno: &game_m.GameConfigDiamond{Diamond: game_e.GameLudoDiamondList}}, + GameConfig: &game_m.GameConfig{ + Ludo: &game_m.GameConfigDiamond{Diamond: game_e.GameLudoDiamondList}, + Uno: &game_m.GameConfigDiamond{Diamond: game_e.GameLudoDiamondList}, + Domino: &game_m.GameConfigDiamond{Diamond: game_e.GameLudoDiamondList}, + }, } roles, _, err := group_m.GetRolesInGroup(model, groupInfo.ImGroupId) diff --git a/route/group_r/group_op.go b/route/group_r/group_op.go index bc05f04..c5ef5f0 100644 --- a/route/group_r/group_op.go +++ b/route/group_r/group_op.go @@ -1730,8 +1730,11 @@ func downgradeRoom(myContext *mycontext.MyContext, gi *group_m.GroupInfo) error // @Param nonce header string true "随机数字" // @Param groupId formData string true "群ID" // @Param password formData string false "房间密码" -// @Param enterType formData int false "进房类型:1.ludo游戏快速匹配进房 2:uno" +// @Param enterType formData int false "进房类型:1.ludo游戏快速匹配进房 2:uno 10.domino" // @Param gameCode formData string false "gameCode" +// @Param is1V1 formData int false "是否1v1,0否1是" +// @Param gameMode formData int false "游戏模式0.快速1.经典" +// @Param is1V1Robot formData int false "是否游戏机器人,0否1是" // @Success 200 {object} group_cv.GroupChannelId // @Router /v1/imGroup/in [put] func GroupIn(c *gin.Context) (*mycontext.MyContext, error) { @@ -1744,6 +1747,9 @@ func GroupIn(c *gin.Context) (*mycontext.MyContext, error) { password := c.PostForm("password") enterType := c.PostForm("enterType") gameCode := c.PostForm("gameCode") + is1V1 := c.PostForm("is1V1") + gameMode := c.PostForm("gameMode") + is1V1Robot := c.PostForm("is1V1Robot") // 把id:9 添加进房间:5030的黑名单 if (userId == 2087771 || userId == 1763211) && groupId == "HTGS#a46766257" { return myContext, bizerr.NoPrivileges @@ -1891,10 +1897,10 @@ func GroupIn(c *gin.Context) (*mycontext.MyContext, error) { }() } // 判断是否需要执行游戏逻辑 - if enterType != "" && gameCode != "" { + if enterType != "" && (gameCode != "" || is1V1Robot == "1") { traceId, _ := c.Get(mycontext.TRACEID) token := c.Writer.Header().Get(mycontext.TOKEN) - err := game_c.SetAutoMathEnterRoom(userId, gi.ImGroupId, cast.ToString(traceId), token, enterType, gameCode) + err := game_c.SetAutoMathEnterRoom(userId, gi.ImGroupId, cast.ToString(traceId), token, enterType, gameCode, is1V1, gameMode, is1V1Robot) if err != nil { model.Log.Errorf("GroupIn cache.SetAutoMathEnterRoom userId:%v, imGroupId:%v, err:%v", userId, gi.ImGroupId, err) } diff --git a/route/group_r/group_setting.go b/route/group_r/group_setting.go index ce4ef33..c01c323 100644 --- a/route/group_r/group_setting.go +++ b/route/group_r/group_setting.go @@ -522,6 +522,8 @@ func AddGroupBlacklist(c *gin.Context) (*mycontext.MyContext, error) { if err == nil { signal_s.SendCustomMsg(model, groupId, nil, string(buf)) } + // socket通知被拉黑者退房 + rpc.SendQuitRoom(user.ID, 1, txGroupId) if err = group_s.NewGroupService(myContext).LeaveGroup(model, groupId, user.ID, externalId); err != nil { return myContext, err @@ -719,6 +721,7 @@ func KickGroupMembers(c *gin.Context) (*mycontext.MyContext, error) { model := domain.CreateModelContext(myContext) + txGroupId := groupId groupId, err = group_m.ToImGroupId(model, groupId) if err != nil { return myContext, err @@ -750,6 +753,8 @@ func KickGroupMembers(c *gin.Context) (*mycontext.MyContext, error) { Source: myExtId, Target: externalId, Content: string(buf)} signal_s.SendSignalMsg(model, groupId, systemMsg, false) } + // socket通知退房 + rpc.SendQuitRoom(user.ID, 2, txGroupId) if err = group_s.NewGroupService(myContext).LeaveGroup(model, groupId, user.ID, externalId); err != nil { return myContext, err diff --git a/route/router.go b/route/router.go index 9d8511c..406bf10 100644 --- a/route/router.go +++ b/route/router.go @@ -48,7 +48,7 @@ func InitRouter() *gin.Engine { imGroup.GET("/ownGroup", wrapper(group_r.GetOwnGroup)) imGroup.GET("/theirGroup/:userExternalId", wrapper(group_r.GetTheirGroups)) imGroup.PUT("/pluginReady/:groupId", wrapper(group_r.PluginReady)) - imGroup.GET("/roomInfo/:groupId", EncryptHandle, wrapper(group_r.GetRoomInfo)) + imGroup.GET("/roomInfo/:groupId", EncryptHandle, wrapper(group_r.GetRoomInfo)) // 进房 // imGroup.GET("/password/:groupId", wrapper(group_r.GetGroupPassword)) imGroup.GET("/role/:groupId", wrapper(group_r.GetGroupRole)) @@ -92,7 +92,7 @@ func InitRouter() *gin.Engine { imGroup.POST("/mic/speech/close", wrapper(group_r.GroupMicSpeechClose)) imGroup.POST("/mic/mute", wrapper(group_r.GroupMicMute)) imGroup.POST("/mic/unmute", wrapper(group_r.GroupMicUnmute)) - imGroup.PUT("/in", wrapper(group_r.GroupIn)) + imGroup.PUT("/in", wrapper(group_r.GroupIn)) // 进房 imGroup.POST("/leave", wrapper(group_r.GroupLeave)) imGroup.POST("/kick", wrapper(group_r.GroupKick)) imGroup.PUT("/user/msg/status", wrapper(group_r.GroupUserMsg)) -- 2.22.0