parent
c9742c54ee
commit
260e623dfc
@ -11,6 +11,7 @@ import (
|
||||
proto "server/msg"
|
||||
"server/pkg/github.com/name5566/leaf/log"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -23,6 +24,7 @@ type ChampshipMgr struct {
|
||||
}
|
||||
|
||||
type ChampshipData struct {
|
||||
mu sync.RWMutex
|
||||
AutoId int
|
||||
RobotId int
|
||||
Rank map[int][]*ChampshipRank // 锦标赛排行榜
|
||||
@ -115,7 +117,7 @@ func (c *ChampshipMgr) NotifyAll() (interface{}, error) {
|
||||
func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) {
|
||||
log.Debug("ChampshipMgr ZeroUpdate")
|
||||
data := c.getData()
|
||||
c.lock.Lock()
|
||||
data.mu.Lock()
|
||||
data.ZeroTime = GoUtil.ZeroTimestamp()
|
||||
// 深拷贝 map,避免多个协程持有同一个 map 引用导致并发读写
|
||||
oldRank := make(map[int][]*ChampshipRank, len(data.Rank))
|
||||
@ -144,7 +146,7 @@ func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) {
|
||||
for k := range data.PreGroupInfo {
|
||||
c.SetRankCache(k)
|
||||
}
|
||||
c.lock.Unlock()
|
||||
data.mu.Unlock()
|
||||
|
||||
c.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
|
||||
c.ZeroUpdate()
|
||||
@ -159,7 +161,7 @@ func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) {
|
||||
|
||||
func (c *ChampshipMgr) NotifyPlayer() {
|
||||
data := c.getData()
|
||||
c.lock.Lock()
|
||||
data.mu.RLock()
|
||||
// 深拷贝需要通知的数据,避免在锁外访问 map
|
||||
notifyList := make([]struct {
|
||||
Uid int
|
||||
@ -176,7 +178,7 @@ func (c *ChampshipMgr) NotifyPlayer() {
|
||||
}{Uid: v[i].Uid, Rank: i + 1})
|
||||
}
|
||||
}
|
||||
c.lock.Unlock()
|
||||
data.mu.RUnlock()
|
||||
|
||||
// 在锁外通知,避免持锁时间过长
|
||||
for _, item := range notifyList {
|
||||
@ -186,8 +188,8 @@ func (c *ChampshipMgr) NotifyPlayer() {
|
||||
|
||||
func (c *ChampshipMgr) ai() (interface{}, error) {
|
||||
ChampshipData := c.getData()
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
ChampshipData.mu.Lock()
|
||||
defer ChampshipData.mu.Unlock()
|
||||
Now := GoUtil.Now()
|
||||
uids := make(map[int]struct{})
|
||||
for k, v := range ChampshipData.Rank {
|
||||
@ -248,8 +250,8 @@ func (c *ChampshipMgr) ai() (interface{}, error) {
|
||||
|
||||
func (c *ChampshipMgr) GetPreRankMsg(Uid int) *proto.ResChampshipPreRank {
|
||||
ChampshipData := c.getData()
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
ChampshipData.mu.RLock()
|
||||
defer ChampshipData.mu.RUnlock()
|
||||
GroupId := ChampshipData.PreGroupInfo[Uid]
|
||||
if GroupId == 0 {
|
||||
return &proto.ResChampshipPreRank{}
|
||||
@ -306,8 +308,8 @@ func (c *ChampshipMgr) GetPreRankMsg(Uid int) *proto.ResChampshipPreRank {
|
||||
// TODO 待优化
|
||||
func (c *ChampshipMgr) GetRankMsg(Uid int) *proto.ResChampshipRank {
|
||||
ChampshipData := c.getData()
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
ChampshipData.mu.RLock()
|
||||
defer ChampshipData.mu.RUnlock()
|
||||
GroupId := ChampshipData.GroupInfo[Uid]
|
||||
if GroupId == 0 {
|
||||
return &proto.ResChampshipRank{}
|
||||
@ -371,8 +373,8 @@ func (c *ChampshipMgr) group() (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
ChampshipData := c.getData()
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
ChampshipData.mu.Lock()
|
||||
defer ChampshipData.mu.Unlock()
|
||||
if len(ChampshipData.Pool) == 0 { // 未分配玩家池为空
|
||||
return nil, nil
|
||||
}
|
||||
@ -468,8 +470,8 @@ func (c *ChampshipMgr) group() (interface{}, error) {
|
||||
|
||||
func (c *ChampshipMgr) getGroupId(Uid int) int {
|
||||
ChampshipData := c.getData()
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
ChampshipData.mu.RLock()
|
||||
defer ChampshipData.mu.RUnlock()
|
||||
GroupId, ok := ChampshipData.GroupInfo[Uid]
|
||||
if ok {
|
||||
return GroupId
|
||||
@ -484,8 +486,8 @@ func (c *ChampshipMgr) inRank(m *msg.Msg) (interface{}, error) {
|
||||
GroupId := c.getGroupId(data.Uid)
|
||||
|
||||
ChampshipData := c.getData()
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
ChampshipData.mu.Lock()
|
||||
defer ChampshipData.mu.Unlock()
|
||||
|
||||
// 再次检查 GroupId,因为可能在等待锁期间被其他协程修改
|
||||
if currentGroupId, ok := ChampshipData.GroupInfo[data.Uid]; ok {
|
||||
@ -557,8 +559,8 @@ func (c *ChampshipMgr) inRank(m *msg.Msg) (interface{}, error) {
|
||||
|
||||
func (c *ChampshipMgr) getMyRank(Uid int) int {
|
||||
ChampshipData := c.getData()
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
ChampshipData.mu.RLock()
|
||||
defer ChampshipData.mu.RUnlock()
|
||||
GroupId := ChampshipData.GroupInfo[Uid]
|
||||
if GroupId == 0 {
|
||||
return 0
|
||||
@ -595,8 +597,8 @@ func (c *ChampshipMgr) unsafe_getMyRank(Uid int) int {
|
||||
|
||||
func (c *ChampshipMgr) getLastMyRank(Uid int) int {
|
||||
ChampshipData := c.getData()
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
ChampshipData.mu.RLock()
|
||||
defer ChampshipData.mu.RUnlock()
|
||||
GroupId := ChampshipData.PreGroupInfo[Uid]
|
||||
if GroupId == 0 {
|
||||
return 0
|
||||
|
||||
@ -49,6 +49,7 @@ type MessageMgr struct {
|
||||
type MessageData struct {
|
||||
MessageList map[int64]*MessageList
|
||||
PlayerList map[int64]int
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
type MessageList struct {
|
||||
@ -131,8 +132,8 @@ func (m *MessageMgr) MessageMgrInit() {
|
||||
func FixBug() {
|
||||
messageMgrData := getMessageData()
|
||||
// 先更新 PlayerList(需要加锁)
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
defer G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData.mu.Lock()
|
||||
defer messageMgrData.mu.Unlock()
|
||||
now := GoUtil.Now()
|
||||
for k, v := range messageMgrData.MessageList {
|
||||
if k < 100000 {
|
||||
@ -214,12 +215,12 @@ func ChampshipRankInfoHandler(data *msg.Msg) (interface{}, error) {
|
||||
func NotifyAllPlayerMsg(m *msg.Msg) {
|
||||
messageMgrData := getMessageData()
|
||||
// 先复制 PlayerList,避免长时间持有锁
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
messageMgrData.mu.Lock()
|
||||
playerListCopy := make(map[int64]int, len(messageMgrData.PlayerList))
|
||||
for k, v := range messageMgrData.PlayerList {
|
||||
playerListCopy[k] = v
|
||||
}
|
||||
G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData.mu.Unlock()
|
||||
|
||||
// 在锁外发送消息
|
||||
for PlayerId, node := range playerListCopy {
|
||||
@ -249,9 +250,9 @@ func CatnipPartnerHandler(data *msg.Msg) (interface{}, error) {
|
||||
func ReplyPlayerMsgASync(m *msg.Msg, reply interface{}) (interface{}, error) {
|
||||
clone := m.Reply(reply)
|
||||
messageMgrData := getMessageData()
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
messageMgrData.mu.Lock()
|
||||
node, ok := messageMgrData.PlayerList[int64(m.From)]
|
||||
G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData.mu.Unlock()
|
||||
|
||||
if ok {
|
||||
SendMsgToNodeAsync(clone, node)
|
||||
@ -272,10 +273,10 @@ func ClusterSyncHandler(data *msg.Msg) (interface{}, error) {
|
||||
})
|
||||
// 发送暂存区消息(先复制再释放锁,避免长时间持有锁)
|
||||
messageMgrData := getMessageData()
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
messageMgrData.mu.Lock()
|
||||
TempMessageList := messageMgrData.MessageList
|
||||
messageMgrData.MessageList = make(map[int64]*MessageList)
|
||||
G_GameLogicPtr.MessageMgr.lock.Unlock() // 立即释放锁,在锁外发送消息
|
||||
messageMgrData.mu.Unlock() // 立即释放锁,在锁外发送消息
|
||||
|
||||
log.Debug("[Middleware] Cluster sync send temp message len: %d", len(TempMessageList))
|
||||
for _, Message := range TempMessageList {
|
||||
@ -291,9 +292,9 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
|
||||
node := data.Extra.(int)
|
||||
messageMgrData := getMessageData()
|
||||
// 先更新 PlayerList(需要加锁)
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
messageMgrData.mu.Lock()
|
||||
messageMgrData.PlayerList[int64(data.From)] = node
|
||||
G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData.mu.Unlock()
|
||||
|
||||
log.Debug("[Middleware] Player login success player id: %v, node: %v", data.From, data.Extra.(int))
|
||||
// 对玩家消息列表加锁
|
||||
@ -331,9 +332,9 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
|
||||
|
||||
func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) {
|
||||
messageMgrData := getMessageData()
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
messageMgrData.mu.Lock()
|
||||
delete(messageMgrData.PlayerList, int64(data.From))
|
||||
G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData.mu.Unlock()
|
||||
log.Debug("[Middleware] Player logout success player id: %v", data.From)
|
||||
return nil, nil
|
||||
}
|
||||
@ -359,9 +360,9 @@ func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) {
|
||||
func NotifyPlayerMsgAsync(m *msg.Msg) {
|
||||
messageMgrData := getMessageData()
|
||||
// 检查玩家是否在线(需要加锁)
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
messageMgrData.mu.Lock()
|
||||
node, ok := messageMgrData.PlayerList[int64(m.To)]
|
||||
G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData.mu.Unlock()
|
||||
// 在线则直接发送消息
|
||||
if ok {
|
||||
SendMsgToNodeAsync(m, node)
|
||||
@ -375,9 +376,9 @@ func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) {
|
||||
// 遍历消息列表,发送消息给在线玩家
|
||||
|
||||
// 检查玩家是否在线(需要加锁)
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
messageMgrData.mu.Lock()
|
||||
node, ok := messageMgrData.PlayerList[int64(PlayerId)]
|
||||
G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData.mu.Unlock()
|
||||
// 在线则直接发送消息
|
||||
if ok {
|
||||
SendMsgToNodeAsync(data, node)
|
||||
@ -885,8 +886,9 @@ func sendMessageSync(m *msg.Msg, node int) (*msg.Msg, error) {
|
||||
|
||||
// 保存消息到本地
|
||||
func saveMessage(m *msg.Msg) error {
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
defer G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
data := getMessageData()
|
||||
data.mu.Lock()
|
||||
defer data.mu.Unlock()
|
||||
// 使用不加锁的内部方法,避免死锁
|
||||
messages := getMessgeUnsafe(int64(m.To))
|
||||
messages.mu.Lock()
|
||||
@ -933,8 +935,9 @@ func getMessgeUnsafe(PlayerId int64) *MessageList {
|
||||
|
||||
// getMessge 获取消息列表(加锁版本)
|
||||
func getMessge(PlayerId int64) *MessageList {
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
defer G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData := getMessageData()
|
||||
messageMgrData.mu.Lock()
|
||||
defer messageMgrData.mu.Unlock()
|
||||
return getMessgeUnsafe(PlayerId)
|
||||
}
|
||||
|
||||
@ -968,8 +971,8 @@ func deleteMessage(m *msg.Msg) error {
|
||||
if len(messages.Messages) == 0 {
|
||||
// 如果消息列表为空,则删除该玩家的消息列表
|
||||
messageMgrData := getMessageData()
|
||||
G_GameLogicPtr.MessageMgr.lock.Lock()
|
||||
defer G_GameLogicPtr.MessageMgr.lock.Unlock()
|
||||
messageMgrData.mu.Lock()
|
||||
defer messageMgrData.mu.Unlock()
|
||||
delete(messageMgrData.MessageList, int64(m.To))
|
||||
}
|
||||
return nil
|
||||
|
||||
@ -139,9 +139,7 @@ func (s *ServerMod) SaveData() {
|
||||
DbData.Key = s.key
|
||||
DbData.UpdataTime = GoUtil.Now()
|
||||
var err error
|
||||
s.lock.Lock()
|
||||
DbData.ModData, err = GoUtil.GobMarshal(s.data)
|
||||
s.lock.Unlock()
|
||||
if err != nil {
|
||||
log.Error("SaveData Marshal failed,Mod Key: %s err:%v", s.key, err)
|
||||
return
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"server/game/mod/msg"
|
||||
GoUtil "server/game_util"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -23,6 +24,7 @@ type VarData struct {
|
||||
NewUseVar map[int]map[string]*VarExpireData
|
||||
ZeroTime int64
|
||||
Version int64
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
const (
|
||||
@ -64,8 +66,8 @@ func (f *VarMgr) Init() {
|
||||
|
||||
func (f *VarMgr) fixbug() {
|
||||
data := f.getData()
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
data.mu.Lock()
|
||||
defer data.mu.Unlock()
|
||||
for k, v := range data.NewUseVar {
|
||||
if v != nil {
|
||||
del := true
|
||||
@ -87,8 +89,8 @@ func (f *VarMgr) version() {
|
||||
case 0:
|
||||
// future version update
|
||||
data := f.getData()
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
data.mu.Lock()
|
||||
defer data.mu.Unlock()
|
||||
// set to next version
|
||||
for k, v := range data.UserVar {
|
||||
if v != nil {
|
||||
@ -127,8 +129,9 @@ func (f *VarMgr) ZeroUpdate() {
|
||||
}
|
||||
|
||||
func (f *VarMgr) HandleCatnipPartner(Uid, Partner, GameId int, EndTime int64) (interface{}, error) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
data := f.getData()
|
||||
data.mu.Lock()
|
||||
defer data.mu.Unlock()
|
||||
|
||||
OtherPartnerInfo := f.GetUserVar(Uid, VAR_CATNIP_PARTNER)
|
||||
MyPartnerInfo := f.GetUserVar(Partner, VAR_CATNIP_PARTNER)
|
||||
@ -149,8 +152,6 @@ func (f *VarMgr) HandleCatnipPartner(Uid, Partner, GameId int, EndTime int64) (i
|
||||
}
|
||||
|
||||
func (f *VarMgr) SetUserVar(uid int, key string, value interface{}) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
varData := f.getData().NewUseVar[uid]
|
||||
if varData == nil {
|
||||
varData = make(map[string]*VarExpireData)
|
||||
@ -167,8 +168,6 @@ func (f *VarMgr) SetUserVar(uid int, key string, value interface{}) {
|
||||
}
|
||||
|
||||
func (f *VarMgr) GetUserVar(uid int, key string) *VarExpireData {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
varData := f.getData().NewUseVar[uid]
|
||||
if varData == nil {
|
||||
varData = make(map[string]*VarExpireData)
|
||||
@ -183,8 +182,6 @@ func (f *VarMgr) GetUserVar(uid int, key string) *VarExpireData {
|
||||
}
|
||||
|
||||
func (f *VarMgr) SetVar(key string, value interface{}) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.getData().NewVar[key] = &VarExpireData{
|
||||
D: value,
|
||||
}
|
||||
@ -201,8 +198,8 @@ func getVarData() *VarData {
|
||||
|
||||
func SetVarDataHandler(m *msg.Msg) (interface{}, error) {
|
||||
data := getVarData()
|
||||
G_GameLogicPtr.VarMgr.lock.Lock()
|
||||
defer G_GameLogicPtr.VarMgr.lock.Unlock()
|
||||
data.mu.Lock()
|
||||
defer data.mu.Unlock()
|
||||
if v, ok := m.Extra.(msg.VarData); ok {
|
||||
ved, ok := data.NewVar[v.Key]
|
||||
if !ok {
|
||||
@ -240,8 +237,8 @@ func SetVarDataHandler(m *msg.Msg) (interface{}, error) {
|
||||
|
||||
func GetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
|
||||
data := getVarData()
|
||||
G_GameLogicPtr.VarMgr.lock.Lock()
|
||||
defer G_GameLogicPtr.VarMgr.lock.Unlock()
|
||||
data.mu.Lock()
|
||||
defer data.mu.Unlock()
|
||||
userVar := &VarExpireData{}
|
||||
if v, ok := m.Extra.(msg.VarData); ok {
|
||||
if varData, ok := data.NewUseVar[m.From]; ok {
|
||||
@ -258,8 +255,8 @@ func GetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
|
||||
|
||||
func SetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
|
||||
data := getVarData()
|
||||
G_GameLogicPtr.VarMgr.lock.Lock()
|
||||
defer G_GameLogicPtr.VarMgr.lock.Unlock()
|
||||
data.mu.Lock()
|
||||
defer data.mu.Unlock()
|
||||
if v, ok := m.Extra.(msg.VarData); ok {
|
||||
varData := data.NewUseVar[m.To]
|
||||
if varData == nil {
|
||||
@ -304,8 +301,6 @@ func SetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
|
||||
|
||||
func GetVarDataHandler(m *msg.Msg) (interface{}, error) {
|
||||
data := getVarData()
|
||||
G_GameLogicPtr.VarMgr.lock.Lock()
|
||||
defer G_GameLogicPtr.VarMgr.lock.Unlock()
|
||||
varData := &VarExpireData{}
|
||||
if v, ok := m.Extra.(msg.VarData); ok {
|
||||
varData, _ = data.NewVar[v.Key]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user