From 5a78e911d3056fea95a2eb0e5a58573eba5f7f6b Mon Sep 17 00:00:00 2001 From: chenweijian <820961417@qq.com> Date: Tue, 7 Feb 2023 18:38:46 +0800 Subject: [PATCH] =?UTF-8?q?user=E6=9C=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domain/service/event_s/event_init.go | 124 --- domain/service/event_s/group_in.go | 86 -- domain/service/event_s/group_leave.go | 83 -- domain/service/game_s/game.go | 1213 ------------------------- domain/service/game_s/jwt.go | 72 -- domain/service/group_s/group.go | 53 -- resource/consul/consul.go | 4 +- 7 files changed, 2 insertions(+), 1633 deletions(-) delete mode 100755 domain/service/event_s/event_init.go delete mode 100755 domain/service/event_s/group_in.go delete mode 100755 domain/service/event_s/group_leave.go delete mode 100755 domain/service/game_s/game.go delete mode 100755 domain/service/game_s/jwt.go delete mode 100755 domain/service/group_s/group.go diff --git a/domain/service/event_s/event_init.go b/domain/service/event_s/event_init.go deleted file mode 100755 index 57dfb24..0000000 --- a/domain/service/event_s/event_init.go +++ /dev/null @@ -1,124 +0,0 @@ -package event_s - -import ( - "errors" - "hilo-user/_const/enum/user_e" - "hilo-user/domain" - "hilo-user/domain/event/group_ev" - "hilo-user/domain/event/user_ev" - "hilo-user/domain/model/groupPower_m" - "hilo-user/domain/model/group_m" - "hilo-user/domain/model/user_m" - "hilo-user/domain/service/user_s" - "hilo-user/mycontext" - "hilo-user/req/jwt" - "hilo-user/resource/config" - "hilo-user/resource/mysql" -) - -func EventInit() { - GroupInEvents() - GameEventInit() - GroupLeaveEvents() - ModelFuncInit() -} - -// 用户进房事件 -func GroupInEvents() { - group_ev.AddGroupInEventSync(func(model *domain.Model, event interface{}) error { - e, ok := event.(*group_ev.GroupInEvent) - if !ok { - model.Log.Errorf("AddGroupInEventSync event type err") - return nil - } - txGroupId, err := group_m.ToTxGroupId(model, e.GroupId) - if err != nil { - model.Log.Errorf("AddGroupInEventSync err:%v, imGroupId:%v", err, e.GroupId) - return nil - } - return user_s.NewGameService(mycontext.CreateMyContext(model.Cxt)).PushGameInfo("", e.ExternalId, txGroupId, 0) - }) -} - -// 用户退房事件 -func GroupLeaveEvents() { - group_ev.AddGroupLeaveEventAsync(func(model *domain.Model, event interface{}) error { - e, ok := event.(*group_ev.GroupLeaveEvent) - if !ok || e == nil { - model.Log.Errorf("AddGroupLeaveEventAsync event type err") - return nil - } - txGroupId, err := group_m.ToTxGroupId(model, e.GroupId) - if err != nil { - model.Log.Errorf("ToTxGroupId fail:%v-%v", e.GroupId, err) - } - if err := user_s.NewGameService(model.MyContext).GameOpt(e.UserId, 0, "", e.ExternalId, "", "", txGroupId, user_e.GameOptExit, 0, false); err != nil { - model.Log.Warnf("AddGroupLeaveEventAsync GameOpt fail,e%v,err:%v", *e, err) - } - return nil - }) -} - -// 游戏上报事件 -func GameEventInit() { - user_ev.AddReportGameInfoEventSync(func(model *domain.Model, event interface{}) error { - e, ok := event.(*user_ev.ReportGameInfoEvent) - if !ok { - model.Log.Errorf("AddReportGameInfoEventSync 消息类型错误!event:%+v", event) - return nil - } - switch e.ReportType { - case user_e.ReportTypeGameStart: - // 更新游戏信息 - return user_s.NewGameService(model.MyContext).GameStart(e.GameStartObject) - //return user_m.GameStartUpdate(model, e.GameStartObject) - case user_e.ReportTypeGameSettle: - return user_s.NewGameService(model.MyContext).GameSettle(e.GameSettleObject) - } - return nil - }) -} - -func ModelFuncInit() { - group_m.GetGroupPowerNameByUserId = func(model *domain.Model, userId uint64) (uint64, string, error) { - return groupPower_m.GetUserGroupPower(model, userId) - } - // 编辑游戏-清理机器人 - user_ev.AddGameEditEventAsync(func(model *domain.Model, event interface{}) error { - e, ok := event.(*user_ev.GameEditEvent) - if !ok { - return errors.New("GameEditEvent asset fail") - } - robots, err := user_m.GetRoomRobots(model, e.TxGroupId) - if err != nil { - model.Log.Errorf("GetRoomRobots fail:%v", err) - return err - } - model.Log.Infof("AddGameEditEventAsync event:%v,robots:%v", *e, robots) - var userIds []mysql.ID - for _, robot := range robots { - userIds = append(userIds, robot.UserId) - } - users, err := user_m.GetUserMapByIds(model, userIds) - if err != nil { - model.Log.Errorf("GetUserMapByIds fail:%v", err) - return err - } - userService := user_s.NewGameService(model.MyContext) - for i, robot := range robots { - user, ok := users[robot.UserId] - if !ok { - model.Log.Errorf("robot userId not exits:%v", robot) - continue - } - // filled - robots[i].GameOpt = userService.GameOpt // service func -> model func - robots[i].User = users[robot.UserId] // user info - robots[i].Token, _ = jwt.GenerateToken(user.ID, user.ExternalId, - config.GetConfigJWT().ISSUER_API) // jwt - // 离开 - robots[i].Leave("GameEdit") - } - return nil - }) -} diff --git a/domain/service/event_s/group_in.go b/domain/service/event_s/group_in.go deleted file mode 100755 index a110132..0000000 --- a/domain/service/event_s/group_in.go +++ /dev/null @@ -1,86 +0,0 @@ -package event_s - -import ( - "encoding/json" - "golang.org/x/sync/errgroup" - "hilo-user/domain" - "hilo-user/domain/event/group_ev" - "hilo-user/domain/model/event_m" - "hilo-user/domain/service" - "hilo-user/mycontext" - "hilo-user/resource/mysql" - "runtime/debug" -) - -// 每次处理500条 -const BatchCount = 500 - -type GroupInEventService struct { - svc *service.Service -} - -func NewGroupInEventService(myContext *mycontext.MyContext) *GroupInEventService { - svc := service.CreateService(myContext) - return &GroupInEventService{svc} -} - -// -func (s *GroupInEventService) Consume() error { - defer func() { - if err := recover(); err != nil { - s.svc.Log.Errorf("ExceptionHandle GroupInEventService Consume SYSTEM ACTION PANIC: %v, stack: %v", err, string(debug.Stack())) - } - }() - var model = domain.CreateModel(s.svc.CtxAndDb) - events, offset, err := event_m.FetchEventGroupIn(model, BatchCount) - if err != nil { - return err - } - var wg errgroup.Group - for k := range events { - cpEvent := &event_m.EventGroupIn{ - Entity: mysql.Entity{ - ID: events[k].ID, - CreatedTime: events[k].CreatedTime, - UpdatedTime: events[k].UpdatedTime, - }, - Proto: events[k].Proto, - Payload: events[k].Payload, - Mark: events[k].Mark, - } - wg.Go(func() error { - if cpEvent.Mark == mysql.YES { - model.Log.Warnf("already consume msg :%v", cpEvent) - return nil - } - groupInEvent := new(group_ev.GroupInEvent) - if err := json.Unmarshal(cpEvent.Payload, groupInEvent); err != nil { - model.Log.Errorf("json msg fail,event:%v,err:%v", cpEvent, err) - return nil - } - // 发布事件 - if err := group_ev.PublishGroupInEvent(model, groupInEvent); err != nil { - model.Log.Errorf("PublishGroupInEvent,event:%v,err:%v", cpEvent, err) - return err - } - // 标记已经处理 - cpEvent.Model = model - err = cpEvent.MarkDone() - if err != nil { - model.Log.Errorf("consume msg fail,event:%v,err:%v", cpEvent, err) - } - return err - }) - } - err = wg.Wait() - if err != nil { - model.Log.Errorf("batch consume msg has fail,event,err:%v", err) - // 暂时先允许丢数据,继续mark offset - } - // 最后一次提交offset - if len(events) > 0 { - offset.MarkOffset = events[len(events)-1].ID - return offset.Persistence() - } - return nil -} diff --git a/domain/service/event_s/group_leave.go b/domain/service/event_s/group_leave.go deleted file mode 100755 index 70fb0e3..0000000 --- a/domain/service/event_s/group_leave.go +++ /dev/null @@ -1,83 +0,0 @@ -package event_s - -import ( - "encoding/json" - "golang.org/x/sync/errgroup" - "hilo-user/domain" - "hilo-user/domain/event/group_ev" - "hilo-user/domain/model/event_m" - "hilo-user/domain/service" - "hilo-user/mycontext" - "hilo-user/resource/mysql" - "runtime/debug" -) - -type GroupLeaveEventService struct { - svc *service.Service -} - -func NewGroupLeaveEventService(myContext *mycontext.MyContext) *GroupLeaveEventService { - svc := service.CreateService(myContext) - return &GroupLeaveEventService{svc} -} - -// -func (s *GroupLeaveEventService) Consume() error { - defer func() { - if err := recover(); err != nil { - s.svc.Log.Errorf("ExceptionHandle GroupLeaveEventService Consume SYSTEM ACTION PANIC: %v, stack: %v", err, string(debug.Stack())) - } - }() - var model = domain.CreateModel(s.svc.CtxAndDb) - events, offset, err := event_m.FetchEventGroupLeave(model, BatchCount) - if err != nil { - return err - } - var wg errgroup.Group - for k := range events { - cpEvent := &event_m.EventGroupLeave{ - Entity: mysql.Entity{ - ID: events[k].ID, - CreatedTime: events[k].CreatedTime, - UpdatedTime: events[k].UpdatedTime, - }, - Proto: events[k].Proto, - Payload: events[k].Payload, - Mark: events[k].Mark, - } - wg.Go(func() error { - if cpEvent.Mark == mysql.YES { - model.Log.Warnf("already consume msg :%v", cpEvent) - return nil - } - groupLeaveEvent := new(group_ev.GroupLeaveEvent) - if err := json.Unmarshal(cpEvent.Payload, groupLeaveEvent); err != nil { - model.Log.Errorf("json msg fail,event:%v,err:%v", cpEvent, err) - return nil - } - // 发布事件 - if err := group_ev.PublishGroupLeaveEvent(model, groupLeaveEvent); err != nil { - model.Log.Errorf("PublishGroupLeaveEvent,event:%v,err:%v", cpEvent, err) - return err - } - // 标记已经处理 - cpEvent.Model = model - err = cpEvent.MarkDone() - if err != nil { - model.Log.Errorf("consume msg fail,event:%v,err:%v", cpEvent, err) - } - return err - }) - } - err = wg.Wait() - if err != nil { - model.Log.Errorf("batch consume msg has fail,event,err:%v", err) - // 暂时先允许丢数据,继续mark offset - } - // 最后一次提交offset - if len(events) > 0 { - offset.MarkOffset = events[len(events)-1].ID - return offset.Persistence() - } - return nil -} diff --git a/domain/service/game_s/game.go b/domain/service/game_s/game.go deleted file mode 100755 index 4ce8cc2..0000000 --- a/domain/service/game_s/game.go +++ /dev/null @@ -1,1213 +0,0 @@ -package user_s - -import ( - "encoding/json" - "fmt" - "github.com/jinzhu/copier" - "hilo-user/_const/enum/diamond_e" - "hilo-user/_const/enum/group_e" - "hilo-user/_const/enum/user_e" - "hilo-user/common" - "hilo-user/cv/msg_cv" - "hilo-user/cv/user_cv" - "hilo-user/domain" - "hilo-user/domain/cache" - "hilo-user/domain/cache/user_c" - "hilo-user/domain/event/user_ev" - "hilo-user/domain/model/diamond_m" - "hilo-user/domain/model/group_m" - "hilo-user/domain/model/noble_m" - "hilo-user/domain/model/res_m" - "hilo-user/domain/model/user_m" - "hilo-user/domain/service" - "hilo-user/domain/service/group_s" - "hilo-user/mycontext" - "hilo-user/myerr" - "hilo-user/myerr/bizerr" - "hilo-user/mylogrus" - "hilo-user/req/user_req" - "hilo-user/resource/config" - "hilo-user/resource/mysql" - "hilo-user/sdk/sud" - "hilo-user/sdk/tencentyun" - "math" - "sort" - "strconv" - "time" -) - -type GameService struct { - svc *service.Service -} - -func NewGameService(myContext *mycontext.MyContext) *GameService { - svc := service.CreateService(myContext) - return &GameService{svc} -} - -// 生成App客户端code -// param userId 用户id -// condition -// 1.jwt生成,只带userId -// 2.入库 -func (s *GameService) GenClientCode(userId mysql.ID, externalId mysql.Str) (string, error) { - var model = domain.CreateModelContext(s.svc.MyContext) - code, err := generateGameJwtToken(userId, externalId, config.GetConfigGameJWT().ISSUER_CLIENT) - if err != nil { - model.Log.Errorf("generateGameJwtToken fail:%v", err) - return "", err - } - err = s.svc.Transactional(func() error { - // todo 持久化 - return nil - }) - return code, err -} - -// 生成游戏服务器用的ssToken -// return userId ssToken expireDateMs err -func (s *GameService) GetSsToken(code string) (mysql.ID, string, int64, error) { - var model = domain.CreateModelContext(s.svc.MyContext) - userId, externalId, expiresAt, err := ParseJwtToken(code, config.GetConfigGameJWT().ISSUER_CLIENT) - if err != nil { - model.Log.Errorf("ParseJwtToken fail:%v", err) - return userId, "", expiresAt, err - } - ssToken, err := generateGameJwtToken(userId, externalId, config.GetConfigGameJWT().ISSUER_SERVER) - if err != nil { - model.Log.Errorf("generateGameJwtToken fail:%v", err) - return userId, "", expiresAt, err - } - err = s.svc.Transactional(func() error { - // todo 持久化 - return nil - }) - return userId, ssToken, expiresAt, err -} - -// 生成游戏服务器用的ssToken -// return userId ssToken expireDateMs err -func (s *GameService) UpdateSsToken(ssToken string) (mysql.ID, string, int64, error) { - var model = domain.CreateModelContext(s.svc.MyContext) - userId, externalId, expiresAt, err := ParseJwtToken(ssToken, config.GetConfigGameJWT().ISSUER_SERVER) - // err 不需要判断过期 - if err != nil && err != bizerr.GameTokenExpire { - model.Log.Errorf("ParseJwtToken fail:%v", err) - return userId, "", expiresAt, err - } - newSsToken, err := generateGameJwtToken(userId, externalId, config.GetConfigGameJWT().ISSUER_SERVER) - if err != nil { - model.Log.Errorf("generateGameJwtToken fail:%v", err) - return userId, "", expiresAt, err - } - err = s.svc.Transactional(func() error { - // todo 持久化 - return nil - }) - return userId, newSsToken, expiresAt, err -} - -// 游戏服务器信息上报 -func (s *GameService) ReportGameInfo(userInfo user_req.ReportGameInfoReq) error { - model := domain.CreateModel(s.svc.CtxAndDb) - var ( - userRoundId = "" - roomId = "" - ) - reportMsg, err := json.Marshal(userInfo.ReportMsg) - if err != nil { - model.Log.Errorf("ReportGameInfo err:%v, userInfo:%v", err, userInfo) - return err - } - event := &user_ev.ReportGameInfoEvent{ - ReportType: userInfo.ReportType, - } - if userInfo.ReportType == user_e.ReportTypeGameStart { - event.GameStartObject = new(user_ev.GameStartObject) - err = json.Unmarshal(reportMsg, event.GameStartObject) - if err != nil { - model.Log.Errorf("ReportGameInfo err:%v, userInfo:%v", err, userInfo) - return err - } - userRoundId = event.GameStartObject.GameRoundId - roomId = event.GameStartObject.RoomId - } else if userInfo.ReportType == user_e.ReportTypeGameSettle { - event.GameSettleObject = new(user_ev.GameSettleObject) - err = json.Unmarshal(reportMsg, event.GameSettleObject) - if err != nil { - model.Log.Errorf("ReportGameInfo err:%v, userInfo:%v", err, userInfo) - return err - } - userRoundId = event.GameSettleObject.GameRoundId - roomId = event.GameSettleObject.RoomId - } - // 持久化 - err = user_m.SaveGameSdkReport(domain.CreateModelContext(s.svc.MyContext), userRoundId, roomId, string(userInfo.ReportType), string(reportMsg), userInfo.ExternalId, userInfo.SsToken) - if err != nil { - return err - } - return model.Transaction(func(model *domain.Model) error { - userId, err := user_c.ToUserId(model, userInfo.ExternalId) - if err != nil { - return err - } - event.UserId = userId - return user_ev.PublishReportGameInfoEvent(model, event) - }) -} - -func (s *GameService) GameAdd(userId mysql.ID, extId, code, lang string, para *user_m.GameAddParam) error { - var model = domain.CreateModelContext(s.svc.MyContext) - if !user_c.LockGame(model, para.TxGroupId) { - mylogrus.MyLog.Infof("GameAdd LockGame faild TxGroupId:%v", para.TxGroupId) - return bizerr.ReqTooFrequent - } - defer user_c.UnLockGame(model, para.TxGroupId) - - info, err := group_m.GetByTxGroupId(model, para.TxGroupId) - if err != nil { - return myerr.WrapErr(err) - } - // 一个房间只能存在一个还未结束的游戏 - // 房主/经理/管理员可以创建游戏,其它用户点击提示“仅房间管理可以创建游戏” - role, err := group_m.GetRoleInGroup(model, userId, info.ImGroupId) - if err != nil { - return err - } - if role < common.GROUP_ADMIN { - return bizerr.GameAddNoPermissions - } - // 在麦上才能创建游戏 - micUser, err := group_m.GetMicUserByExternalId(model, extId) - if err != nil { - return err - } - if micUser == nil { - return bizerr.GameAddNotOnMic - } - mgId := "" - switch para.GameType { - case 1: - mgId = user_e.MgIdLudo - case 2: - mgId = user_e.MgIdUno - } - // 创建游戏 - userInfo := &user_m.GameInfo{ - MgId: mgId, - GameType: para.GameType, - Mode: int32(para.Mode), - Piece: int32(para.Piece), - OnOff1: uint8(para.OnOff1), - Diamond: para.Diamond, - CreateId: userId, - TxGroupId: info.TxGroupId, - AutoMatch: uint8(para.AutoMatch), - } - err = model.Transaction(func(model *domain.Model) error { - err = user_m.Add(model, userInfo) - if err != nil { - return myerr.WrapErr(bizerr.GameHaveNoEnd) - } - // 自己作为游戏成员加入游戏 - err = user_m.SaveGamePlayer(model, &user_m.GamePlayer{GameId: userInfo.Id, UserId: userId, UserCode: code, ExternalId: extId, CreatedTime: time.Now(), SeatIdx: 0}) - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return myerr.WrapErr(bizerr.GameHaveNoEndGame) - } - - if userInfo.Diamond > 0 { - // 扣费 - diamondAccount, err := diamond_m.CheckEnoughDiamondFrozen(model, userId, mysql.Num(userInfo.Diamond)) - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return err - } - diamondAccountDetail, err := diamondAccount.ChangeDiamondAccountDetail(diamond_e.GameJoin, userInfo.Id, mysql.Num(userInfo.Diamond)) - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return err - } - err = diamondAccountDetail.Persistent() - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return err - } - } - // 游戏相关操作 - err = s.afterCreate(model, userInfo, para.GameCode, extId) - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return err - } - return nil - }) - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return err - } - go s.SendGamePublicMsg(model, userId, info.TxGroupId, lang, userInfo.GameType, user_e.GameOptCreate) - go s.PushGameInfo("", extId, "", userInfo.Id) - - return nil -} - -func (s *GameService) afterCreate(model *domain.Model, userInfo *user_m.GameInfo, userCode, extId string) error { - // 清理房间游戏 - err := sud.RoomClear(domain.CreateModelNil(), userInfo.MgId, sud.RoomClearReqData{RoomId: userInfo.TxGroupId}) - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return myerr.WrapErr(err) - } - mode := int32(0) - if userInfo.MgId == user_e.MgIdLudo { - mode = userInfo.Mode - } - // 加入游戏 - err = sud.UserIn(model, userInfo.MgId, sud.UserInReqData{ - Code: userCode, - RoomId: userInfo.TxGroupId, - Mode: mode, - Language: "zh-CN", - SeatIndex: -1, - }) - // 设置游戏 - if userInfo.MgId == user_e.MgIdLudo { - if err = sud.GameSetting(model, userInfo.MgId, sud.GameSettingReqData{ - RoomId: userInfo.TxGroupId, - LudoRule: sud.LudoRule{Mode: int(userInfo.Mode), ChessNum: int(userInfo.Piece), Item: int(userInfo.OnOff1)}, - }); err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return myerr.WrapErr(err) - } - } - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return myerr.WrapErr(err) - } - // 准备游戏 - err = sud.UserReady(model, userInfo.MgId, sud.UserReadyReqData{ExternalId: extId, IsReady: true}) - if err != nil { - model.Log.Errorf("CreateGame err:%v", err) - return myerr.WrapErr(err) - } - return nil -} - -func (s *GameService) GameEdit(para *user_m.GameAddParam, userId uint64, extId, code string) error { - var model = domain.CreateModelContext(s.svc.MyContext) - - // 查询游戏是否存在 - userInfo, err := user_m.GetGameInfo(model, para.GameId, "", "", -1, -1) - if err != nil { - mylogrus.MyLog.Errorf("GameEdit err:%v", err) - return bizerr.InvalidParameter - } - if userInfo.Id == 0 { - mylogrus.MyLog.Errorf("GameEdit err:%v", err) - return bizerr.GameNotFound - } - // 加锁 - if !user_c.LockGame(model, userInfo.TxGroupId) { - mylogrus.MyLog.Infof("GameEdit LockGame faild TxGroupId:%v", para.TxGroupId) - return bizerr.ReqTooFrequent - } - defer user_c.UnLockGame(model, userInfo.TxGroupId) - - // 开始了不能编辑 - if userInfo.BattleStartAt > 0 { - return bizerr.GameStart - } - // 钻石不能编辑 - if userInfo.Diamond != para.Diamond { - return bizerr.GameDiamondCannotEdit - } - // 放入事务 - err = model.Transaction(func(model *domain.Model) error { - // 编辑user - err = user_m.Edit(model, userInfo.Id, para) - if err != nil { - model.Log.Errorf("GameEdit err:%v", err) - return err - } - // 设置游戏 - if userInfo.MgId == user_e.MgIdLudo { - if err = sud.GameSetting(domain.CreateModelNil(), userInfo.MgId, sud.GameSettingReqData{ - RoomId: userInfo.TxGroupId, - LudoRule: sud.LudoRule{Mode: para.Mode, ChessNum: para.Piece, Item: para.OnOff1}, - }); err != nil { - model.Log.Errorf("GameEdit err:%v", err) - return myerr.WrapErr(err) - } - } - return nil - }) - //err = s.svc.Transactional(func() error { - // model := domain.CreateModelContext(s.svc.MyContext) - // // 编辑user - // err = user_m.Edit(model, userInfo.Id, para) - // if err != nil { - // model.Log.Errorf("GameEdit err:%v", err) - // return err - // } - // //// 钻石前后不一致 - // //if userInfo.Diamond != para.Diamond { - // // // 所有用户退款 - // // err = s.userRefund(model, userInfo) - // // if err != nil { - // // model.Log.Errorf("GameEdit err:%v", err) - // // return myerr.WrapErr(err) - // // } - // // if para.Diamond > 0 { - // // // 扣费 - // // diamondAccount, err := diamond_m.CheckEnoughDiamondFrozen(model, userId, mysql.Num(para.Diamond)) - // // if err != nil { - // // model.Log.Errorf("GameEdit err:%v", err) - // // return err - // // } - // // diamondAccountDetail, err := diamondAccount.ChangeDiamondAccountDetail(diamond_e.GameJoin, userInfo.Id, mysql.Num(para.Diamond)) - // // if err != nil { - // // model.Log.Errorf("GameEdit err:%v", err) - // // return err - // // } - // // err = diamondAccountDetail.Persistent() - // // if err != nil { - // // model.Log.Errorf("GameEdit err:%v", err) - // // return err - // // } - // // } - // // // 编辑者重新加入游戏 - // // err = user_m.SaveGamePlayer(model, &user_m.GamePlayer{GameId: userInfo.Id, UserId: userId, UserCode: code, ExternalId: extId, CreatedTime: time.Now()}) - // // if err != nil { - // // model.Log.Errorf("GameEdit err:%v", err) - // // return err - // // } - // // // 游戏相关操作 - // // userInfo.Mode, userInfo.Piece, userInfo.OnOff1 = int32(para.Mode), int32(para.Piece), uint8(para.OnOff1) - // // err = s.afterCreate(model, userInfo, para.GameCode, extId) - // // if err != nil { - // // model.Log.Errorf("CreateGame err:%v", err) - // // return err - // // } - // // // 发布事件 - // // event := &user_ev.GameEditEvent{GameId: userInfo.Id, TxGroupId: userInfo.TxGroupId} - // // if err = user_ev.PublishGameEditEvent(model, event); err != nil { - // // model.Log.Errorf("PublishGameEditEvent,event:%v,err:%v", event, err) - // // return err - // // } - // //} else { - // // // 设置游戏 - // // err = sud.GameSetting(domain.CreateModelNil(), userInfo.MgId, sud.GameSettingReqData{ - // // RoomId: userInfo.TxGroupId, - // // LudoRule: sud.LudoRule{Mode: para.Mode, ChessNum: para.Piece, Item: para.OnOff1}, - // // }) - // //} - // // 设置游戏 - // if userInfo.MgId == user_e.MgIdLudo { - // if err = sud.GameSetting(domain.CreateModelNil(), userInfo.MgId, sud.GameSettingReqData{ - // RoomId: userInfo.TxGroupId, - // LudoRule: sud.LudoRule{Mode: para.Mode, ChessNum: para.Piece, Item: para.OnOff1}, - // }); err != nil { - // model.Log.Errorf("GameEdit err:%v", err) - // return myerr.WrapErr(err) - // } - // } - // return nil - //}) - go s.PushGameInfo("", "", "", userInfo.Id) - return nil -} - -func (s *GameService) PushGameInfo(sourceExtId, targetExtId, txGroupId string, userId uint64) error { - defer common.CheckGoPanic() - var model = domain.CreateModelContext(s.svc.MyContext) - var userInfo *user_m.GameInfo - var err error - if userId > 0 { - userInfo, err = user_m.GetGameInfo(model, userId, "", "", -1, -1) - } else { - // 房间当前是否有未结束的游戏 - userInfo, err = user_m.GetGamingInfo(model, txGroupId) - } - if err != nil { - model.Log.Errorf("PushGameInfo err:%v", err) - return err - } - if userInfo == nil || userInfo.Id == 0 { - return nil - } - // 获取玩家信息 - userPlayers, err := user_m.GetGamePlayers(model, userInfo.Id) - if err != nil { - model.Log.Errorf("PushGameInfo err:%v", err) - return err - } - // 组装信令推送消息 - var creatorExternalId string - playerMsg := make([]*user_cv.GamePlayerMsg, 0, len(userPlayers)) - for _, v := range userPlayers { - tmp := &user_cv.GamePlayerMsg{Status: v.Status, IsEscaped: v.IsEscaped, SeatIdx: v.SeatIdx} - userTiny, err := user_c.GetUserTinyById(model, v.UserId) - if err != nil { - model.Log.Errorf("PushGameInfo err:%v", err) - return err - } - tmp.UserTiny = userTiny - playerMsg = append(playerMsg, tmp) - if v.UserId == userInfo.CreateId { - creatorExternalId = userTiny.ExternalId - } - } - msg := &user_cv.GameMsg{ - GameId: userInfo.Id, - MgId: userInfo.MgId, - GameType: userInfo.GameType, - Mode: userInfo.Mode + 1, // 客户端那边是:1.quick 2.classic - Piece: userInfo.Piece, - OnOff1: userInfo.OnOff1, - Diamond: userInfo.Diamond, - Status: userInfo.Status, - AutoMatch: userInfo.AutoMatch, - ExternalId: creatorExternalId, - Players: playerMsg, - } - jsonMsg, err := json.Marshal(msg) - if err != nil { - model.Log.Errorf("PushGameInfo err:%v", err) - return err - } - msgId := group_e.GroupGameInfoLudo - if userInfo.MgId == user_e.MgIdUno { - msgId = group_e.GroupGameInfoUno - } - - // 发送腾讯云信令 - group_s.SendSignalMsg(model, "", userInfo.TxGroupId, group_m.GroupSystemMsg{ - MsgId: msgId, - Source: sourceExtId, - Target: targetExtId, - Content: string(jsonMsg), - }, false) - return nil -} - -func (s *GameService) GameOpt(userId, userId uint64, code, extId, lang, userCode, txGroupId string, opt user_e.GameOpt, seatIdx int8, isAi bool) (err error) { - var model = domain.CreateModelContext(s.svc.MyContext) - // log - go user_m.SaveGameOptLog(model, userId, userId, opt, txGroupId) - - // 查询游戏是否存在 - var userInfo *user_m.GameInfo - if opt == user_e.GameOptExit { - userInfo, err = user_m.GetGamingInfoByUserId(model, userId, txGroupId) - if err != nil { - return bizerr.InvalidParameter - } - if userInfo == nil { - return - } - } else { - userInfo, err = user_m.GetGameInfo(model, userId, "", "", -1, -1) - if err != nil { - return bizerr.InvalidParameter - } - } - if userInfo.Id == 0 { - model.Log.Errorf("GameOpt userInfo.Id = 0") - return bizerr.GameNotFound - } - // 玩家信息 - userr, err := user_m.GetGamePlayer(model, userInfo.Id, userId) - if err != nil { - return err - } - - switch opt { - case user_e.GameOptJoin: - err = s.joinGame(model, userr, userInfo, userId, code, extId, userCode, seatIdx, isAi) - if err != nil { - model.Log.Errorf("GameOpt joinGame err:%v", err) - return err - } - if !isAi { // 机器人没有加入腾讯云,发不了公屏 - go s.SendGamePublicMsg(model, userId, userInfo.TxGroupId, lang, userInfo.GameType, user_e.GameOptJoin) - } - case user_e.GameOptExit: - if userInfo.Status == uint8(user_e.GameStatusNoStart) { - if userInfo.CreateId == userr.UserId { - err = s.OwnerGameClear(model, userInfo.Id) - if err != nil { - model.Log.Errorf("GameOpt err:%v", err) - return err - } - } else { - err = s.exitGame(model, userr, userInfo) - if err != nil { - model.Log.Errorf("GameOpt err:%v", err) - return err - } - } - } else if userInfo.Status == uint8(user_e.GameStatusGaming) && userr.IsAi != 1 { // 给sdk发退出游戏 - err = sud.GameEnd(domain.CreateModelNil(), userInfo.MgId, sud.GameEndReqData{ - RoomId: userInfo.TxGroupId, ExternalId: userr.ExternalId, - }) - if err != nil { - model.Log.Errorf("GameOpt sud.GameEnd err:%v", err) - } - err = user_m.UpdateGamePlayerExit(model, userr.Id) - if err != nil { - model.Log.Errorf("GameOpt sud.GameEnd err:%v", err) - } - if userInfo.GameType == user_e.GameTypeUno { - // 如果只是剩下一个玩家,直接结束掉 - if userPlayers, err := user_m.GetGamePlayers(model, userInfo.Id); err != nil { - model.Log.Errorf("GameOpt GetGamePlayers err:%v", err) - return err - } else { - var leftPlayer int - for _, player := range userPlayers { - if player.EndAt == 0 { - leftPlayer++ - } - } - if leftPlayer <= 1 { - model.Log.Infof("GameOpt left player 1,roomClear:%v,players:%v", userInfo, userPlayers) - if err := sud.RoomClear(model, userInfo.MgId, sud.RoomClearReqData{RoomId: userInfo.TxGroupId}); err != nil { - model.Log.Infof("GameOpt RoomClear fail,user:%v:%v", *userInfo, err) - } - } - } - } - } - } - go s.PushGameInfo("", "", "", userInfo.Id) - return nil -} - -func (s *GameService) joinGame(model *domain.Model, userr *user_m.GamePlayer, userInfo *user_m.GameInfo, userId uint64, - code, extId, userCode string, seatIdx int8, isAi bool) error { - - if !isAi && userCode == "" { - model.Log.Errorf("joinGame err:%v", bizerr.InvalidParameter) - return bizerr.InvalidParameter - } - if userr.Id > 0 { - model.Log.Errorf("joinGame err:%v", bizerr.GameAlreadyJoin) - return bizerr.GameAlreadyJoin - } - if userInfo.Status != uint8(user_e.GameStatusNoStart) { - return bizerr.GameJoinFailed - } - // 在麦上才能加入游戏 - micUser, err := group_m.GetMicUserByExternalId(model, extId) - if err != nil { - return err - } - if micUser == nil { - return bizerr.GameAddNotOnMic - } - if !user_c.LockGame(model, userInfo.TxGroupId) { - mylogrus.MyLog.Infof("joinGame LockGame faild TxGroupId:%v", userInfo.TxGroupId) - return bizerr.ReqTooFrequent - } - defer user_c.UnLockGame(model, userInfo.TxGroupId) - - return model.Transaction(func(model *domain.Model) error { - var isAiInt uint8 - if isAi { - isAiInt = 1 - } - userInfoNew, err := user_m.GetGameInfo(model, userInfo.Id, "", "", -1, -1) - if err != nil { - return bizerr.InvalidParameter - } - if userInfoNew.Status != uint8(user_e.GameStatusNoStart) { // 游戏状态不对,不能加入 - return bizerr.GameJoinFailed - } - - if !isAi && userInfo.Diamond > 0 { - // 扣费 - diamondAccount, err := diamond_m.CheckEnoughDiamondFrozen(model, userId, mysql.Num(userInfo.Diamond)) - if err != nil { - model.Log.Errorf("joinGame err:%v", err) - return err - } - diamondAccountDetail, err := diamondAccount.ChangeDiamondAccountDetail(diamond_e.GameJoin, userInfo.Id, mysql.Num(userInfo.Diamond)) - if err != nil { - model.Log.Errorf("joinGame err:%v", err) - return err - } - err = diamondAccountDetail.Persistent() - if err != nil { - model.Log.Errorf("joinGame err:%v", err) - return err - } - } - userr.GameId = userInfo.Id - userr.UserId = userId - userr.UserCode = code - userr.SeatIdx = seatIdx - userr.ExternalId = extId - userr.IsAi = isAiInt - userr.CreatedTime = time.Now() - // 保存游戏玩家信息 - err = user_m.SaveGamePlayer(model, userr) - if err != nil { - mylogrus.MyLog.Infof("joinGame SaveGamePlayer faild:%v, err:%v", userr, err) - return bizerr.GameHaveNoEndGame - } - err = s.sendJoinToSDK(model, userr, userInfo, isAi, userCode, extId) - if err != nil { - model.Log.Errorf("joinGame err:%v", err) - return err - } - return nil - }) -} - -func (s *GameService) exitGame(model *domain.Model, userr *user_m.GamePlayer, userInfo *user_m.GameInfo) error { - lockKey := user_c.GetGameKey(userInfo.TxGroupId) - if !cache.TryLock(model, lockKey, time.Millisecond*150, time.Minute*5) { - mylogrus.MyLog.Infof("exitGame LockGame faild TxGroupId:%v", userInfo.TxGroupId) - return bizerr.ReqTooFrequent - } - defer cache.UnLock(model, lockKey) - - //if !user_c.LockGame(model, userInfo.TxGroupId) { - // mylogrus.MyLog.Infof("exitGame LockGame faild TxGroupId:%v", userInfo.TxGroupId) - // return bizerr.ReqTooFrequent - //} - //defer user_c.UnLockGame(model, userInfo.TxGroupId) - - return model.Transaction(func(model *domain.Model) error { - err := user_m.DelGamePlayer(model, userr.Id) - if err != nil { - model.Log.Errorf("GameOpt err:%v", err) - return err - } - // 玩家退费 - err = s.userrRefund(model, userr, userInfo) - if err != nil { - model.Log.Errorf("GameOpt err:%v", err) - return err - } - // 判断游戏是否还有人 - players, err := user_m.GetGamePlayers(model, userInfo.Id) - if err != nil { - model.Log.Errorf("GameOpt err:%v", err) - return err - } - // 是否都是机器人 - allAi := true - for _, v := range players { - if v.IsAi != 1 { - allAi = false - break - } - } - if len(players) == 0 || allAi { - // 修改所有游戏玩家状态 - err = user_m.GameCloseUpdatePlayer(model, userInfo) - if err != nil { - return err - } - err = sud.RoomClear(domain.CreateModelNil(), userInfo.MgId, sud.RoomClearReqData{ - RoomId: userInfo.TxGroupId, - }) - // 修改游戏状态 - err = user_m.GameCloseUpdate(model, userInfo) - if err != nil { - return err - } - } else { - sud.UserReady(domain.CreateModelNil(), userInfo.MgId, sud.UserReadyReqData{ - ExternalId: userr.ExternalId, IsReady: false, - }) - //if err != nil { - // model.Log.Errorf("GameOpt err:%v", err) - // //return err - //} - sud.UserOut(domain.CreateModelNil(), userInfo.MgId, sud.UserOutReqData{ - ExternalId: userr.ExternalId, - }) - //if err != nil { - // model.Log.Errorf("GameOpt err:%v", err) - // //return err - //} - } - return nil - }) -} - -func (s *GameService) sendJoinToSDK(model *domain.Model, userr *user_m.GamePlayer, userInfo *user_m.GameInfo, isAi bool, userCode, extId string) (err error) { - if isAi { - user, err := user_c.GetUserTinyById(model, userr.UserId) - if err != nil { - model.Log.Errorf("sendJoinToSDK err:%v", err) - return err - } - gender := "male" - if user.Sex == 2 { - gender = "female" - } - return sud.AddAi(domain.CreateModelNil(), userInfo.MgId, sud.AiAddReqData{ - RoomId: userInfo.TxGroupId, - AiPlayers: []sud.AiPlayer{{user.ExternalId, user.Avatar, user.Nick, gender}}, - IsReady: 1, - }) - } - mode := int32(0) - if userInfo.GameType == user_e.GameTypeLudo { - mode = userInfo.Mode - } - err = sud.UserIn(domain.CreateModelNil(), userInfo.MgId, sud.UserInReqData{ - Code: userCode, - RoomId: userInfo.TxGroupId, - Mode: mode, - Language: "zh-CN", - SeatIndex: -1, - }) - if err != nil { - model.Log.Errorf("sendJoinToSDK err:%v", err) - return myerr.WrapErr(bizerr.GameJoinFailed) - } - err = sud.UserReady(domain.CreateModelNil(), userInfo.MgId, sud.UserReadyReqData{ - ExternalId: extId, - IsReady: true, - }) - if err != nil { - model.Log.Errorf("sendJoinToSDK err:%v", err) - return myerr.WrapErr(bizerr.GameJoinFailed) - } - return nil -} - -func (s *GameService) GameStart(userStart *user_ev.GameStartObject) error { - return s.svc.Transactional(func() error { - model := domain.CreateModel(s.svc.CtxAndDb) - return user_m.GameStartUpdate(model, userStart) - }) -} - -func (s *GameService) GameSettle(userSettle *user_ev.GameSettleObject) error { - model := domain.CreateModel(s.svc.CtxAndDb) - // 查询游戏 - infoKey, err := strconv.Atoi(userSettle.ReportGameInfoKey) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return myerr.WrapErr(bizerr.GameNotFound) - } - userInfo, err := user_m.GetGameInfo(model, uint64(infoKey), "", "", -1, 1) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return myerr.WrapErr(bizerr.GameNotFound) - } - if userInfo.Id == 0 { - model.Log.Errorf("GameSettle err:%v, GameRoundId:%v", bizerr.GameNotFound, userSettle.GameRoundId) - return myerr.WrapErr(bizerr.GameNotFound) - } - err = model.Transaction(func(model *domain.Model) error { - // 计算排名奖励 - userExtIds, winList, userSettle2, err := s.calcAwardDiamond(userSettle, userInfo) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return err - } - userSettle = userSettle2 - if userInfo.Diamond > 0 { - userMap, err := user_m.GetGamePlayersMap(model, userInfo.Id, userExtIds) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return err - } - if userInfo.Status == 1 { // 避免多发 - // 发奖励 - err = s.sendAwardDiamond(model, userInfo, winList, userMap) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return err - } - } - } - // 更新游戏信息、玩家信息 - err = user_m.GameSettleUpdate(model, userSettle) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return err - } - - return nil - }) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return err - } - if userInfo.Status == 1 { // 因为sdk可能有多个settle上报过来,所以这里只处理游戏状态还没转变的 - // 组装信令推送消息 - model := domain.CreateModelContext(model.MyContext) - go s.userSettlePushMsg(model, userSettle, userInfo.TxGroupId, userInfo.CreateId, userInfo.GameType) - } - return nil -} - -func (s *GameService) calcAwardDiamond(userSettle *user_ev.GameSettleObject, userInfo *user_m.GameInfo) ([]string, - []*user_ev.PlayerResultObject, *user_ev.GameSettleObject, error) { - // 计算奖励 - userExtIds := make([]string, 0) - allDiamond := float64(userInfo.Diamond) * float64(len(userSettle.Results)) - winList := make([]*user_ev.PlayerResultObject, 0, len(userSettle.Results)) - diamondMap := make(map[string]int64) - for _, v := range userSettle.Results { - userExtIds = append(userExtIds, v.Uid) - // 逃跑不算win - if v.IsEscaped != 1 { - tmpWin := new(user_ev.PlayerResultObject) - copier.Copy(tmpWin, &v) - tmpWin.LudoExtras = new(user_ev.LudoExtras) - json.Unmarshal([]byte(tmpWin.Extras), &tmpWin.LudoExtras) - winList = append(winList, tmpWin) - } - } - switch userInfo.GameType { - case user_e.GameTypeLudo: - // 排序:isWin -> score -> steps - sort.Slice(winList, func(i, j int) bool { - if winList[i].IsWin == 2 && winList[j].IsWin != 2 { - return true - } - if winList[i].Score > winList[j].Score { - return true - } - if winList[i].LudoExtras.Steps >= winList[j].LudoExtras.Steps { - return true - } - return false - }) - if len(userSettle.Results) > 2 { // 游戏人数大于2人,2人获胜瓜分 - for i, v := range winList { - switch i { - case 0: - v.Diamond = int64(math.Floor(allDiamond * 0.65)) - case 1: - v.Diamond = int64(math.Floor(allDiamond * 0.30)) - default: - v.Diamond = int64(userInfo.Diamond) * -1 - } - diamondMap[v.Uid] = v.Diamond - } - } else { - for i, v := range winList { - if i == 0 { - v.Diamond = int64(math.Floor(allDiamond * 0.95)) - } else { - v.Diamond = int64(userInfo.Diamond) * -1 - } - diamondMap[v.Uid] = v.Diamond - } - } - case user_e.GameTypeUno: - // 排序:isWin -> score - sort.Slice(winList, func(i, j int) bool { - if winList[i].IsWin == 2 && winList[j].IsWin != 2 { - return true - } - return winList[i].Score > winList[j].Score - }) - if len(winList) > 0 { - // 第一名获得游戏分成的95%,系统抽成5% - diamond := int64(math.Floor(allDiamond * 0.95)) - winList[0].Diamond = diamond - diamondMap[winList[0].Uid] = diamond - } - } - // 给客户端的返回结果赋值 - for i, v := range userSettle.Results { - if winDia, ok := diamondMap[v.Uid]; ok { - userSettle.Results[i].Diamond = winDia - if winDia > 0 { - userSettle.Results[i].IsWin = 2 - } - } else { - userSettle.Results[i].Diamond = int64(userInfo.Diamond) * -1 - } - } - return userExtIds, winList, userSettle, nil -} - -func (s *GameService) sendAwardDiamond(model *domain.Model, userInfo *user_m.GameInfo, winList []*user_ev.PlayerResultObject, userMap map[string]*user_m.GamePlayer) error { - if userInfo.Status != uint8(user_e.GamerStatusGaming) { - return nil - } - for _, v := range winList { - if v.Diamond <= 0 || v.IsAi == 1 { - continue - } - player, ok := userMap[v.Uid] - if !ok { - mylogrus.MyLog.Errorf("sendAwardDiamond 找不到用户 extId:%v, userMap:%v", v.Uid, userMap) - continue - } - diamondAccount, err := diamond_m.GetDiamondAccountByUserId(model, player.UserId) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return err - } - diamondAccountDetail, err := diamondAccount.ChangeDiamondAccountDetail(diamond_e.GameAward, userInfo.Id, mysql.Num(v.Diamond)) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return err - } - err = diamondAccountDetail.Persistent() - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return err - } - } - return nil -} - -func (s *GameService) userSettlePushMsg(model *domain.Model, userSettle *user_ev.GameSettleObject, txGroupId string, createId uint64, userType user_e.GameType) { - defer common.CheckGoPanic() - if txGroupId == "" { - model.Log.Errorf("userSettlePushMsg txGroupId is null") - return - } - createExtId := "" - // 组装信令推送消息 - playerMsg := make([]*user_cv.GameAwardPlayer, 0, len(userSettle.Results)) - for _, v := range userSettle.Results { - tmp := &user_cv.GameAwardPlayer{Rank: v.Rank, IsWin: v.IsWin == 2, Diamond: v.Diamond} - userTiny, err := user_c.GetUserByExternalId(model, v.Uid) - if err != nil { - model.Log.Errorf("PushGameInfo err:%v,v:%v,userSettle:%v", err, v, *userSettle) - continue - } - tmp.UserTiny = userTiny - playerMsg = append(playerMsg, tmp) - if userTiny.ID == createId { - createExtId = userTiny.ExternalId - } - } - msg := &user_cv.GameAward{ - OwnerId: createExtId, - Players: playerMsg, - } - jsonMsg, err := json.Marshal(msg) - if err != nil { - model.Log.Errorf("GameSettle err:%v", err) - return - } - //time.Sleep(time.Second * 2) // 延迟两秒,避免客户端棋子没有走完就弹结算 - // 发送腾讯云信令 - msgId := group_e.GroupGameSettleLudo - if userType == user_e.GameTypeUno { - msgId = group_e.GroupGameSettleUno - } - group_s.SendSignalMsg(model, "", txGroupId, group_m.GroupSystemMsg{ - MsgId: msgId, - Content: string(jsonMsg), - }, false) -} - -func (s *GameService) SendGamePublicMsg(model *domain.Model, userId uint64, txGroupId, lang string, userType user_e.GameType, opt user_e.GameOpt) error { - defer common.CheckGoPanic() - user, err := user_c.GetUserTinyById(model, userId) - if err != nil { - model.Log.Errorf("SendGamePublicMsg err:%v", err) - return err - } - nobleLevel, err := noble_m.GetNobleLevel(model.Db, userId) - if err != nil { - model.Log.Errorf("SendGamePublicMsg err:%v", err) - return err - } - // 公屏内容 - userName := "Game" - switch userType { - case user_e.GameTypeLudo: - userName = "Ludo" - case user_e.GameTypeUno: - userName = "Uno" - } - msgTmp := "Take mic and create a user" - msgId := common.MSG_ID_GAME_CREATE - msgContent := msgTmp - if opt == user_e.GameOptJoin { - msgTmp = "I joined the %s" - msgId = common.MSG_ID_GAME_JOIN - msgContent = fmt.Sprintf(msgTmp, userName) - } - if resMul, _ := res_m.GetResMultiTextBy(model.Db, msgId, lang); resMul != nil { - msgContent = resMul.Content - if opt == user_e.GameOptJoin { - msgContent = fmt.Sprintf(resMul.Content, userName) - } - } - - typeScreen := group_e.GameLudoPubMsg - if userType == user_e.GameTypeUno { - typeScreen = group_e.GameUnoPubMsg - } - msg := msg_cv.GamePublicMsg{CommonPublicMsg: msg_cv.CommonPublicMsg{Type: typeScreen, GameType: userType, - ExternalId: user.ExternalId, Nick: user.Nick, Avatar: user.Avatar, NobleLevel: nobleLevel}, - Msg: msgContent} - body, err := json.Marshal(msg) - if err != nil { - return myerr.WrapErr(err) - } - //发送公屏消息, - u, err := tencentyun.SendCustomMsg(model.Log, txGroupId, &user.ExternalId, string(body), group_m.GetHiloUserInfo(domain.CreateModelContext(model.MyContext), user.ExternalId)) - model.Log.Infof("SendGamePublicMsg result response.MsgSeq:%v, err:%v", u, err) - return err -} - -func (s *GameService) GameQuickMatch(userId uint64, externalId string, userType user_e.GameType) (txGroupId, userCode string, err error) { - var model = domain.CreateModelContext(s.svc.MyContext) - - txGroupId, err = user_m.GetGamingTxGroupId(model, userType) - if err != nil { - return "", "", myerr.WrapErr(err) - } - if txGroupId == "" { - // 获取自己房间的id - groupInfo, err := group_m.GetGroupInfoByOwner(model, userId) - if err != nil { - return "", "", myerr.WrapErr(err) - } - if groupInfo == nil { // 自己没有房间 - return "", "", myerr.WrapErr(bizerr.GameHaveNoMyRoom) - } - txGroupId = groupInfo.TxGroupId - } - // 获取userCode - userCode, err = s.GenClientCode(userId, externalId) - if err != nil { - return "", "", myerr.WrapErr(err) - } - return -} - -// 游戏房间主人清理 -func (s *GameService) OwnerGameClear(model *domain.Model, userId uint64) error { - userInfo, err := user_m.GetGameInfo(model, userId, "", "", -1, -1) - if err != nil { - model.Log.Errorf("GameClear err:%v", err) - return myerr.WrapErr(err) - } - lockKey := user_c.GetGameKey(userInfo.TxGroupId) - if !cache.TryLock(model, lockKey, time.Millisecond*150, time.Minute*5) { - mylogrus.MyLog.Infof("OwnerGameClear LockGame faild TxGroupId:%v", userInfo.TxGroupId) - return bizerr.ReqTooFrequent - } - defer cache.UnLock(model, lockKey) - //if !user_c.LockGame(model, userInfo.TxGroupId) { - // mylogrus.MyLog.Infof("OwnerGameClear LockGame faild TxGroupId:%v", userInfo.TxGroupId) - // return bizerr.ReqTooFrequent - //} - //defer user_c.UnLockGame(model, userInfo.TxGroupId) - - return model.Transaction(func(model *domain.Model) error { - // 修改游戏状态 - err = user_m.GameCloseUpdate(model, userInfo) - if err != nil { - model.Log.Errorf("GameClear err:%v", err) - return err - } - // 用户退费 - err = s.userRefund(model, userInfo) - if err != nil { - model.Log.Errorf("GameClear err:%v", err) - return myerr.WrapErr(err) - } - // 清理房间游戏 - err = sud.RoomClear(domain.CreateModelNil(), userInfo.MgId, sud.RoomClearReqData{RoomId: userInfo.TxGroupId}) - if err != nil { - model.Log.Errorf("GameClear err:%v", err) - return myerr.WrapErr(err) - } - return nil - }) -} - -// 游戏房间清理,所有人踢出游戏,退钻,游戏置为结束;拿到房间锁之后才能调用该方法 -func (s *GameService) GameClear(model *domain.Model, userId uint64) error { - userInfo, err := user_m.GetGameInfo(model, userId, "", "", -1, -1) - if err != nil { - model.Log.Errorf("GameClear err:%v", err) - return myerr.WrapErr(err) - } - // 用户退费 - err = s.userRefund(model, userInfo) - if err != nil { - model.Log.Errorf("GameClear err:%v", err) - return myerr.WrapErr(err) - } - // 修改游戏状态 - err = user_m.GameCloseUpdate(model, userInfo) - if err != nil { - model.Log.Errorf("GameClear err:%v", err) - return err - } - // 清理房间游戏 - err = sud.RoomClear(domain.CreateModelNil(), userInfo.MgId, sud.RoomClearReqData{RoomId: userInfo.TxGroupId}) - if err != nil { - model.Log.Errorf("GameClear err:%v", err) - return myerr.WrapErr(err) - } - go s.PushGameInfo("", "", "", userInfo.Id) - return nil -} - -// 游戏房间玩家退钻 -func (s *GameService) userRefund(model *domain.Model, userInfo *user_m.GameInfo) (err error) { - var players []*user_m.GamePlayer - if userInfo.Diamond > 0 { - players, err = user_m.GetGamePlayers(model, userInfo.Id) - if err != nil { - model.Log.Errorf("GameRefund err:%v", err) - return myerr.WrapErr(err) - } - } - err = user_m.DelGamePlayers(model, userInfo.Id) - if err != nil { - model.Log.Errorf("GameRefund err:%v", err) - return myerr.WrapErr(err) - } - if userInfo.Diamond <= 0 { - return nil - } - if userInfo.Diamond > 0 { - for _, v := range players { - err = s.userrRefund(model, v, userInfo) - if err != nil { - model.Log.Errorf("GameRefund err:%v", err) - return err - } - } - } - return nil -} - -// 游戏房间玩家退钻 -func (s *GameService) userrRefund(model *domain.Model, userr *user_m.GamePlayer, userInfo *user_m.GameInfo) error { - if userr.UserId <= 0 || userr.IsAi == 1 || userInfo.Diamond <= 0 { - return nil - } - // 退费 - diamondAccount, err := diamond_m.GetDiamondAccountByUserId(model, userr.UserId) - if err != nil { - model.Log.Errorf("GameRefund err:%v", err) - return err - } - diamondAccountDetail, err := diamondAccount.ChangeDiamondAccountDetail(diamond_e.GameRefund, userInfo.Id, mysql.Num(userInfo.Diamond)) - if err != nil { - model.Log.Errorf("GameRefund err:%v", err) - return err - } - err = diamondAccountDetail.Persistent() - if err != nil { - model.Log.Errorf("GameRefund err:%v", err) - return err - } - return nil -} diff --git a/domain/service/game_s/jwt.go b/domain/service/game_s/jwt.go deleted file mode 100755 index d1cea47..0000000 --- a/domain/service/game_s/jwt.go +++ /dev/null @@ -1,72 +0,0 @@ -package user_s - -import ( - "github.com/dgrijalva/jwt-go" - "hilo-user/myerr" - "hilo-user/myerr/bizerr" - "hilo-user/resource/config" - "hilo-user/resource/mysql" - "time" -) - -// 载荷,增加用户别名 -type Claims struct { - UserId uint64 - ExternalId string - jwt.StandardClaims -} - -// 生成App用的jwt token -// issuer 外面传 -func generateGameJwtToken(userId uint64, externalId string, issuer string) (string, error) { - jwtConfig := config.GetConfigGameJWT() - duration, err := time.ParseDuration(jwtConfig.EXPIRE) - if err != nil { - return "", myerr.WrapErr(err) - } - - expireTime := time.Now().Add(duration) - claims := Claims{ - UserId: userId, - ExternalId: externalId, - StandardClaims: jwt.StandardClaims{ - ExpiresAt: expireTime.UnixNano() / 1e6, //过期时间 - Issuer: issuer, //签名的发行者 - }, - } - tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - token, err := tokenClaims.SignedString(getGameJWTSecret()) - return token, myerr.WrapErr(err) -} - -//解析jwt token -func ParseJwtToken(token, issuer string) (userId mysql.ID, externalId string, expiresAt int64, err error) { - tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) { - return getGameJWTSecret(), nil - }) - if err != nil { - return - } - if tokenClaims != nil { - claims, ok := tokenClaims.Claims.(*Claims) - if ok && tokenClaims.Valid { - if time.Now().Unix() > claims.ExpiresAt { - err = bizerr.GameTokenExpire - return - } - if claims.Issuer != issuer { - err = bizerr.GameTokenInvalid - return - } - // success - userId, externalId, expiresAt = claims.UserId, claims.ExternalId, claims.ExpiresAt - } - } else { - err = bizerr.GameTokenInvalid - } - return -} - -func getGameJWTSecret() []byte { - return []byte(config.GetConfigGameJWT().SECRET) -} diff --git a/domain/service/group_s/group.go b/domain/service/group_s/group.go deleted file mode 100755 index 84c3be7..0000000 --- a/domain/service/group_s/group.go +++ /dev/null @@ -1,53 +0,0 @@ -package group_s - -import ( - "encoding/json" - "github.com/sirupsen/logrus" - "hilo-user/domain" - "hilo-user/domain/model/group_m" - "hilo-user/sdk/tencentyun" - "runtime/debug" -) - -// 发送群信令。入参是内部imGroupId,这里做转换 -func SendSignalMsg(model *domain.Model, imGroupId, txGroupId string, msg group_m.GroupSystemMsg, async bool) { - model.Log.WithField("imGroupId:", imGroupId) - model.Log.WithField("txGroupId:", txGroupId) - - groupId := txGroupId - var err error - if len(groupId) == 0 { - groupId, err = group_m.ToTxGroupId(model, imGroupId) - if err != nil { - return - } - } - - buffer, err := json.Marshal(msg) - if err == nil { - str := string(buffer) - model.Log.Infof("SendSignalMsg: %s, async = %v", str, async) - - if async { - go func(logger *logrus.Entry) { - defer func() { - if r := recover(); r != nil { - //打印错误堆栈信息 - logger.Errorf("SendSignalMsg SYSTEM ACTION PANIC: %v, stack: %v", r, string(debug.Stack())) - } - }() - if err = tencentyun.SendSystemMsg(logger, groupId, []string{}, str); err != nil { - logger.Errorf("SendSignalMsg aync failed for %s, msgId = %d, context:%v, err:%v", groupId, msg.MsgId, str, err) - } else { - logger.Infof("SendSignalMsg aync success for %s, msgId = %d, context:%v, err:%v", groupId, msg.MsgId, str) - } - }(model.Log) - } else if err = tencentyun.SendSystemMsg(model.Log, groupId, []string{}, str); err != nil { - model.Log.Errorf("SendSignalMsg sync failed for %s, msgId = %d, context:%v, err:%v", groupId, msg.MsgId, str, err) - } else { - model.Log.Infof("SendSignalMsg sync success for %s, msgId = %d, context:%v", groupId, msg.MsgId, str) - } - } else { - model.Log.Errorln("Marshall failure, msgId = %d : %s", msg.MsgId, err.Error()) - } -} diff --git a/resource/consul/consul.go b/resource/consul/consul.go index 82f7199..56eb51e 100755 --- a/resource/consul/consul.go +++ b/resource/consul/consul.go @@ -11,8 +11,8 @@ import ( ) const ( - RegisterName = "hiloGame" - RegisterTag = "游戏中心" + RegisterName = "hiloUser" + RegisterTag = "用户中心" ) // 异步注册到consul -- 2.22.0