mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 15:32:26 +08:00
拆分了聊天数据,减小玩家数据结构大小
This commit is contained in:
@@ -10,17 +10,17 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type NetMsg struct {
|
type NetMsg struct {
|
||||||
MsgType uint8 `msgpack:"MsgType"`
|
MsgType uint8
|
||||||
EventId uint16 `msgpack:"EventId"`
|
EventId uint16
|
||||||
ServerType string `msgpack:"-"`
|
ServerType string `msgpack:"-"`
|
||||||
AppId string `msgpack:"-"`
|
AppId string `msgpack:"-"`
|
||||||
Topic string `msgpack:"-"`
|
Topic string `msgpack:"-"`
|
||||||
GameMsg *GameMsg `msgpack:"GameMsg"`
|
GameMsg *GameMsg
|
||||||
FightMsg *FightMsg `msgpack:"FightMsg"`
|
FightMsg *FightMsg
|
||||||
ConnCtrlMsg *ConnCtrlMsg `msgpack:"ConnCtrlMsg"`
|
ConnCtrlMsg *ConnCtrlMsg
|
||||||
ServerMsg *ServerMsg `msgpack:"ServerMsg"`
|
ServerMsg *ServerMsg
|
||||||
OriginServerType string `msgpack:"OriginServerType"`
|
OriginServerType string
|
||||||
OriginServerAppId string `msgpack:"OriginServerAppId"`
|
OriginServerAppId string
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -28,11 +28,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type GameMsg struct {
|
type GameMsg struct {
|
||||||
UserId uint32 `msgpack:"UserId"`
|
UserId uint32
|
||||||
CmdId uint16 `msgpack:"CmdId"`
|
CmdId uint16
|
||||||
ClientSeq uint32 `msgpack:"ClientSeq"`
|
ClientSeq uint32
|
||||||
PayloadMessage pb.Message `msgpack:"-"`
|
PayloadMessage pb.Message `msgpack:"-"`
|
||||||
PayloadMessageData []byte `msgpack:"PayloadMessageData"`
|
PayloadMessageData []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -43,11 +43,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ConnCtrlMsg struct {
|
type ConnCtrlMsg struct {
|
||||||
UserId uint32 `msgpack:"UserId"`
|
UserId uint32
|
||||||
ClientRtt uint32 `msgpack:"ClientRtt"`
|
ClientRtt uint32
|
||||||
ClientTime uint32 `msgpack:"ClientTime"`
|
ClientTime uint32
|
||||||
KickUserId uint32 `msgpack:"KickUserId"`
|
KickUserId uint32
|
||||||
KickReason uint32 `msgpack:"KickReason"`
|
KickReason uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -58,12 +58,12 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FightMsg struct {
|
type FightMsg struct {
|
||||||
FightRoutineId uint32 `msgpack:"FightRoutineId"`
|
FightRoutineId uint32
|
||||||
EntityId uint32 `msgpack:"EntityId"`
|
EntityId uint32
|
||||||
FightPropMap map[uint32]float32 `msgpack:"FightPropMap"`
|
FightPropMap map[uint32]float32
|
||||||
Uid uint32 `msgpack:"Uid"`
|
Uid uint32
|
||||||
AvatarGuid uint64 `msgpack:"AvatarGuid"`
|
AvatarGuid uint64
|
||||||
GateServerAppId string `msgpack:"GateServerAppId"`
|
GateServerAppId string
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -77,56 +77,56 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ServerMsg struct {
|
type ServerMsg struct {
|
||||||
FightServerAppId string `msgpack:"FightServerAppId"`
|
FightServerAppId string
|
||||||
UserId uint32 `msgpack:"UserId"`
|
UserId uint32
|
||||||
IsOnline bool `msgpack:"IsOnline"`
|
IsOnline bool
|
||||||
GameServerAppId string `msgpack:"GameServerAppId"`
|
GameServerAppId string
|
||||||
JoinHostUserId uint32 `msgpack:"JoinHostUserId"`
|
JoinHostUserId uint32
|
||||||
UserMpInfo *UserMpInfo `msgpack:"UserMpInfo"`
|
UserMpInfo *UserMpInfo
|
||||||
ChatMsgInfo *ChatMsgInfo `msgpack:"ChatMsgInfo"`
|
ChatMsgInfo *ChatMsgInfo
|
||||||
AddFriendInfo *AddFriendInfo `msgpack:"AddFriendInfo"`
|
AddFriendInfo *AddFriendInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
type OriginInfo struct {
|
type OriginInfo struct {
|
||||||
CmdName string `msgpack:"CmdName"`
|
CmdName string
|
||||||
UserId uint32 `msgpack:"UserId"`
|
UserId uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserBaseInfo struct {
|
type UserBaseInfo struct {
|
||||||
UserId uint32 `msgpack:"UserId"`
|
UserId uint32
|
||||||
Nickname string `msgpack:"Nickname"`
|
Nickname string
|
||||||
PlayerLevel uint32 `msgpack:"PlayerLevel"`
|
PlayerLevel uint32
|
||||||
MpSettingType uint8 `msgpack:"MpSettingType"`
|
MpSettingType uint8
|
||||||
NameCardId uint32 `msgpack:"NameCardId"`
|
NameCardId uint32
|
||||||
Signature string `msgpack:"Signature"`
|
Signature string
|
||||||
HeadImageId uint32 `msgpack:"HeadImageId"`
|
HeadImageId uint32
|
||||||
WorldPlayerNum uint32 `msgpack:"WorldPlayerNum"`
|
WorldPlayerNum uint32
|
||||||
WorldLevel uint32 `msgpack:"WorldLevel"`
|
WorldLevel uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserMpInfo struct {
|
type UserMpInfo struct {
|
||||||
OriginInfo *OriginInfo `msgpack:"OriginInfo"`
|
OriginInfo *OriginInfo
|
||||||
HostUserId uint32 `msgpack:"HostUserId"`
|
HostUserId uint32
|
||||||
ApplyUserId uint32 `msgpack:"ApplyUserId"`
|
ApplyUserId uint32
|
||||||
ApplyPlayerOnlineInfo *UserBaseInfo `msgpack:"ApplyPlayerOnlineInfo"`
|
ApplyPlayerOnlineInfo *UserBaseInfo
|
||||||
ApplyOk bool `msgpack:"ApplyOk"`
|
ApplyOk bool
|
||||||
Agreed bool `msgpack:"Agreed"`
|
Agreed bool
|
||||||
Reason int32 `msgpack:"Reason"`
|
Reason int32
|
||||||
HostNickname string `msgpack:"HostNickname"`
|
HostNickname string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChatMsgInfo struct {
|
type ChatMsgInfo struct {
|
||||||
Time uint32 `msgpack:"Time"`
|
Time uint32
|
||||||
ToUid uint32 `msgpack:"ToUid"`
|
ToUid uint32
|
||||||
Uid uint32 `msgpack:"Uid"`
|
Uid uint32
|
||||||
IsRead bool `msgpack:"IsRead"`
|
IsRead bool
|
||||||
MsgType uint8 `msgpack:"MsgType"`
|
MsgType uint8
|
||||||
Text string `msgpack:"Text"`
|
Text string
|
||||||
Icon uint32 `msgpack:"Icon"`
|
Icon uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddFriendInfo struct {
|
type AddFriendInfo struct {
|
||||||
OriginInfo *OriginInfo `msgpack:"OriginInfo"`
|
OriginInfo *OriginInfo
|
||||||
TargetUserId uint32 `msgpack:"TargetUserId"`
|
TargetUserId uint32
|
||||||
ApplyPlayerOnlineInfo *UserBaseInfo `msgpack:"ApplyPlayerOnlineInfo"`
|
ApplyPlayerOnlineInfo *UserBaseInfo
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,33 @@ import (
|
|||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PlayerDb 只从数据库读写的结构
|
||||||
|
type PlayerDb struct {
|
||||||
|
ID primitive.ObjectID `bson:"_id,omitempty"`
|
||||||
|
PlayerID uint32 `bson:"PlayerID"` // 玩家uid
|
||||||
|
ChatMsgMap map[uint32][]*model.ChatMsg // 聊天信息
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Dao) InsertPlayer(player *model.Player) error {
|
func (d *Dao) InsertPlayer(player *model.Player) error {
|
||||||
db := d.db.Collection("player")
|
db := d.db.Collection("player")
|
||||||
_, err := db.InsertOne(context.TODO(), player)
|
_, err := db.InsertOne(context.TODO(), player)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dao) InsertPlayerDb(playerDb *PlayerDb) error {
|
||||||
|
db := d.db.Collection("player_db")
|
||||||
|
_, err := db.InsertOne(context.TODO(), playerDb)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dao) InsertPlayerList(playerList []*model.Player) error {
|
func (d *Dao) InsertPlayerList(playerList []*model.Player) error {
|
||||||
@@ -26,13 +46,45 @@ func (d *Dao) InsertPlayerList(playerList []*model.Player) error {
|
|||||||
modelOperateList = append(modelOperateList, modelOperate)
|
modelOperateList = append(modelOperateList, modelOperate)
|
||||||
}
|
}
|
||||||
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dao) InsertPlayerDbList(playerDbList []*PlayerDb) error {
|
||||||
|
if len(playerDbList) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
db := d.db.Collection("player_db")
|
||||||
|
modelOperateList := make([]mongo.WriteModel, 0)
|
||||||
|
for _, playerDb := range playerDbList {
|
||||||
|
modelOperate := mongo.NewInsertOneModel().SetDocument(playerDb)
|
||||||
|
modelOperateList = append(modelOperateList, modelOperate)
|
||||||
|
}
|
||||||
|
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dao) DeletePlayer(playerID uint32) error {
|
func (d *Dao) DeletePlayer(playerID uint32) error {
|
||||||
db := d.db.Collection("player")
|
db := d.db.Collection("player")
|
||||||
_, err := db.DeleteOne(context.TODO(), bson.D{{"playerID", playerID}})
|
_, err := db.DeleteOne(context.TODO(), bson.D{{"PlayerID", playerID}})
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dao) DeletePlayerDb(playerID uint32) error {
|
||||||
|
db := d.db.Collection("player_db")
|
||||||
|
_, err := db.DeleteOne(context.TODO(), bson.D{{"PlayerID", playerID}})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dao) DeletePlayerList(playerIDList []uint32) error {
|
func (d *Dao) DeletePlayerList(playerIDList []uint32) error {
|
||||||
@@ -42,21 +94,57 @@ func (d *Dao) DeletePlayerList(playerIDList []uint32) error {
|
|||||||
db := d.db.Collection("player")
|
db := d.db.Collection("player")
|
||||||
modelOperateList := make([]mongo.WriteModel, 0)
|
modelOperateList := make([]mongo.WriteModel, 0)
|
||||||
for _, playerID := range playerIDList {
|
for _, playerID := range playerIDList {
|
||||||
modelOperate := mongo.NewDeleteOneModel().SetFilter(bson.D{{"playerID", playerID}})
|
modelOperate := mongo.NewDeleteOneModel().SetFilter(bson.D{{"PlayerID", playerID}})
|
||||||
modelOperateList = append(modelOperateList, modelOperate)
|
modelOperateList = append(modelOperateList, modelOperate)
|
||||||
}
|
}
|
||||||
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dao) DeletePlayerDbList(playerIDList []uint32) error {
|
||||||
|
if len(playerIDList) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
db := d.db.Collection("player_db")
|
||||||
|
modelOperateList := make([]mongo.WriteModel, 0)
|
||||||
|
for _, playerID := range playerIDList {
|
||||||
|
modelOperate := mongo.NewDeleteOneModel().SetFilter(bson.D{{"PlayerID", playerID}})
|
||||||
|
modelOperateList = append(modelOperateList, modelOperate)
|
||||||
|
}
|
||||||
|
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dao) UpdatePlayer(player *model.Player) error {
|
func (d *Dao) UpdatePlayer(player *model.Player) error {
|
||||||
db := d.db.Collection("player")
|
db := d.db.Collection("player")
|
||||||
_, err := db.UpdateOne(
|
_, err := db.UpdateOne(
|
||||||
context.TODO(),
|
context.TODO(),
|
||||||
bson.D{{"playerID", player.PlayerID}},
|
bson.D{{"PlayerID", player.PlayerID}},
|
||||||
bson.D{{"$set", player}},
|
bson.D{{"$set", player}},
|
||||||
)
|
)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dao) UpdatePlayerDb(playerDb *PlayerDb) error {
|
||||||
|
db := d.db.Collection("player_db")
|
||||||
|
_, err := db.UpdateOne(
|
||||||
|
context.TODO(),
|
||||||
|
bson.D{{"PlayerID", playerDb.PlayerID}},
|
||||||
|
bson.D{{"$set", playerDb}},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dao) UpdatePlayerList(playerList []*model.Player) error {
|
func (d *Dao) UpdatePlayerList(playerList []*model.Player) error {
|
||||||
@@ -66,27 +154,65 @@ func (d *Dao) UpdatePlayerList(playerList []*model.Player) error {
|
|||||||
db := d.db.Collection("player")
|
db := d.db.Collection("player")
|
||||||
modelOperateList := make([]mongo.WriteModel, 0)
|
modelOperateList := make([]mongo.WriteModel, 0)
|
||||||
for _, player := range playerList {
|
for _, player := range playerList {
|
||||||
modelOperate := mongo.NewUpdateOneModel().SetFilter(bson.D{{"playerID", player.PlayerID}}).SetUpdate(bson.D{{"$set", player}})
|
modelOperate := mongo.NewUpdateOneModel().SetFilter(bson.D{{"PlayerID", player.PlayerID}}).SetUpdate(bson.D{{"$set", player}})
|
||||||
modelOperateList = append(modelOperateList, modelOperate)
|
modelOperateList = append(modelOperateList, modelOperate)
|
||||||
}
|
}
|
||||||
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dao) UpdatePlayerDbList(playerDbList []*PlayerDb) error {
|
||||||
|
if len(playerDbList) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
db := d.db.Collection("player_db")
|
||||||
|
modelOperateList := make([]mongo.WriteModel, 0)
|
||||||
|
for _, playerDb := range playerDbList {
|
||||||
|
modelOperate := mongo.NewUpdateOneModel().SetFilter(bson.D{{"PlayerID", playerDb.PlayerID}}).SetUpdate(bson.D{{"$set", playerDb}})
|
||||||
|
modelOperateList = append(modelOperateList, modelOperate)
|
||||||
|
}
|
||||||
|
_, err := db.BulkWrite(context.TODO(), modelOperateList)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dao) QueryPlayerByID(playerID uint32) (*model.Player, error) {
|
func (d *Dao) QueryPlayerByID(playerID uint32) (*model.Player, error) {
|
||||||
db := d.db.Collection("player")
|
db := d.db.Collection("player")
|
||||||
result := db.FindOne(
|
result := db.FindOne(
|
||||||
context.TODO(),
|
context.TODO(),
|
||||||
bson.D{{"playerID", playerID}},
|
bson.D{{"PlayerID", playerID}},
|
||||||
)
|
)
|
||||||
item := new(model.Player)
|
player := new(model.Player)
|
||||||
err := result.Decode(item)
|
err := result.Decode(player)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return item, nil
|
return player, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Dao) QueryPlayerDbByID(playerID uint32) (*PlayerDb, error) {
|
||||||
|
db := d.db.Collection("player_db")
|
||||||
|
result := db.FindOne(
|
||||||
|
context.TODO(),
|
||||||
|
bson.D{{"PlayerID", playerID}},
|
||||||
|
)
|
||||||
|
playerDb := new(PlayerDb)
|
||||||
|
err := result.Decode(playerDb)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if playerDb.ChatMsgMap == nil {
|
||||||
|
playerDb.ChatMsgMap = make(map[uint32][]*model.ChatMsg)
|
||||||
|
}
|
||||||
|
return playerDb, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryPlayerList 危险接口 非测试禁止使用
|
||||||
func (d *Dao) QueryPlayerList() ([]*model.Player, error) {
|
func (d *Dao) QueryPlayerList() ([]*model.Player, error) {
|
||||||
db := d.db.Collection("player")
|
db := d.db.Collection("player")
|
||||||
find, err := db.Find(
|
find, err := db.Find(
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ import (
|
|||||||
pb "google.golang.org/protobuf/proto"
|
pb "google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MaxMsgListLen = 1000 // 与某人的最大聊天记录条数
|
||||||
|
)
|
||||||
|
|
||||||
func (g *GameManager) PullRecentChatReq(player *model.Player, payloadMsg pb.Message) {
|
func (g *GameManager) PullRecentChatReq(player *model.Player, payloadMsg pb.Message) {
|
||||||
logger.Debug("user pull recent chat, uid: %v", player.PlayerID)
|
logger.Debug("user pull recent chat, uid: %v", player.PlayerID)
|
||||||
req := payloadMsg.(*proto.PullRecentChatReq)
|
req := payloadMsg.(*proto.PullRecentChatReq)
|
||||||
@@ -94,7 +98,7 @@ func (g *GameManager) SendPrivateChat(player *model.Player, targetUid uint32, co
|
|||||||
chatInfo.Content = &proto.ChatInfo_Text{
|
chatInfo.Content = &proto.ChatInfo_Text{
|
||||||
Text: content.(string),
|
Text: content.(string),
|
||||||
}
|
}
|
||||||
case int, int32, uint32:
|
case uint32:
|
||||||
// 图标消息
|
// 图标消息
|
||||||
chatInfo.Content = &proto.ChatInfo_Icon{
|
chatInfo.Content = &proto.ChatInfo_Icon{
|
||||||
Icon: content.(uint32),
|
Icon: content.(uint32),
|
||||||
@@ -106,6 +110,9 @@ func (g *GameManager) SendPrivateChat(player *model.Player, targetUid uint32, co
|
|||||||
if !exist {
|
if !exist {
|
||||||
msgList = make([]*model.ChatMsg, 0)
|
msgList = make([]*model.ChatMsg, 0)
|
||||||
}
|
}
|
||||||
|
if len(msgList) > MaxMsgListLen {
|
||||||
|
msgList = msgList[1:]
|
||||||
|
}
|
||||||
msgList = append(msgList, chatMsg)
|
msgList = append(msgList, chatMsg)
|
||||||
player.ChatMsgMap[targetUid] = msgList
|
player.ChatMsgMap[targetUid] = msgList
|
||||||
|
|
||||||
@@ -136,7 +143,10 @@ func (g *GameManager) SendPrivateChat(player *model.Player, targetUid uint32, co
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 目标玩家全服离线
|
// 目标玩家全服离线
|
||||||
// TODO 接入redis直接同步写入数据
|
chatMsgMap := map[uint32][]*model.ChatMsg{
|
||||||
|
player.PlayerID: {chatMsg},
|
||||||
|
}
|
||||||
|
go USER_MANAGER.AppendOfflineUserChatMsgToDbSync(targetUid, chatMsgMap)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -145,6 +155,9 @@ func (g *GameManager) SendPrivateChat(player *model.Player, targetUid uint32, co
|
|||||||
if !exist {
|
if !exist {
|
||||||
msgList = make([]*model.ChatMsg, 0)
|
msgList = make([]*model.ChatMsg, 0)
|
||||||
}
|
}
|
||||||
|
if len(msgList) > MaxMsgListLen {
|
||||||
|
msgList = msgList[1:]
|
||||||
|
}
|
||||||
msgList = append(msgList, chatMsg)
|
msgList = append(msgList, chatMsg)
|
||||||
targetPlayer.ChatMsgMap[player.PlayerID] = msgList
|
targetPlayer.ChatMsgMap[player.PlayerID] = msgList
|
||||||
|
|
||||||
@@ -167,7 +180,8 @@ func (g *GameManager) PrivateChatReq(player *model.Player, payloadMsg pb.Message
|
|||||||
switch content.(type) {
|
switch content.(type) {
|
||||||
case *proto.PrivateChatReq_Text:
|
case *proto.PrivateChatReq_Text:
|
||||||
text := content.(*proto.PrivateChatReq_Text).Text
|
text := content.(*proto.PrivateChatReq_Text).Text
|
||||||
if len(text) == 0 {
|
if len(text) == 0 || len(text) > 80 {
|
||||||
|
g.SendError(cmd.PrivateChatRsp, player, &proto.PrivateChatRsp{}, proto.Retcode_RET_PRIVATE_CHAT_CONTENT_TOO_LONG)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 发送私聊文本消息
|
// 发送私聊文本消息
|
||||||
|
|||||||
@@ -149,13 +149,13 @@ func (g *GameManager) LoginNotify(userId uint32, player *model.Player, clientSeq
|
|||||||
g.GCGLogin(player) // 发送GCG登录相关的通知包
|
g.GCGLogin(player) // 发送GCG登录相关的通知包
|
||||||
playerLoginRsp := &proto.PlayerLoginRsp{
|
playerLoginRsp := &proto.PlayerLoginRsp{
|
||||||
IsUseAbilityHash: true,
|
IsUseAbilityHash: true,
|
||||||
AbilityHashCode: -228935105,
|
AbilityHashCode: 0,
|
||||||
GameBiz: "hk4e_cn",
|
GameBiz: "hk4e_cn",
|
||||||
IsScOpen: false,
|
IsScOpen: false,
|
||||||
RegisterCps: "taptap",
|
RegisterCps: "taptap",
|
||||||
CountryCode: "CN",
|
CountryCode: "CN",
|
||||||
Birthday: "2000-01-01",
|
Birthday: "2000-01-01",
|
||||||
TotalTickTime: 1185941.871788,
|
TotalTickTime: 0.0,
|
||||||
}
|
}
|
||||||
g.SendMsg(cmd.PlayerLoginRsp, userId, clientSeq, playerLoginRsp)
|
g.SendMsg(cmd.PlayerLoginRsp, userId, clientSeq, playerLoginRsp)
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ func (g *GameManager) PacketPlayerDataNotify(player *model.Player) *proto.Player
|
|||||||
NickName: player.NickName,
|
NickName: player.NickName,
|
||||||
ServerTime: uint64(time.Now().UnixMilli()),
|
ServerTime: uint64(time.Now().UnixMilli()),
|
||||||
IsFirstLoginToday: true,
|
IsFirstLoginToday: true,
|
||||||
RegionId: player.RegionId,
|
RegionId: 1,
|
||||||
PropMap: make(map[uint32]*proto.PropValue),
|
PropMap: make(map[uint32]*proto.PropValue),
|
||||||
}
|
}
|
||||||
for k, v := range player.PropertiesMap {
|
for k, v := range player.PropertiesMap {
|
||||||
@@ -344,7 +344,6 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata
|
|||||||
player.FriendList = make(map[uint32]bool)
|
player.FriendList = make(map[uint32]bool)
|
||||||
player.FriendApplyList = make(map[uint32]bool)
|
player.FriendApplyList = make(map[uint32]bool)
|
||||||
|
|
||||||
player.RegionId = 1
|
|
||||||
player.SceneId = 3
|
player.SceneId = 3
|
||||||
|
|
||||||
player.PropertiesMap = make(map[uint16]uint32)
|
player.PropertiesMap = make(map[uint16]uint32)
|
||||||
@@ -397,7 +396,6 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata
|
|||||||
player.AvatarMap = make(map[uint32]*model.Avatar)
|
player.AvatarMap = make(map[uint32]*model.Avatar)
|
||||||
player.GameObjectGuidMap = make(map[uint64]model.GameObject)
|
player.GameObjectGuidMap = make(map[uint64]model.GameObject)
|
||||||
player.DropInfo = model.NewDropInfo()
|
player.DropInfo = model.NewDropInfo()
|
||||||
player.ChatMsgMap = make(map[uint32][]*model.ChatMsg)
|
|
||||||
player.GCGInfo = model.NewGCGInfo()
|
player.GCGInfo = model.NewGCGInfo()
|
||||||
|
|
||||||
// 添加选定的主角
|
// 添加选定的主角
|
||||||
@@ -418,5 +416,7 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata
|
|||||||
player.TeamConfig = model.NewTeamInfo()
|
player.TeamConfig = model.NewTeamInfo()
|
||||||
player.TeamConfig.GetActiveTeam().SetAvatarIdList([]uint32{mainCharAvatarId})
|
player.TeamConfig.GetActiveTeam().SetAvatarIdList([]uint32{mainCharAvatarId})
|
||||||
|
|
||||||
|
player.ChatMsgMap = make(map[uint32][]*model.ChatMsg)
|
||||||
|
|
||||||
return player
|
return player
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"hk4e/gs/dao"
|
"hk4e/gs/dao"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
|
"hk4e/pkg/object"
|
||||||
"hk4e/protocol/proto"
|
"hk4e/protocol/proto"
|
||||||
|
|
||||||
"github.com/vmihailenco/msgpack/v5"
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
@@ -141,6 +142,8 @@ func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32, gateAppId stri
|
|||||||
if player != nil {
|
if player != nil {
|
||||||
u.SaveUserToRedisSync(player)
|
u.SaveUserToRedisSync(player)
|
||||||
u.ChangeUserDbState(player, model.DbNormal)
|
u.ChangeUserDbState(player, model.DbNormal)
|
||||||
|
playerDb := u.LoadUserChatMsgFromDbSync(userId)
|
||||||
|
player.ChatMsgMap = playerDb.ChatMsgMap
|
||||||
} else {
|
} else {
|
||||||
logger.Error("can not find user from db, uid: %v", userId)
|
logger.Error("can not find user from db, uid: %v", userId)
|
||||||
}
|
}
|
||||||
@@ -170,11 +173,20 @@ type PlayerOfflineInfo struct {
|
|||||||
|
|
||||||
// OfflineUser 玩家离线
|
// OfflineUser 玩家离线
|
||||||
func (u *UserManager) OfflineUser(player *model.Player, changeGsInfo *ChangeGsInfo) {
|
func (u *UserManager) OfflineUser(player *model.Player, changeGsInfo *ChangeGsInfo) {
|
||||||
|
startTime := time.Now().UnixNano()
|
||||||
playerData, err := msgpack.Marshal(player)
|
playerData, err := msgpack.Marshal(player)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("marshal player data error: %v", err)
|
logger.Error("marshal player data error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
chatMsgMapData, err := object.DeepMarshal(&player.ChatMsgMap)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("marshal chat msg map error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
endTime := time.Now().UnixNano()
|
||||||
|
costTime := endTime - startTime
|
||||||
|
logger.Info("offline copy player data and chat msg cost time: %v ns", costTime)
|
||||||
go func() {
|
go func() {
|
||||||
playerCopy := new(model.Player)
|
playerCopy := new(model.Player)
|
||||||
err := msgpack.Unmarshal(playerData, playerCopy)
|
err := msgpack.Unmarshal(playerData, playerCopy)
|
||||||
@@ -185,6 +197,16 @@ func (u *UserManager) OfflineUser(player *model.Player, changeGsInfo *ChangeGsIn
|
|||||||
playerCopy.DbState = player.DbState
|
playerCopy.DbState = player.DbState
|
||||||
u.SaveUserToDbSync(playerCopy)
|
u.SaveUserToDbSync(playerCopy)
|
||||||
u.SaveUserToRedisSync(playerCopy)
|
u.SaveUserToRedisSync(playerCopy)
|
||||||
|
chatMsgMap := make(map[uint32][]*model.ChatMsg)
|
||||||
|
err = object.DeepUnmarshal(&chatMsgMap, chatMsgMapData)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("unmarshal chat msg map error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
playerDb := new(dao.PlayerDb)
|
||||||
|
playerDb.PlayerID = playerCopy.PlayerID
|
||||||
|
playerDb.ChatMsgMap = chatMsgMap
|
||||||
|
u.SaveUserChatMsgToDbSync(playerDb)
|
||||||
LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
|
LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
|
||||||
EventId: UserOfflineSaveToDbFinish,
|
EventId: UserOfflineSaveToDbFinish,
|
||||||
Msg: &PlayerOfflineInfo{
|
Msg: &PlayerOfflineInfo{
|
||||||
@@ -457,6 +479,51 @@ func (u *UserManager) SaveUserListToDbSync(insertPlayerList []*model.Player, upd
|
|||||||
logger.Info("save user finish, insert user count: %v, update user count: %v", len(insertPlayerList), len(updatePlayerList))
|
logger.Info("save user finish, insert user count: %v, update user count: %v", len(insertPlayerList), len(updatePlayerList))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UserManager) LoadUserChatMsgFromDbSync(userId uint32) *dao.PlayerDb {
|
||||||
|
playerDb, err := u.dao.QueryPlayerDbByID(userId)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("query player db error: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return playerDb
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserManager) SaveUserChatMsgToDbSync(playerDb *dao.PlayerDb) {
|
||||||
|
_, err := u.dao.QueryPlayerDbByID(playerDb.PlayerID)
|
||||||
|
if err != nil {
|
||||||
|
err := u.dao.InsertPlayerDb(playerDb)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("insert player db error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := u.dao.UpdatePlayerDb(playerDb)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("update player db error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserManager) AppendOfflineUserChatMsgToDbSync(userId uint32, chatMsgMap map[uint32][]*model.ChatMsg) {
|
||||||
|
playerDb := u.LoadUserChatMsgFromDbSync(userId)
|
||||||
|
if playerDb == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for uid, msgList := range chatMsgMap {
|
||||||
|
allMsgList, exist := playerDb.ChatMsgMap[uid]
|
||||||
|
if !exist {
|
||||||
|
allMsgList = make([]*model.ChatMsg, 0)
|
||||||
|
}
|
||||||
|
allMsgList = append(allMsgList, msgList...)
|
||||||
|
if len(allMsgList) > MaxMsgListLen {
|
||||||
|
allMsgList = allMsgList[len(allMsgList)-MaxMsgListLen:]
|
||||||
|
}
|
||||||
|
playerDb.ChatMsgMap[uid] = allMsgList
|
||||||
|
}
|
||||||
|
u.SaveUserChatMsgToDbSync(playerDb)
|
||||||
|
}
|
||||||
|
|
||||||
func (u *UserManager) LoadUserFromRedisSync(userId uint32) *model.Player {
|
func (u *UserManager) LoadUserFromRedisSync(userId uint32) *model.Player {
|
||||||
player := u.dao.GetRedisPlayer(userId)
|
player := u.dao.GetRedisPlayer(userId)
|
||||||
return player
|
return player
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ func (s *Scene) SetEntityLifeState(entity *Entity, lifeState uint16, dieType pro
|
|||||||
GAME_MANAGER.EntityFightPropUpdateNotifyBroadcast(s, entity, uint32(constant.FIGHT_PROP_CUR_HP))
|
GAME_MANAGER.EntityFightPropUpdateNotifyBroadcast(s, entity, uint32(constant.FIGHT_PROP_CUR_HP))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PacketAvatarLifeStateChangeNotify
|
|
||||||
avatarLifeStateChangeNotify := &proto.AvatarLifeStateChangeNotify{
|
avatarLifeStateChangeNotify := &proto.AvatarLifeStateChangeNotify{
|
||||||
LifeState: uint32(lifeState),
|
LifeState: uint32(lifeState),
|
||||||
AttackTag: "",
|
AttackTag: "",
|
||||||
@@ -111,9 +110,7 @@ func (s *Scene) SetEntityLifeState(entity *Entity, lifeState uint16, dieType pro
|
|||||||
SourceEntityId: 0,
|
SourceEntityId: 0,
|
||||||
AvatarGuid: avatar.Guid,
|
AvatarGuid: avatar.Guid,
|
||||||
}
|
}
|
||||||
for _, p := range s.playerMap {
|
GAME_MANAGER.SendToWorldA(s.world, cmd.AvatarLifeStateChangeNotify, 0, avatarLifeStateChangeNotify)
|
||||||
GAME_MANAGER.SendMsg(cmd.AvatarLifeStateChangeNotify, p.PlayerID, p.ClientSeq, avatarLifeStateChangeNotify)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 设置存活状态
|
// 设置存活状态
|
||||||
entity.lifeState = lifeState
|
entity.lifeState = lifeState
|
||||||
@@ -124,7 +121,6 @@ func (s *Scene) SetEntityLifeState(entity *Entity, lifeState uint16, dieType pro
|
|||||||
GAME_MANAGER.EntityFightPropUpdateNotifyBroadcast(s, entity, uint32(constant.FIGHT_PROP_CUR_HP))
|
GAME_MANAGER.EntityFightPropUpdateNotifyBroadcast(s, entity, uint32(constant.FIGHT_PROP_CUR_HP))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PacketLifeStateChangeNotify
|
|
||||||
lifeStateChangeNotify := &proto.LifeStateChangeNotify{
|
lifeStateChangeNotify := &proto.LifeStateChangeNotify{
|
||||||
EntityId: entity.id,
|
EntityId: entity.id,
|
||||||
AttackTag: "",
|
AttackTag: "",
|
||||||
@@ -133,9 +129,7 @@ func (s *Scene) SetEntityLifeState(entity *Entity, lifeState uint16, dieType pro
|
|||||||
LifeState: uint32(lifeState),
|
LifeState: uint32(lifeState),
|
||||||
SourceEntityId: 0,
|
SourceEntityId: 0,
|
||||||
}
|
}
|
||||||
for _, p := range s.playerMap {
|
GAME_MANAGER.SendToWorldA(s.world, cmd.LifeStateChangeNotify, 0, lifeStateChangeNotify)
|
||||||
GAME_MANAGER.SendMsg(cmd.LifeStateChangeNotify, p.PlayerID, p.ClientSeq, lifeStateChangeNotify)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除实体
|
// 删除实体
|
||||||
s.DestroyEntity(entity.id)
|
s.DestroyEntity(entity.id)
|
||||||
@@ -159,9 +153,8 @@ func (s *Scene) CreateEntityAvatar(player *model.Player, avatarId uint32) uint32
|
|||||||
moveState: uint16(proto.MotionState_MOTION_NONE),
|
moveState: uint16(proto.MotionState_MOTION_NONE),
|
||||||
lastMoveSceneTimeMs: 0,
|
lastMoveSceneTimeMs: 0,
|
||||||
lastMoveReliableSeq: 0,
|
lastMoveReliableSeq: 0,
|
||||||
// fightProp: player.AvatarMap[avatarId].FightPropMap, // 使用角色结构的数据
|
fightProp: player.AvatarMap[avatarId].FightPropMap, // 使用角色结构的数据
|
||||||
entityType: uint32(proto.ProtEntityType_PROT_ENTITY_AVATAR),
|
entityType: uint32(proto.ProtEntityType_PROT_ENTITY_AVATAR),
|
||||||
// level: 0, // 使用角色结构的数据
|
|
||||||
avatarEntity: &AvatarEntity{
|
avatarEntity: &AvatarEntity{
|
||||||
uid: player.PlayerID,
|
uid: player.PlayerID,
|
||||||
avatarId: avatarId,
|
avatarId: avatarId,
|
||||||
|
|||||||
@@ -9,24 +9,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Avatar struct {
|
type Avatar struct {
|
||||||
AvatarId uint32 `bson:"avatarId"` // 角色id
|
AvatarId uint32 // 角色id
|
||||||
LifeState uint16 `bson:"lifeState"` // 存活状态
|
LifeState uint16 // 存活状态
|
||||||
Level uint8 `bson:"level"` // 等级
|
Level uint8 // 等级
|
||||||
Exp uint32 `bson:"exp"` // 经验值
|
Exp uint32 // 经验值
|
||||||
Promote uint8 `bson:"promote"` // 突破等阶
|
Promote uint8 // 突破等阶
|
||||||
Satiation uint32 `bson:"satiation"` // 饱食度
|
Satiation uint32 // 饱食度
|
||||||
SatiationPenalty uint32 `bson:"satiationPenalty"` // 饱食度溢出
|
SatiationPenalty uint32 // 饱食度溢出
|
||||||
CurrHP float64 `bson:"currHP"` // 当前生命值
|
CurrHP float64 // 当前生命值
|
||||||
CurrEnergy float64 `bson:"currEnergy"` // 当前元素能量值
|
CurrEnergy float64 // 当前元素能量值
|
||||||
FetterList []uint32 `bson:"fetterList"` // 资料解锁条目
|
FetterList []uint32 // 资料解锁条目
|
||||||
SkillLevelMap map[uint32]uint32 `bson:"skillLevelMap"` // 技能等级数据
|
SkillLevelMap map[uint32]uint32 // 技能等级数据
|
||||||
SkillDepotId uint32 `bson:"skillDepotId"` // 技能库id
|
SkillDepotId uint32 // 技能库id
|
||||||
FlyCloak uint32 `bson:"flyCloak"` // 当前风之翼
|
FlyCloak uint32 // 当前风之翼
|
||||||
Costume uint32 `bson:"costume"` // 当前衣装
|
Costume uint32 // 当前衣装
|
||||||
BornTime int64 `bson:"bornTime"` // 获得时间
|
BornTime int64 // 获得时间
|
||||||
FetterLevel uint8 `bson:"fetterLevel"` // 好感度等级
|
FetterLevel uint8 // 好感度等级
|
||||||
FetterExp uint32 `bson:"fetterExp"` // 好感度经验
|
FetterExp uint32 // 好感度经验
|
||||||
PromoteRewardMap map[uint32]bool `bson:"promoteRewardMap"` // 突破奖励 map[突破等级]是否已被领取
|
PromoteRewardMap map[uint32]bool // 突破奖励 map[突破等级]是否已被领取
|
||||||
Guid uint64 `bson:"-" msgpack:"-"`
|
Guid uint64 `bson:"-" msgpack:"-"`
|
||||||
EquipGuidMap map[uint64]uint64 `bson:"-" msgpack:"-"`
|
EquipGuidMap map[uint64]uint64 `bson:"-" msgpack:"-"`
|
||||||
EquipWeapon *Weapon `bson:"-" msgpack:"-"`
|
EquipWeapon *Weapon `bson:"-" msgpack:"-"`
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ChatMsg struct {
|
type ChatMsg struct {
|
||||||
Time uint32 `bson:"time"`
|
Time uint32
|
||||||
ToUid uint32 `bson:"toUid"`
|
ToUid uint32
|
||||||
Uid uint32 `bson:"uid"`
|
Uid uint32
|
||||||
IsRead bool `bson:"isRead"`
|
IsRead bool
|
||||||
MsgType uint8 `bson:"msgType"`
|
MsgType uint8
|
||||||
Text string `bson:"text"`
|
Text string
|
||||||
Icon uint32 `bson:"icon"`
|
Icon uint32
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
type GachaPoolInfo struct {
|
type GachaPoolInfo struct {
|
||||||
GachaType uint32 `bson:"gachaType"` // 卡池类型
|
GachaType uint32 // 卡池类型
|
||||||
OrangeTimes uint32 `bson:"orangeTimes"` // 5星保底计数
|
OrangeTimes uint32 // 5星保底计数
|
||||||
PurpleTimes uint32 `bson:"purpleTimes"` // 4星保底计数
|
PurpleTimes uint32 // 4星保底计数
|
||||||
MustGetUpOrange bool `bson:"mustGetUpOrange"` // 是否5星大保底
|
MustGetUpOrange bool // 是否5星大保底
|
||||||
MustGetUpPurple bool `bson:"mustGetUpPurple"` // 是否4星大保底
|
MustGetUpPurple bool // 是否4星大保底
|
||||||
}
|
}
|
||||||
|
|
||||||
type DropInfo struct {
|
type DropInfo struct {
|
||||||
GachaPoolInfo map[uint32]*GachaPoolInfo `bson:"gachaPoolInfo"`
|
GachaPoolInfo map[uint32]*GachaPoolInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDropInfo() (r *DropInfo) {
|
func NewDropInfo() (r *DropInfo) {
|
||||||
|
|||||||
@@ -2,61 +2,61 @@ package model
|
|||||||
|
|
||||||
// GCGCard 卡牌
|
// GCGCard 卡牌
|
||||||
type GCGCard struct {
|
type GCGCard struct {
|
||||||
CardId uint32 `bson:"cardId"` // 卡牌Id
|
CardId uint32 // 卡牌Id
|
||||||
Num uint32 `bson:"num"` // 数量
|
Num uint32 // 数量
|
||||||
FaceType uint32 `bson:"faceType"` // 卡面类型
|
FaceType uint32 // 卡面类型
|
||||||
UnlockFaceTypeList []uint32 `bson:"unlockFaceTypeList"` // 解锁的卡面类型
|
UnlockFaceTypeList []uint32 // 解锁的卡面类型
|
||||||
Proficiency uint32 `bson:"proficiency"` // 熟练程度等级
|
Proficiency uint32 // 熟练程度等级
|
||||||
ProficiencyRewardTakenIdxList []uint32 `bson:"faceType"` // 熟练程度奖励列表
|
ProficiencyRewardTakenIdxList []uint32 // 熟练程度奖励列表
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCGDeck 卡组
|
// GCGDeck 卡组
|
||||||
type GCGDeck struct {
|
type GCGDeck struct {
|
||||||
Name string `bson:"name"` // 卡组名
|
Name string // 卡组名
|
||||||
CharacterCardList []uint32 `bson:"characterCardList"` // 角色牌列表
|
CharacterCardList []uint32 // 角色牌列表
|
||||||
CardList []uint32 `bson:"cardList"` // 卡牌列表
|
CardList []uint32 // 卡牌列表
|
||||||
FieldId uint32 `bson:"fieldId"` // 牌盒样式Id
|
FieldId uint32 // 牌盒样式Id
|
||||||
CardBackId uint32 `bson:"cardBackId"` // 牌背样式Id
|
CardBackId uint32 // 牌背样式Id
|
||||||
CreateTime int64 `bson:"createTime"` // 卡组创建时间
|
CreateTime int64 // 卡组创建时间
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCGTavernChallenge 酒馆挑战信息
|
// GCGTavernChallenge 酒馆挑战信息
|
||||||
type GCGTavernChallenge struct {
|
type GCGTavernChallenge struct {
|
||||||
CharacterId uint32 `bson:"characterId"` // 角色Id
|
CharacterId uint32 // 角色Id
|
||||||
UnlockLevelIdList []uint32 `bson:"unlockLevelIdList"` // 解锁的等级Id
|
UnlockLevelIdList []uint32 // 解锁的等级Id
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCGBossChallenge Boss挑战信息
|
// GCGBossChallenge Boss挑战信息
|
||||||
type GCGBossChallenge struct {
|
type GCGBossChallenge struct {
|
||||||
Id uint32 `bson:"Id"` // BossId
|
Id uint32 // BossId
|
||||||
UnlockLevelIdList []uint32 `bson:"unlockLevelIdList"` // 解锁的等级Id
|
UnlockLevelIdList []uint32 // 解锁的等级Id
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCGLevelChallenge 等级挑战信息
|
// GCGLevelChallenge 等级挑战信息
|
||||||
type GCGLevelChallenge struct {
|
type GCGLevelChallenge struct {
|
||||||
LevelId uint32 `bson:"levelId"` // 等级Id
|
LevelId uint32 // 等级Id
|
||||||
FinishedChallengeIdList []uint32 `bson:"finishedChallengeIdList"` // 完成的挑战Id列表
|
FinishedChallengeIdList []uint32 // 完成的挑战Id列表
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCGInfo 七圣召唤信息
|
// GCGInfo 七圣召唤信息
|
||||||
type GCGInfo struct {
|
type GCGInfo struct {
|
||||||
// 基础信息
|
// 基础信息
|
||||||
Level uint32 `bson:"level"` // 等级
|
Level uint32 // 等级
|
||||||
Exp uint32 `bson:"exp"` // 经验
|
Exp uint32 // 经验
|
||||||
// 卡牌
|
// 卡牌
|
||||||
CardList map[uint32]*GCGCard `bson:"cardList"` // 拥有的卡牌 uint32 -> CardId(卡牌Id)
|
CardList map[uint32]*GCGCard // 拥有的卡牌 uint32 -> CardId(卡牌Id)
|
||||||
CurDeckId uint32 `bson:"CurDeckId"` // 现行的卡组Id
|
CurDeckId uint32 // 现行的卡组Id
|
||||||
DeckList []*GCGDeck `bson:"deckList"` // 卡组列表
|
DeckList []*GCGDeck // 卡组列表
|
||||||
UnlockDeckIdList []uint32 `bson:"unlockDeckIdList"` // 解锁的卡组
|
UnlockDeckIdList []uint32 // 解锁的卡组
|
||||||
UnlockCardBackIdList []uint32 `bson:"unlockCardBackIdList"` // 解锁的卡背
|
UnlockCardBackIdList []uint32 // 解锁的卡背
|
||||||
UnlockFieldIdList []uint32 `bson:"unlockFieldIdList"` // 解锁的牌盒
|
UnlockFieldIdList []uint32 // 解锁的牌盒
|
||||||
// 挑战
|
// 挑战
|
||||||
TavernChallengeMap map[uint32]*GCGTavernChallenge `bson:"tavernChallengeMap"` // 酒馆挑战 uint32 -> CharacterId(角色Id)
|
TavernChallengeMap map[uint32]*GCGTavernChallenge // 酒馆挑战 uint32 -> CharacterId(角色Id)
|
||||||
LevelChallengeMap map[uint32]*GCGLevelChallenge `bson:"levelChallengeMap"` // 等级挑战 uint32 -> LevelId(等级Id)
|
LevelChallengeMap map[uint32]*GCGLevelChallenge // 等级挑战 uint32 -> LevelId(等级Id)
|
||||||
UnlockBossChallengeMap map[uint32]*GCGBossChallenge `bson:"unlockBossChallengeMap"` // 解锁的Boss挑战 uint32 -> Id
|
UnlockBossChallengeMap map[uint32]*GCGBossChallenge // 解锁的Boss挑战 uint32 -> Id
|
||||||
UnlockWorldChallengeList []uint32 `bson:"unlockWorldChallengeList"` // 解锁的世界挑战
|
UnlockWorldChallengeList []uint32 // 解锁的世界挑战
|
||||||
// 其他
|
// 其他
|
||||||
BanCardList []uint32 `bson:"banCardList"` // 被禁止的卡牌列表
|
BanCardList []uint32 // 被禁止的卡牌列表
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGCGInfo() *GCGInfo {
|
func NewGCGInfo() *GCGInfo {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package model
|
|||||||
import "hk4e/common/constant"
|
import "hk4e/common/constant"
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
ItemId uint32 `bson:"itemId"` // 道具id
|
ItemId uint32 // 道具id
|
||||||
Count uint32 `bson:"count"` // 道具数量
|
Count uint32 // 道具数量
|
||||||
Guid uint64 `bson:"-" msgpack:"-"`
|
Guid uint64 `bson:"-" msgpack:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,36 +26,34 @@ type GameObject interface {
|
|||||||
type Player struct {
|
type Player struct {
|
||||||
// 离线数据 请尽量不要定义接口等复杂数据结构
|
// 离线数据 请尽量不要定义接口等复杂数据结构
|
||||||
ID primitive.ObjectID `bson:"_id,omitempty"`
|
ID primitive.ObjectID `bson:"_id,omitempty"`
|
||||||
PlayerID uint32 `bson:"playerID"` // 玩家uid
|
PlayerID uint32 `bson:"PlayerID"` // 玩家uid
|
||||||
NickName string `bson:"nickname"` // 玩家昵称
|
NickName string // 玩家昵称
|
||||||
Signature string `bson:"signature"` // 玩家签名
|
Signature string // 玩家签名
|
||||||
HeadImage uint32 `bson:"headImage"` // 玩家头像
|
HeadImage uint32 // 玩家头像
|
||||||
Birthday []uint8 `bson:"birthday"` // 生日
|
Birthday []uint8 // 生日
|
||||||
NameCard uint32 `bson:"nameCard"` // 当前名片
|
NameCard uint32 // 当前名片
|
||||||
NameCardList []uint32 `bson:"nameCardList"` // 已解锁名片列表
|
NameCardList []uint32 // 已解锁名片列表
|
||||||
FriendList map[uint32]bool `bson:"friendList"` // 好友uid列表
|
FriendList map[uint32]bool // 好友uid列表
|
||||||
FriendApplyList map[uint32]bool `bson:"friendApplyList"` // 好友申请uid列表
|
FriendApplyList map[uint32]bool // 好友申请uid列表
|
||||||
OfflineTime uint32 `bson:"offlineTime"` // 离线时间点
|
OfflineTime uint32 // 离线时间点
|
||||||
OnlineTime uint32 `bson:"onlineTime"` // 上线时间点
|
OnlineTime uint32 // 上线时间点
|
||||||
TotalOnlineTime uint32 `bson:"totalOnlineTime"` // 玩家累计在线时长
|
TotalOnlineTime uint32 // 玩家累计在线时长
|
||||||
PropertiesMap map[uint16]uint32 `bson:"propertiesMap"` // 玩家自身相关的一些属性
|
PropertiesMap map[uint16]uint32 // 玩家自身相关的一些属性
|
||||||
RegionId uint32 `bson:"regionId"` // regionId
|
FlyCloakList []uint32 // 风之翼列表
|
||||||
FlyCloakList []uint32 `bson:"flyCloakList"` // 风之翼列表
|
CostumeList []uint32 // 角色衣装列表
|
||||||
CostumeList []uint32 `bson:"costumeList"` // 角色衣装列表
|
SceneId uint32 // 场景
|
||||||
SceneId uint32 `bson:"sceneId"` // 场景
|
SafePos *Vector // 玩家在陆地时的坐标
|
||||||
SafePos *Vector `bson:"safePos"` // 玩家在陆地时的坐标
|
Pos *Vector // 玩家坐标
|
||||||
Pos *Vector `bson:"pos"` // 玩家坐标
|
Rot *Vector // 玩家朝向
|
||||||
Rot *Vector `bson:"rot"` // 玩家朝向
|
ItemMap map[uint32]*Item // 玩家统一大背包仓库
|
||||||
ItemMap map[uint32]*Item `bson:"itemMap"` // 玩家统一大背包仓库
|
WeaponMap map[uint64]*Weapon // 玩家武器背包
|
||||||
WeaponMap map[uint64]*Weapon `bson:"weaponMap"` // 玩家武器背包
|
ReliquaryMap map[uint64]*Reliquary // 玩家圣遗物背包
|
||||||
ReliquaryMap map[uint64]*Reliquary `bson:"reliquaryMap"` // 玩家圣遗物背包
|
TeamConfig *TeamInfo // 队伍配置
|
||||||
TeamConfig *TeamInfo `bson:"teamConfig"` // 队伍配置
|
AvatarMap map[uint32]*Avatar // 角色信息
|
||||||
AvatarMap map[uint32]*Avatar `bson:"avatarMap"` // 角色信息
|
DropInfo *DropInfo // 掉落信息
|
||||||
DropInfo *DropInfo `bson:"dropInfo"` // 掉落信息
|
MainCharAvatarId uint32 // 主角id
|
||||||
MainCharAvatarId uint32 `bson:"mainCharAvatarId"` // 主角id
|
GCGInfo *GCGInfo // 七圣召唤信息
|
||||||
ChatMsgMap map[uint32][]*ChatMsg `bson:"chatMsgMap"` // 聊天信息
|
IsGM uint8 // 管理员权限等级
|
||||||
GCGInfo *GCGInfo `bson:"gcgInfo"` // 七圣召唤信息
|
|
||||||
IsGM uint8 `bson:"isGM"` // 管理员权限等级
|
|
||||||
// 在线数据 请随意 记得加忽略字段的tag
|
// 在线数据 请随意 记得加忽略字段的tag
|
||||||
LastSaveTime uint32 `bson:"-" msgpack:"-"` // 上一次保存时间
|
LastSaveTime uint32 `bson:"-" msgpack:"-"` // 上一次保存时间
|
||||||
EnterSceneToken uint32 `bson:"-" msgpack:"-"` // 玩家的世界进入令牌
|
EnterSceneToken uint32 `bson:"-" msgpack:"-"` // 玩家的世界进入令牌
|
||||||
@@ -79,6 +77,8 @@ type Player struct {
|
|||||||
GateAppId string `bson:"-" msgpack:"-"` // 网关服务器的appid
|
GateAppId string `bson:"-" msgpack:"-"` // 网关服务器的appid
|
||||||
FightAppId string `bson:"-" msgpack:"-"` // 战斗服务器的appid
|
FightAppId string `bson:"-" msgpack:"-"` // 战斗服务器的appid
|
||||||
GCGCurGameGuid uint32 `bson:"-" msgpack:"-"` // GCG玩家所在的游戏guid
|
GCGCurGameGuid uint32 `bson:"-" msgpack:"-"` // GCG玩家所在的游戏guid
|
||||||
|
// 特殊数据
|
||||||
|
ChatMsgMap map[uint32][]*ChatMsg `bson:"-" msgpack:"-"` // 聊天信息 数据量偏大 只从db读写 不保存到redis
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) GetNextGameObjectGuid() uint64 {
|
func (p *Player) GetNextGameObjectGuid() uint64 {
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Reliquary struct {
|
type Reliquary struct {
|
||||||
ReliquaryId uint64 `bson:"reliquaryId"` // 圣遗物的唯一id
|
ReliquaryId uint64 // 圣遗物的唯一id
|
||||||
ItemId uint32 `bson:"itemId"` // 圣遗物的道具id
|
ItemId uint32 // 圣遗物的道具id
|
||||||
Level uint8 `bson:"level"` // 等级
|
Level uint8 // 等级
|
||||||
Exp uint32 `bson:"exp"` // 当前经验值
|
Exp uint32 // 当前经验值
|
||||||
Promote uint8 `bson:"promote"` // 突破等阶
|
Promote uint8 // 突破等阶
|
||||||
Lock bool `bson:"lock"` // 锁定状态
|
Lock bool // 锁定状态
|
||||||
AffixIdList []uint32 `bson:"affixIdList"` // 词缀
|
AffixIdList []uint32 // 词缀
|
||||||
MainPropId uint32 `bson:"mainPropId"` // 主词条id
|
MainPropId uint32 // 主词条id
|
||||||
AvatarId uint32 `bson:"avatarId"` // 装备角色id
|
AvatarId uint32 // 装备角色id
|
||||||
Guid uint64 `bson:"-" msgpack:"-"`
|
Guid uint64 `bson:"-" msgpack:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Team struct {
|
type Team struct {
|
||||||
Name string `bson:"name"`
|
Name string
|
||||||
AvatarIdList []uint32 `bson:"avatarIdList"`
|
AvatarIdList []uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Team) GetAvatarIdList() []uint32 {
|
func (t *Team) GetAvatarIdList() []uint32 {
|
||||||
@@ -33,9 +33,9 @@ func (t *Team) SetAvatarIdList(avatarIdList []uint32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TeamInfo struct {
|
type TeamInfo struct {
|
||||||
TeamList []*Team `bson:"teamList"`
|
TeamList []*Team
|
||||||
CurrTeamIndex uint8 `bson:"currTeamIndex"`
|
CurrTeamIndex uint8
|
||||||
CurrAvatarIndex uint8 `bson:"currAvatarIndex"`
|
CurrAvatarIndex uint8
|
||||||
TeamResonances map[uint16]bool `bson:"-" msgpack:"-"`
|
TeamResonances map[uint16]bool `bson:"-" msgpack:"-"`
|
||||||
TeamResonancesConfig map[int32]bool `bson:"-" msgpack:"-"`
|
TeamResonancesConfig map[int32]bool `bson:"-" msgpack:"-"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package model
|
|||||||
import "math"
|
import "math"
|
||||||
|
|
||||||
type Vector struct {
|
type Vector struct {
|
||||||
X float64 `bson:"x"`
|
X float64
|
||||||
Y float64 `bson:"y"`
|
Y float64
|
||||||
Z float64 `bson:"z"`
|
Z float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distance 两坐标之间的距离
|
// Distance 两坐标之间的距离
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Weapon struct {
|
type Weapon struct {
|
||||||
WeaponId uint64 `bson:"weaponId"` // 武器的唯一id
|
WeaponId uint64 // 武器的唯一id
|
||||||
ItemId uint32 `bson:"itemId"` // 武器的道具id
|
ItemId uint32 // 武器的道具id
|
||||||
Level uint8 `bson:"level"` // 等级
|
Level uint8 // 等级
|
||||||
Exp uint32 `bson:"exp"` // 当前经验值
|
Exp uint32 // 当前经验值
|
||||||
Promote uint8 `bson:"promote"` // 突破等阶
|
Promote uint8 // 突破等阶
|
||||||
Lock bool `bson:"lock"` // 锁定状态
|
Lock bool // 锁定状态
|
||||||
AffixIdList []uint32 `bson:"affixIdList"` // 词缀
|
AffixIdList []uint32 // 词缀
|
||||||
Refinement uint8 `bson:"refinement"` // 精炼等阶
|
Refinement uint8 // 精炼等阶
|
||||||
AvatarId uint32 `bson:"avatarId"` // 装备角色id
|
AvatarId uint32 // 装备角色id
|
||||||
Guid uint64 `bson:"-" msgpack:"-"`
|
Guid uint64 `bson:"-" msgpack:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,23 @@ func DeepCopy(dst, src any) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeepMarshal(src any) ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := gob.NewEncoder(&buf).Encode(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeepUnmarshal(dst any, data []byte) error {
|
||||||
|
err := gob.NewDecoder(bytes.NewBuffer(data)).Decode(dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func CopyProtoBufSameField(dst, src pb.Message) ([]string, error) {
|
func CopyProtoBufSameField(dst, src pb.Message) ([]string, error) {
|
||||||
data, err := protojson.Marshal(src)
|
data, err := protojson.Marshal(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user