mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
修改聊天和登录信息的数据库结构
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user