diff --git a/dispatch/controller/controller.go b/dispatch/controller/controller.go index 641b8dae..19f1ae23 100644 --- a/dispatch/controller/controller.go +++ b/dispatch/controller/controller.go @@ -47,9 +47,7 @@ func NewController(dao *dao.Dao, discovery *rpc.DiscoveryClient) (r *Controller) func (c *Controller) authorize() gin.HandlerFunc { return func(context *gin.Context) { - // TODO auth token或其他验证方式 - ok := true - if ok { + if context.Query("key") == "flswld" { context.Next() return } @@ -80,10 +78,10 @@ func (c *Controller) registerRouter() { { // 调度 // dispatchosglobal.yuanshen.com - engine.GET("/query_security_file", c.query_security_file) - engine.GET("/query_region_list", c.query_region_list) + engine.GET("/query_security_file", c.querySecurityFile) + engine.GET("/query_region_list", c.queryRegionList) // osusadispatch.yuanshen.com - engine.GET("/query_cur_region", c.query_cur_region) + engine.GET("/query_cur_region", c.queryCurRegion) } { // 登录 diff --git a/dispatch/controller/dispatch_controller.go b/dispatch/controller/dispatch_controller.go index d906dcf3..fb7eacdb 100644 --- a/dispatch/controller/dispatch_controller.go +++ b/dispatch/controller/dispatch_controller.go @@ -18,7 +18,7 @@ import ( "github.com/gin-gonic/gin" ) -func (c *Controller) query_security_file(context *gin.Context) { +func (c *Controller) querySecurityFile(context *gin.Context) { // 很早以前2.6.0版本的时候抓包为了完美还原写的 不清楚有没有副作用暂时不要了 return file, err := os.ReadFile("static/security_file") @@ -30,7 +30,7 @@ func (c *Controller) query_security_file(context *gin.Context) { _, _ = context.Writer.WriteString(string(file)) } -func (c *Controller) query_region_list(context *gin.Context) { +func (c *Controller) queryRegionList(context *gin.Context) { context.Header("Content-type", "text/html; charset=UTF-8") regionListBase64 := region.GetRegionListBase64(c.ec2b) _, _ = context.Writer.WriteString(regionListBase64) @@ -66,7 +66,7 @@ func (c *Controller) getClientVersionByName(versionName string) (int, string) { return version, strconv.Itoa(version) } -func (c *Controller) query_cur_region(context *gin.Context) { +func (c *Controller) queryCurRegion(context *gin.Context) { rspError := func() { rspContentError := "CAESGE5vdCBGb3VuZCB2ZXJzaW9uIGNvbmZpZw==" rspSignError := "TW9yZSBsb3ZlIGZvciBVQSBQYXRjaCBwbGF5ZXJz" diff --git a/dispatch/controller/gate_controller.go b/dispatch/controller/gate_controller.go index e246632d..7de51e34 100644 --- a/dispatch/controller/gate_controller.go +++ b/dispatch/controller/gate_controller.go @@ -42,29 +42,29 @@ func (c *Controller) gateTokenVerify(context *gin.Context) { verifyFail(0) return } - account, err := c.dao.QueryAccountByField("accountID", accountId) + account, err := c.dao.QueryAccountByField("AccountID", accountId) if err != nil || account == nil { verifyFail(0) return } if tokenVerifyReq.AccountToken != account.ComboToken { - verifyFail(uint32(account.PlayerID)) + verifyFail(account.PlayerID) return } if account.ComboTokenUsed { - verifyFail(uint32(account.PlayerID)) + verifyFail(account.PlayerID) return } - _, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "comboTokenUsed", true) + _, err = c.dao.UpdateAccountFieldByFieldName("AccountID", account.AccountID, "ComboTokenUsed", true) if err != nil { - verifyFail(uint32(account.PlayerID)) + verifyFail(account.PlayerID) return } context.JSON(http.StatusOK, &TokenVerifyRsp{ Valid: true, Forbid: account.Forbid, - ForbidEndTime: uint32(account.ForbidEndTime), - PlayerID: uint32(account.PlayerID), + ForbidEndTime: account.ForbidEndTime, + PlayerID: account.PlayerID, }) } @@ -85,7 +85,7 @@ func (c *Controller) gateTokenReset(context *gin.Context) { }) return } - _, err = c.dao.UpdateAccountFieldByFieldName("playerID", req.PlayerId, "comboTokenUsed", false) + _, err = c.dao.UpdateAccountFieldByFieldName("PlayerID", req.PlayerId, "ComboTokenUsed", false) if err != nil { context.JSON(http.StatusOK, &TokenResetRsp{ Result: false, diff --git a/dispatch/controller/login_controller.go b/dispatch/controller/login_controller.go index c2307eb0..1a90e767 100644 --- a/dispatch/controller/login_controller.go +++ b/dispatch/controller/login_controller.go @@ -92,8 +92,7 @@ func (c *Controller) apiLogin(context *gin.Context) { context.JSON(http.StatusOK, responseData) return } - // TODO SDK账号登陆 - account, err := c.dao.QueryAccountByField("username", username) + account, err := c.dao.QueryAccountByField("Username", username) if err != nil { logger.Error("query account from db error: %v", err) return @@ -141,14 +140,14 @@ func (c *Controller) apiLogin(context *gin.Context) { } // 生成新的token account.Token = base64.StdEncoding.EncodeToString(random.GetRandomByte(24)) - _, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "token", account.Token) + _, err = c.dao.UpdateAccountFieldByFieldName("AccountID", account.AccountID, "Token", account.Token) if err != nil { responseData.Retcode = -201 responseData.Message = "服务器内部错误:-4" context.JSON(http.StatusOK, responseData) return } - _, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "tokenCreateTime", time.Now().UnixMilli()) + _, err = c.dao.UpdateAccountFieldByFieldName("AccountID", account.AccountID, "TokenCreateTime", time.Now().UnixMilli()) if err != nil { responseData.Retcode = -201 responseData.Message = "服务器内部错误:-5" @@ -174,7 +173,7 @@ func (c *Controller) apiVerify(context *gin.Context) { logger.Error("parse uid error: %v", err) return } - account, err := c.dao.QueryAccountByField("accountID", uid) + account, err := c.dao.QueryAccountByField("AccountID", uid) if err != nil { logger.Error("query account from db error: %v", err) return @@ -223,7 +222,7 @@ func (c *Controller) v2Login(context *gin.Context) { return } responseData := api.NewComboTokenRsp() - account, err := c.dao.QueryAccountByField("accountID", uid) + account, err := c.dao.QueryAccountByField("AccountID", uid) if account == nil || account.Token != loginData.Token { responseData.Retcode = -201 responseData.Message = "token错误" @@ -232,14 +231,14 @@ func (c *Controller) v2Login(context *gin.Context) { } // 生成新的comboToken account.ComboToken = random.GetRandomByteHexStr(20) - _, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "comboToken", account.ComboToken) + _, err = c.dao.UpdateAccountFieldByFieldName("AccountID", account.AccountID, "ComboToken", account.ComboToken) if err != nil { responseData.Retcode = -201 responseData.Message = "服务器内部错误:-1" context.JSON(http.StatusOK, responseData) return } - _, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "comboTokenUsed", false) + _, err = c.dao.UpdateAccountFieldByFieldName("AccountID", account.AccountID, "ComboTokenUsed", false) if err != nil { responseData.Retcode = -201 responseData.Message = "服务器内部错误:-2" diff --git a/dispatch/dao/account_redis.go b/dispatch/dao/account_redis.go index eac39317..3a7f9564 100644 --- a/dispatch/dao/account_redis.go +++ b/dispatch/dao/account_redis.go @@ -8,26 +8,26 @@ const RedisPlayerKeyPrefix = "HK4E" const ( AccountIdRedisKey = "AccountId" - AccountIdBegin uint64 = 10000 + AccountIdBegin uint32 = 10000 YuanShenUidRedisKey = "YuanShenUid" - YuanShenUidBegin uint64 = 100000000 + YuanShenUidBegin uint32 = 100000000 ) -func (d *Dao) GetNextAccountId() (uint64, error) { +func (d *Dao) GetNextAccountId() (uint32, error) { return d.redisInc(RedisPlayerKeyPrefix + ":" + AccountIdRedisKey) } -func (d *Dao) GetNextYuanShenUid() (uint64, error) { +func (d *Dao) GetNextYuanShenUid() (uint32, error) { return d.redisInc(RedisPlayerKeyPrefix + ":" + YuanShenUidRedisKey) } -func (d *Dao) redisInc(keyName string) (uint64, error) { +func (d *Dao) redisInc(keyName string) (uint32, error) { exist, err := d.redis.Exists(context.TODO(), keyName).Result() if err != nil { return 0, err } if exist == 0 { - var value uint64 = 0 + var value uint32 = 0 if keyName == RedisPlayerKeyPrefix+":"+AccountIdRedisKey { value = AccountIdBegin } else if keyName == RedisPlayerKeyPrefix+":"+YuanShenUidRedisKey { @@ -42,5 +42,5 @@ func (d *Dao) redisInc(keyName string) (uint64, error) { if err != nil { return 0, err } - return uint64(id), nil + return uint32(id), nil } diff --git a/dispatch/model/account.go b/dispatch/model/account.go index 229c5ac6..492bae2c 100644 --- a/dispatch/model/account.go +++ b/dispatch/model/account.go @@ -4,14 +4,14 @@ import "go.mongodb.org/mongo-driver/bson/primitive" type Account struct { ID primitive.ObjectID `bson:"_id,omitempty"` - AccountID uint64 `bson:"accountID"` - Username string `bson:"username"` - Password string `bson:"password"` - PlayerID uint64 `bson:"playerID"` - Token string `bson:"token"` - TokenCreateTime uint64 `bson:"tokenCreateTime"` // 毫秒时间戳 - ComboToken string `bson:"comboToken"` - ComboTokenUsed bool `bson:"comboTokenUsed"` - Forbid bool `bson:"forbid"` - ForbidEndTime uint64 `bson:"forbidEndTime"` // 秒时间戳 + AccountID uint32 `bson:"AccountID"` + PlayerID uint32 `bson:"PlayerID"` + Username string `bson:"Username"` + Password string `bson:"Password"` + Token string `bson:"Token"` + TokenCreateTime uint64 `bson:"TokenCreateTime"` // 毫秒时间戳 + ComboToken string `bson:"ComboToken"` + ComboTokenUsed bool `bson:"ComboTokenUsed"` + Forbid bool `bson:"Forbid"` + ForbidEndTime uint32 `bson:"ForbidEndTime"` // 秒时间戳 } diff --git a/dispatch/model/client_log.go b/dispatch/model/client_log.go index 7b5fa637..06aba679 100644 --- a/dispatch/model/client_log.go +++ b/dispatch/model/client_log.go @@ -6,19 +6,19 @@ import ( type ClientLog struct { ID primitive.ObjectID `json:"-" bson:"_id,omitempty"` - Auid string `json:"auid" bson:"auid"` - ClientIp string `json:"clientIp" bson:"clientIp"` - CpuInfo string `json:"cpuInfo" bson:"cpuInfo"` - DeviceModel string `json:"deviceModel" bson:"deviceModel"` - DeviceName string `json:"deviceName" bson:"deviceName"` - GpuInfo string `json:"gpuInfo" bson:"gpuInfo"` - Guid string `json:"guid" bson:"guid"` - LogStr string `json:"logStr" bson:"logStr"` - LogType string `json:"logType" bson:"logType"` - OperatingSystem string `json:"operatingSystem" bson:"operatingSystem"` - StackTrace string `json:"stackTrace" bson:"stackTrace"` - Time string `json:"time" bson:"time"` - Uid uint64 `json:"uid" bson:"uid"` - UserName string `json:"userName" bson:"userName"` - Version string `json:"version" bson:"version"` + Auid string `json:"auid" bson:"Auid"` + ClientIp string `json:"clientIp" bson:"ClientIp"` + CpuInfo string `json:"cpuInfo" bson:"CpuInfo"` + DeviceModel string `json:"deviceModel" bson:"DeviceModel"` + DeviceName string `json:"deviceName" bson:"DeviceName"` + GpuInfo string `json:"gpuInfo" bson:"GpuInfo"` + Guid string `json:"guid" bson:"Guid"` + LogStr string `json:"logStr" bson:"LogStr"` + LogType string `json:"logType" bson:"LogType"` + OperatingSystem string `json:"operatingSystem" bson:"OperatingSystem"` + StackTrace string `json:"stackTrace" bson:"StackTrace"` + Time string `json:"time" bson:"Time"` + Uid uint64 `json:"uid" bson:"Uid"` + UserName string `json:"userName" bson:"UserName"` + Version string `json:"version" bson:"Version"` } diff --git a/dispatch/service/service.go b/dispatch/service/service.go index 401e3c4c..40601313 100644 --- a/dispatch/service/service.go +++ b/dispatch/service/service.go @@ -11,7 +11,7 @@ type Service struct { // UserPasswordChange 用户密码改变 func (s *Service) UserPasswordChange(uid uint32) bool { // http登录态失效 - _, err := s.dao.UpdateAccountFieldByFieldName("playerID", uid, "tokenCreateTime", 0) + _, err := s.dao.UpdateAccountFieldByFieldName("PlayerID", uid, "TokenCreateTime", 0) if err != nil { return false } @@ -22,11 +22,11 @@ func (s *Service) UserPasswordChange(uid uint32) bool { // ForbidUser 封号 func (s *Service) ForbidUser(uid uint32, forbidEndTime uint64) bool { // 写入账号封禁信息 - _, err := s.dao.UpdateAccountFieldByFieldName("playerID", uid, "forbid", true) + _, err := s.dao.UpdateAccountFieldByFieldName("PlayerID", uid, "Forbid", true) if err != nil { return false } - _, err = s.dao.UpdateAccountFieldByFieldName("playerID", uid, "forbidEndTime", forbidEndTime) + _, err = s.dao.UpdateAccountFieldByFieldName("PlayerID", uid, "ForbidEndTime", forbidEndTime) if err != nil { return false } @@ -37,7 +37,7 @@ func (s *Service) ForbidUser(uid uint32, forbidEndTime uint64) bool { // UnForbidUser 解封 func (s *Service) UnForbidUser(uid uint32) bool { // 解除账号封禁 - _, err := s.dao.UpdateAccountFieldByFieldName("playerID", uid, "forbid", false) + _, err := s.dao.UpdateAccountFieldByFieldName("PlayerID", uid, "Forbid", false) if err != nil { return false } diff --git a/gate/net/session.go b/gate/net/session.go index 5409ab8d..43274293 100644 --- a/gate/net/session.go +++ b/gate/net/session.go @@ -190,9 +190,12 @@ func (k *KcpConnectManager) sendMsgHandle() { ServerMsg: serverMsg, }) } else if protoMsg.CmdId == cmd.ClientReconnectNotify { - tokenResetRsp, err := httpclient.Post[controller.TokenResetRsp](config.CONF.Hk4e.LoginSdkUrl+"/gate/token/reset", &controller.TokenResetReq{ - PlayerId: session.userId, - }, "") + tokenResetRsp, err := httpclient.Post[controller.TokenResetRsp]( + config.CONF.Hk4e.LoginSdkUrl+"/gate/token/reset?key=flswld", + &controller.TokenResetReq{ + PlayerId: session.userId, + }, + "") if err != nil { logger.Error("reset token error: %v", err) k.kcpEventInput <- &KcpEvent{ @@ -335,10 +338,13 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session EventMessage: uint32(kcp.EnetLoginUnfinished), } } - tokenVerifyRsp, err := httpclient.Post[controller.TokenVerifyRsp](config.CONF.Hk4e.LoginSdkUrl+"/gate/token/verify", &controller.TokenVerifyReq{ - AccountId: req.AccountUid, - AccountToken: req.AccountToken, - }, "") + tokenVerifyRsp, err := httpclient.Post[controller.TokenVerifyRsp]( + config.CONF.Hk4e.LoginSdkUrl+"/gate/token/verify?key=flswld", + &controller.TokenVerifyReq{ + AccountId: req.AccountUid, + AccountToken: req.AccountToken, + }, + "") if err != nil { logger.Error("verify token error: %v, account uid: %v", err, req.AccountUid) loginFailClose() diff --git a/gs/dao/player_mongo.go b/gs/dao/player_mongo.go index b3019c3c..14b86cc4 100644 --- a/gs/dao/player_mongo.go +++ b/gs/dao/player_mongo.go @@ -279,3 +279,24 @@ func (d *Dao) QueryChatMsgListByUid(uid uint32) ([]*model.ChatMsg, error) { } return result, nil } + +func (d *Dao) ReadAndUpdateChatMsgByUid(uid uint32, targetUid uint32) error { + db := d.db.Collection("chat_msg") + _, err := db.UpdateOne( + context.TODO(), + bson.D{{"ToUid", uid}, {"Uid", targetUid}}, + bson.D{{"$set", bson.D{{"IsRead", true}}}}, + ) + if err != nil { + return err + } + _, err = db.UpdateOne( + context.TODO(), + bson.D{{"Uid", uid}, {"ToUid", targetUid}}, + bson.D{{"$set", bson.D{{"IsRead", true}}}}, + ) + if err != nil { + return err + } + return nil +} diff --git a/gs/game/game_manager.go b/gs/game/game_manager.go index 7a9f6870..c58254db 100644 --- a/gs/game/game_manager.go +++ b/gs/game/game_manager.go @@ -24,12 +24,14 @@ import ( ) const ( - AiBaseUid = 10000 - AiName = "GM" - AiSign = "快捷指令" - BigWorldAiUid = 100 - BigWorldAiName = "小可爱" - BigWorldAiSign = "UnKownOwO" + PlayerBaseUid = 100000000 + MaxPlayerBaseUid = 200000000 + AiBaseUid = 10000 + AiName = "GM" + AiSign = "快捷指令" + BigWorldAiUid = 100 + BigWorldAiName = "小可爱" + BigWorldAiSign = "UnKownOwO" ) var GAME_MANAGER *GameManager = nil @@ -271,7 +273,7 @@ func (g *GameManager) Close() { // SendMsgToGate 发送消息给客户端 指定网关 func (g *GameManager) SendMsgToGate(cmdId uint16, userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) { - if userId < 100000000 { + if userId < PlayerBaseUid { return } if payloadMsg == nil { @@ -293,7 +295,7 @@ func (g *GameManager) SendMsgToGate(cmdId uint16, userId uint32, clientSeq uint3 // SendMsg 发送消息给客户端 func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, payloadMsg pb.Message) { - if userId < 100000000 { + if userId < PlayerBaseUid { return } if payloadMsg == nil { diff --git a/gs/game/local_event_manager.go b/gs/game/local_event_manager.go index 03c1552a..3e1f75a2 100644 --- a/gs/game/local_event_manager.go +++ b/gs/game/local_event_manager.go @@ -74,7 +74,7 @@ func (l *LocalEventManager) LocalEventHandle(localEvent *LocalEvent) { startTime := time.Now().UnixNano() playerList := make(PlayerLastSaveTimeSortList, 0) for _, player := range USER_MANAGER.playerMap { - if player.PlayerID < 100000000 { + if player.PlayerID < PlayerBaseUid { continue } playerList = append(playerList, player) diff --git a/gs/game/player_chat.go b/gs/game/player_chat.go index 79985072..b47ccf66 100644 --- a/gs/game/player_chat.go +++ b/gs/game/player_chat.go @@ -13,7 +13,7 @@ import ( ) const ( - MaxMsgListLen = 1000 // 与某人的最大聊天记录条数 + MaxMsgListLen = 100 // 与某人的最大聊天记录条数 ) func (g *GameManager) PullRecentChatReq(player *model.Player, payloadMsg pb.Message) { @@ -84,9 +84,9 @@ func (g *GameManager) PullPrivateChatReq(player *model.Player, payloadMsg pb.Mes // SendPrivateChat 发送私聊文本消息给玩家 func (g *GameManager) SendPrivateChat(player *model.Player, targetUid uint32, content any) { - chatInfo := &proto.ChatInfo{ + chatMsg := &model.ChatMsg{ + Sequence: 0, Time: uint32(time.Now().Unix()), - Sequence: 101, ToUid: targetUid, Uid: player.PlayerID, IsRead: false, @@ -95,24 +95,25 @@ func (g *GameManager) SendPrivateChat(player *model.Player, targetUid uint32, co switch content.(type) { case string: // 文本消息 - chatInfo.Content = &proto.ChatInfo_Text{ - Text: content.(string), - } + chatMsg.MsgType = model.ChatMsgTypeText + chatMsg.Text = content.(string) case uint32: // 图标消息 - chatInfo.Content = &proto.ChatInfo_Icon{ - Icon: content.(uint32), - } + chatMsg.MsgType = model.ChatMsgTypeIcon + chatMsg.Icon = content.(uint32) } - chatMsg := g.ConvChatInfoToChatMsg(chatInfo) // 写入db go USER_MANAGER.SaveUserChatMsgToDbSync(chatMsg) // 消息加入自己的队列 msgList, exist := player.ChatMsgMap[targetUid] + // 处理序号 if !exist { msgList = make([]*model.ChatMsg, 0) + chatMsg.Sequence = 101 + } else { + chatMsg.Sequence = uint32(len(msgList)) + 101 } if len(msgList) > MaxMsgListLen { msgList = msgList[1:] @@ -120,6 +121,8 @@ func (g *GameManager) SendPrivateChat(player *model.Player, targetUid uint32, co msgList = append(msgList, chatMsg) player.ChatMsgMap[targetUid] = msgList + chatInfo := g.ConvChatMsgToChatInfo(chatMsg) + privateChatNotify := &proto.PrivateChatNotify{ ChatInfo: chatInfo, } @@ -213,6 +216,9 @@ func (g *GameManager) ReadPrivateChatReq(player *model.Player, payloadMsg pb.Mes } player.ChatMsgMap[targetUid] = msgList + // 更新db + go USER_MANAGER.ReadAndUpdateUserChatMsgToDbSync(player.PlayerID, targetUid) + g.SendMsg(cmd.ReadPrivateChatRsp, player.PlayerID, player.ClientSeq, new(proto.ReadPrivateChatRsp)) } @@ -261,13 +267,14 @@ func (g *GameManager) PlayerChatReq(player *model.Player, payloadMsg pb.Message) func (g *GameManager) ConvChatInfoToChatMsg(chatInfo *proto.ChatInfo) (chatMsg *model.ChatMsg) { chatMsg = &model.ChatMsg{ - Time: chatInfo.Time, - ToUid: chatInfo.ToUid, - Uid: chatInfo.Uid, - IsRead: chatInfo.IsRead, - MsgType: 0, - Text: "", - Icon: 0, + Sequence: chatInfo.Sequence, + Time: chatInfo.Time, + ToUid: chatInfo.ToUid, + Uid: chatInfo.Uid, + IsRead: chatInfo.IsRead, + MsgType: 0, + Text: "", + Icon: 0, } switch chatInfo.Content.(type) { case *proto.ChatInfo_Text: @@ -284,7 +291,7 @@ func (g *GameManager) ConvChatInfoToChatMsg(chatInfo *proto.ChatInfo) (chatMsg * func (g *GameManager) ConvChatMsgToChatInfo(chatMsg *model.ChatMsg) (chatInfo *proto.ChatInfo) { chatInfo = &proto.ChatInfo{ Time: chatMsg.Time, - Sequence: 0, + Sequence: chatMsg.Sequence, ToUid: chatMsg.ToUid, Uid: chatMsg.Uid, IsRead: chatMsg.IsRead, diff --git a/gs/game/player_login.go b/gs/game/player_login.go index 9f0724e5..4e89e500 100644 --- a/gs/game/player_login.go +++ b/gs/game/player_login.go @@ -26,13 +26,17 @@ func (g *GameManager) SetPlayerBornDataReq(userId uint32, clientSeq uint32, gate logger.Info("user reg req, uid: %v, gateAppId: %v", userId, gateAppId) req := payloadMsg.(*proto.SetPlayerBornDataReq) logger.Debug("reg data: %v", req) + if userId < PlayerBaseUid { + logger.Error("uid can not less than player base uid, reg req uid: %v", userId) + return + } g.OnReg(userId, clientSeq, gateAppId, req) } func (g *GameManager) OnLogin(userId uint32, clientSeq uint32, gateAppId string) { logger.Info("user login, uid: %v", userId) - player, asyncWait := USER_MANAGER.OnlineUser(userId, clientSeq, gateAppId) - if !asyncWait { + player, isRobot := USER_MANAGER.OnlineUser(userId, clientSeq, gateAppId) + if isRobot { g.OnLoginOk(userId, player, clientSeq, gateAppId) } } @@ -64,7 +68,7 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u player.CombatInvokeHandler = model.NewInvokeHandler[proto.CombatInvokeEntry]() player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]() - if userId < 100000000 { + if userId < PlayerBaseUid { return } @@ -98,7 +102,7 @@ func (g *GameManager) OnReg(userId uint32, clientSeq uint32, gateAppId string, p func (g *GameManager) OnRegOk(exist bool, req *proto.SetPlayerBornDataReq, userId uint32, clientSeq uint32, gateAppId string) { if exist { - logger.Error("recv reg req, but user is already exist, userId: %v", userId) + logger.Error("recv reg req, but user is already exist, uid: %v", userId) return } @@ -124,7 +128,7 @@ func (g *GameManager) OnUserOffline(userId uint32, changeGsInfo *ChangeGsInfo) { logger.Info("user offline, uid: %v", userId) player := USER_MANAGER.GetOnlineUser(userId) if player == nil { - logger.Error("player is nil, userId: %v", userId) + logger.Error("player is nil, uid: %v", userId) return } TICK_MANAGER.DestroyUserGlobalTick(userId) diff --git a/gs/game/user_manager.go b/gs/game/user_manager.go index eb873452..c6ec8779 100644 --- a/gs/game/user_manager.go +++ b/gs/game/user_manager.go @@ -132,12 +132,13 @@ type PlayerLoginInfo struct { // OnlineUser 玩家上线 func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32, gateAppId string) (*model.Player, bool) { player, exist := u.playerMap[userId] - if exist { - u.ChangeUserDbState(player, model.DbNormal) - return player, false - } else { + if userId > PlayerBaseUid { + // 每次玩家上线必须从数据库加载最新的档 如果之前存在于内存则删掉 + if exist { + u.DeleteUser(userId) + } go func() { - player = u.LoadUserFromDbSync(userId) + player := u.LoadUserFromDbSync(userId) if player != nil { u.SaveUserToRedisSync(player) u.ChangeUserDbState(player, model.DbNormal) @@ -155,7 +156,9 @@ func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32, gateAppId stri }, } }() - return nil, true + return nil, false + } else { + return player, true } } @@ -325,8 +328,8 @@ func (u *UserManager) LoadTempOfflineUser(userId uint32) *model.Player { if player == nil { // 玩家可能不存在于redis 尝试从db查询出来然后写入redis // 大多数情况下活跃玩家都在redis 所以不会走到下面 - // TODO 布隆过滤器防止恶意攻击造成redis缓存穿透 - if userId < 100000000 || userId > 200000000 { + // TODO 防止恶意攻击造成redis缓存穿透 + if userId < PlayerBaseUid || userId > MaxPlayerBaseUid { logger.Error("try to load a not exist uid, uid: %v", userId) return nil } @@ -487,8 +490,12 @@ func (u *UserManager) LoadUserChatMsgFromDbSync(userId uint32) map[uint32][]*mod } for otherUid, msgList := range chatMsgMap { if len(msgList) > MaxMsgListLen { - chatMsgMap[otherUid] = msgList[len(msgList)-MaxMsgListLen:] + msgList = msgList[len(msgList)-MaxMsgListLen:] } + for index, chatMsg := range msgList { + chatMsg.Sequence = uint32(index) + 101 + } + chatMsgMap[otherUid] = msgList } return chatMsgMap } @@ -501,6 +508,14 @@ func (u *UserManager) SaveUserChatMsgToDbSync(chatMsg *model.ChatMsg) { } } +func (u *UserManager) ReadAndUpdateUserChatMsgToDbSync(uid uint32, targetUid uint32) { + err := u.dao.ReadAndUpdateChatMsgByUid(uid, targetUid) + if err != nil { + logger.Error("read chat msg error: %v", err) + return + } +} + func (u *UserManager) LoadUserFromRedisSync(userId uint32) *model.Player { player := u.dao.GetRedisPlayer(userId) return player diff --git a/gs/game/world_manager.go b/gs/game/world_manager.go index 8d238692..46ef4704 100644 --- a/gs/game/world_manager.go +++ b/gs/game/world_manager.go @@ -203,7 +203,7 @@ func (w *WorldManager) IsAiWorld(world *World) bool { } func (w *WorldManager) IsRobotWorld(world *World) bool { - return world.owner.PlayerID < 100000000 + return world.owner.PlayerID < PlayerBaseUid } func (w *WorldManager) IsBigWorld(world *World) bool { diff --git a/gs/model/chat.go b/gs/model/chat.go index 87477a01..7f99fed4 100644 --- a/gs/model/chat.go +++ b/gs/model/chat.go @@ -10,12 +10,13 @@ const ( ) type ChatMsg struct { - ID primitive.ObjectID `bson:"_id,omitempty"` - Time uint32 `bson:"Time"` - ToUid uint32 `bson:"ToUid"` - Uid uint32 `bson:"Uid"` - IsRead bool `bson:"IsRead"` - MsgType uint8 `bson:"MsgType"` - Text string `bson:"Text"` - Icon uint32 `bson:"Icon"` + ID primitive.ObjectID `bson:"_id,omitempty"` + Sequence uint32 `bson:"-"` + Time uint32 `bson:"Time"` + ToUid uint32 `bson:"ToUid"` + Uid uint32 `bson:"Uid"` + IsRead bool `bson:"IsRead"` + MsgType uint8 `bson:"MsgType"` + Text string `bson:"Text"` + Icon uint32 `bson:"Icon"` }