mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-23 14:32:27 +08:00
服务器玩家在线信息同步
This commit is contained in:
@@ -85,7 +85,7 @@ func Run(ctx context.Context, configFile string) error {
|
||||
messageQueue := mq.NewMessageQueue(api.GS, APPID, client)
|
||||
defer messageQueue.Close()
|
||||
|
||||
gameManager := game.NewGameManager(db, messageQueue, GSID, APPID, mainGsAppid.AppId)
|
||||
gameManager := game.NewGameManager(db, messageQueue, GSID, APPID, mainGsAppid.AppId, client.Discovery)
|
||||
defer gameManager.Close()
|
||||
|
||||
// natsrpc server
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hk4e/common/mq"
|
||||
"hk4e/common/rpc"
|
||||
"hk4e/gate/kcp"
|
||||
"hk4e/gdconf"
|
||||
"hk4e/gs/dao"
|
||||
@@ -46,6 +47,7 @@ var ONLINE_PLAYER_NUM int32 = 0 // 当前在线玩家数
|
||||
var SELF *model.Player
|
||||
|
||||
type GameManager struct {
|
||||
discovery *rpc.DiscoveryClient // node服务器客户端
|
||||
dao *dao.Dao
|
||||
snowflake *alg.SnowflakeWorker
|
||||
gsId uint32
|
||||
@@ -54,8 +56,9 @@ type GameManager struct {
|
||||
ai *model.Player // 本服的Ai玩家对象
|
||||
}
|
||||
|
||||
func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32, gsAppid string, mainGsAppid string) (r *GameManager) {
|
||||
func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32, gsAppid string, mainGsAppid string, discovery *rpc.DiscoveryClient) (r *GameManager) {
|
||||
r = new(GameManager)
|
||||
r.discovery = discovery
|
||||
r.dao = dao
|
||||
MESSAGE_QUEUE = messageQueue
|
||||
r.snowflake = alg.NewSnowflakeWorker(int64(gsId))
|
||||
|
||||
@@ -240,14 +240,16 @@ func (g *GameManager) LoginNotify(userId uint32, player *model.Player, clientSeq
|
||||
g.SendMsg(cmd.QuestListNotify, userId, clientSeq, g.PacketQuestListNotify(player))
|
||||
// g.GCGLogin(player) // 发送GCG登录相关的通知包
|
||||
playerLoginRsp := &proto.PlayerLoginRsp{
|
||||
IsUseAbilityHash: true,
|
||||
AbilityHashCode: 0,
|
||||
GameBiz: "hk4e_global",
|
||||
IsScOpen: false,
|
||||
RegisterCps: "mihoyo",
|
||||
CountryCode: "CN",
|
||||
Birthday: "2000-01-01",
|
||||
TotalTickTime: 0.0,
|
||||
IsUseAbilityHash: true,
|
||||
AbilityHashCode: 0,
|
||||
IsEnableClientHashDebug: true,
|
||||
IsScOpen: false,
|
||||
ScInfo: []byte{},
|
||||
TotalTickTime: 0.0,
|
||||
GameBiz: "hk4e_global",
|
||||
RegisterCps: "mihoyo",
|
||||
CountryCode: "US",
|
||||
Birthday: "2000-01-01",
|
||||
}
|
||||
g.SendMsg(cmd.PlayerLoginRsp, userId, clientSeq, playerLoginRsp)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"hk4e/gs/dao"
|
||||
@@ -19,10 +21,11 @@ import (
|
||||
// 玩家定时保存 写入db和redis
|
||||
|
||||
type UserManager struct {
|
||||
dao *dao.Dao // db对象
|
||||
playerMap map[uint32]*model.Player // 内存玩家数据
|
||||
saveUserChan chan *SaveUserData // 用于主协程发送玩家数据给定时保存协程
|
||||
remotePlayerMap map[uint32]string // 远程玩家 key:userId value:玩家所在gs的appid
|
||||
dao *dao.Dao // db对象
|
||||
playerMap map[uint32]*model.Player // 内存玩家数据
|
||||
saveUserChan chan *SaveUserData // 用于主协程发送玩家数据给定时保存协程
|
||||
remotePlayerMap map[uint32]string // 远程玩家 key:userId value:玩家所在gs的appid
|
||||
remotePlayerMapLock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewUserManager(dao *dao.Dao) (r *UserManager) {
|
||||
@@ -32,6 +35,8 @@ func NewUserManager(dao *dao.Dao) (r *UserManager) {
|
||||
r.saveUserChan = make(chan *SaveUserData) // 无缓冲区chan 避免主协程在写入时被迫加锁
|
||||
r.remotePlayerMap = make(map[uint32]string)
|
||||
go r.saveUserHandle()
|
||||
r.syncRemotePlayerMap()
|
||||
go r.autoSyncRemotePlayerMap()
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -251,8 +256,39 @@ func (u *UserManager) ChangeUserDbState(player *model.Player, state int) {
|
||||
|
||||
// 远程玩家相关操作
|
||||
|
||||
func (u *UserManager) autoSyncRemotePlayerMap() {
|
||||
ticker := time.NewTicker(time.Second * 60)
|
||||
for {
|
||||
<-ticker.C
|
||||
u.syncRemotePlayerMap()
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserManager) syncRemotePlayerMap() {
|
||||
rsp, err := GAME_MANAGER.discovery.GetGlobalGsOnlineMap(context.TODO(), nil)
|
||||
if err != nil {
|
||||
logger.Error("get global gs online map error: %v", err)
|
||||
return
|
||||
}
|
||||
copyMap := make(map[uint32]string)
|
||||
for k, v := range rsp.GlobalGsOnlineMap {
|
||||
player, exist := u.playerMap[k]
|
||||
if exist && player.Online {
|
||||
continue
|
||||
}
|
||||
copyMap[k] = v
|
||||
}
|
||||
copyMapLen := len(copyMap)
|
||||
u.remotePlayerMapLock.Lock()
|
||||
u.remotePlayerMap = copyMap
|
||||
u.remotePlayerMapLock.Unlock()
|
||||
logger.Info("sync remote player map finish, len: %v", copyMapLen)
|
||||
}
|
||||
|
||||
func (u *UserManager) GetRemoteUserOnlineState(userId uint32) bool {
|
||||
u.remotePlayerMapLock.RLock()
|
||||
_, exist := u.remotePlayerMap[userId]
|
||||
u.remotePlayerMapLock.RUnlock()
|
||||
if !exist {
|
||||
return false
|
||||
} else {
|
||||
@@ -261,7 +297,9 @@ func (u *UserManager) GetRemoteUserOnlineState(userId uint32) bool {
|
||||
}
|
||||
|
||||
func (u *UserManager) GetRemoteUserGsAppId(userId uint32) string {
|
||||
u.remotePlayerMapLock.RLock()
|
||||
appId, exist := u.remotePlayerMap[userId]
|
||||
u.remotePlayerMapLock.RUnlock()
|
||||
if !exist {
|
||||
return ""
|
||||
} else {
|
||||
@@ -270,12 +308,14 @@ func (u *UserManager) GetRemoteUserGsAppId(userId uint32) string {
|
||||
}
|
||||
|
||||
func (u *UserManager) SetRemoteUserOnlineState(userId uint32, isOnline bool, appId string) {
|
||||
u.remotePlayerMapLock.Lock()
|
||||
if isOnline {
|
||||
u.remotePlayerMap[userId] = appId
|
||||
} else {
|
||||
delete(u.remotePlayerMap, userId)
|
||||
u.DeleteUser(userId)
|
||||
}
|
||||
u.remotePlayerMapLock.Unlock()
|
||||
}
|
||||
|
||||
// GetRemoteOnlineUserList 获取指定数量的远程在线玩家 玩家数据只读禁止修改
|
||||
@@ -285,16 +325,22 @@ func (u *UserManager) GetRemoteOnlineUserList(total int) map[uint32]*model.Playe
|
||||
}
|
||||
onlinePlayerMap := make(map[uint32]*model.Player)
|
||||
count := 0
|
||||
userIdList := make([]uint32, 0)
|
||||
u.remotePlayerMapLock.RLock()
|
||||
for userId := range u.remotePlayerMap {
|
||||
userIdList = append(userIdList, userId)
|
||||
count++
|
||||
if count >= total {
|
||||
break
|
||||
}
|
||||
}
|
||||
u.remotePlayerMapLock.RUnlock()
|
||||
for _, userId := range userIdList {
|
||||
player := u.LoadTempOfflineUser(userId, false)
|
||||
if player == nil {
|
||||
continue
|
||||
}
|
||||
onlinePlayerMap[player.PlayerID] = player
|
||||
count++
|
||||
if count >= total {
|
||||
break
|
||||
}
|
||||
}
|
||||
return onlinePlayerMap
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user