Merge branch 'cluster2' into develop

This commit is contained in:
hahwu 2025-12-24 15:05:16 +08:00
commit b336e42f21
26 changed files with 1305 additions and 618 deletions

View File

@ -27,14 +27,14 @@ func HandShake(a *Agent) {
log.Debug("HandShake GobMarshal err %v", err)
return
}
// log.Debug("握手 server id :%d", conf.Server.ServerID)
log.Debug("握手 server id :%d", conf.Server.ServerID)
a.WriteMsg(data)
}
// 握手回调
func HandShakeRecv(a *Agent, m *msg.Msg) error {
ServerId := m.From
// log.Debug("收到握手回复 ServerId %v", ServerId)
log.Debug("收到握手回复 ServerId %v", ServerId)
a.ServerId = ServerId
serverAgent.Store(ServerId, a)
@ -48,19 +48,14 @@ func HandShakeRecv(a *Agent, m *msg.Msg) error {
RemoteAddr: m.Extra.(string),
},
})
}
} else {
syncMsg := &msg.Msg{
Type: msg.CLUSTER_FRIEND_SYNC,
To: ServerId,
HandleType: msg.HANDLE_MOD_CLUSTER_SYNC,
}
sendGameMsg(syncMsg)
// fmt.Print("现有区服连接:")
// serverAgent.Range(func(key, value interface{}) bool {
// fmt.Print(key)
// fmt.Print(",")
// return true
// })
// fmt.Println()
}
return nil
}
@ -102,7 +97,7 @@ func connectRemote(RemoteAddr string, ConnType int, ConnLabel string) error {
client.NewAgent = newAgent
client.ConnType = ConnType
client.ConnLabel = ConnLabel
client.ConnectInterval = time.Duration(time.Minute * 5)
client.ConnectInterval = time.Duration(time.Minute * 1)
if ConnType == ClusterCenterId { // 中心服断开重连
client.AutoReconnect = true
}
@ -113,6 +108,9 @@ func connectRemote(RemoteAddr string, ConnType int, ConnLabel string) error {
}
func SendServerMsg(m *msg.Msg, serverId int) error {
if m.UniKey == "" {
m.UniKey = GoUtil.UniKey(fmt.Sprintf("%v,Cluster Msg", m))
}
if v, ok := serverAgent.Load(serverId); ok {
data, err := GoUtil.GobMarshal(m)
if err != nil {
@ -126,32 +124,32 @@ func SendServerMsg(m *msg.Msg, serverId int) error {
}
func CallServerMsg(m *msg.Msg, serverId int) (*msg.Msg, error) {
if m.UniKey == "" {
m.UniKey = GoUtil.UniKey(fmt.Sprintf("%v,Cluster Msg", m))
}
v, ok := serverAgent.Load(serverId)
// 之后再发送消息
if !ok {
return nil, fmt.Errorf("server %d not online", serverId)
}
// 先注册回调通道,避免发送出去后对方快速返回导致丢失
newChan := make(chan *msg.Msg, 1)
registerChanel(m.UniKey, newChan)
defer unregisterChanel(m.UniKey)
// 之后再发送消息
if v, ok := serverAgent.Load(serverId); ok {
data, err := GoUtil.GobMarshal(m)
if err != nil {
log.Debug("CallServerMsg GobMarshal err %v", err)
return nil, err
}
v.(network.Agent).WriteMsg(data)
} else {
return nil, fmt.Errorf("server %d not online", serverId)
}
// 等待返回(直接接收一次)
timeout := time.After(15 * time.Second)
timeout := time.After(5 * time.Second)
select {
case backm := <-newChan:
if backm == nil {
return nil, fmt.Errorf("server %d not response", serverId)
}
log.Debug("CallServerMsg reply %v", backm)
return backm, nil
case <-timeout:
return nil, fmt.Errorf("timeout waiting for server %d response", serverId)
@ -172,13 +170,7 @@ func SendMsgAll(m *msg.Msg) {
func processMsg(a *Agent, m *msg.Msg) error {
var err error
// 先处理同步回调
if m.UniKey != "" {
if chanel, ok := CallbackChan[m.UniKey]; ok {
chanel <- m
return nil
}
}
if fun, ok := FuncMap[m.Type]; ok {
err = fun(a, m)
} else {

View File

@ -16,13 +16,6 @@ import (
"github.com/jmoiron/sqlx"
)
type user struct {
Id int `db:"user_id"`
Sex int `db:"sex"`
UserName string `db:"username"`
Email string `db:"email"`
}
var SqlDb *sqlx.DB
var sqlDbMu sync.Mutex
@ -271,6 +264,22 @@ func GetPlayerBaseInfoFromDbByName(name string) *ResPlayerBaseInfo {
return &res
}
func GetPlayerBan(name string) int64 {
sqlStr := "SELECT ban FROM t_player_baseinfo WHERE user_name = ?"
var ban int64
if err := SqlDb.Get(&ban, sqlStr, name); err != nil {
log.Debug("table: %s, sql :%s, exec failed, err:%v\n", "PlayerBaseInfo", sqlStr, err)
return 0
}
return ban
}
func UpdatePlayerBan(uid int64, ban int64) error {
sqlStr := "UPDATE t_player_baseinfo SET ban = ? WHERE dwUin = ?"
_, err := SqlDb.Exec(sqlStr, ban, uid)
return err
}
func UpdatePlayerBaseInfoName(oldName, newName string) error {
sqlStr := "UPDATE t_player_baseinfo SET user_name = ? WHERE user_name = ?"
_, err := SqlDb.Exec(sqlStr, newName, oldName)

View File

@ -164,6 +164,17 @@ func RedisGetKey(key string) (string, error) {
return val, nil
}
func RedisGetKeyBytes(key string) ([]byte, error) {
if RdbRead == nil {
return nil, nil
}
val, err := RdbRead.Get(ctx, key).Bytes()
if err != nil {
return nil, err
}
return val, nil
}
func RedisDelKey(key string) {
if RdbWrite == nil {
log.Debug("redis write client is nil")

View File

@ -37,7 +37,7 @@ type ResPlayerBaseInfo struct {
Guild int32 `db:"guild"`
PackUnlockCount int32 `db:"pack_unlock_count"`
LastPlayTime int32 `db:"last_play_time"`
EnergyBuyCount int32 `db:"EnergyBuyCount"`
Ban int64 `db:"ban"`
UserName string `db:"user_name"`
NickName string `db:"nick_name"`
LoginTime int32 `db:"login_time"`

View File

@ -83,8 +83,8 @@ type GameLogic struct {
MailMgr *MailMgr // 邮件管理器
ChampshipMgr *ChampshipMgr // 锦标赛管理器
VarMgr *VarMgr // 变量管理器
BanMgr *BanMgr // 封号管理器
StartTime int64 // 服务器启动时间
MessageMgr *MessageMgr // 消息管理器
}
type ServerInfo struct {
@ -192,7 +192,6 @@ func (ad *GameLogic) NewAccountInsertDataToDB() bool {
playerInfo.MusicCode = 1
playerInfo.Guild = 1
playerInfo.PackUnlockCount = 5
playerInfo.EnergyBuyCount = 0
playerInfo.UserName = ad.Db_AccountInfo.UserName
playerInfo.LoginTime = (int32)(time.Now().Unix())
playerInfo.LogoutTime = 0
@ -271,68 +270,6 @@ func (ad *GameLogic) CreateFriendMgr() {
ad.FriendMgr.Init()
}
func (ad *GameLogic) FriendMgrSend(m *MsgMod.Msg) {
ad.FriendMgr.Send(m)
}
func (ad *GameLogic) SetUserData(Uid int, Op int, Data interface{}) {
ad.FriendMgr.Send(&MsgMod.Msg{
From: Uid,
To: Uid,
Type: MsgMod.HANDLE_TYPE_VAR_USER_SET,
SendT: GoUtil.Now(),
Extra: VarOpration{Type: Op, Data: Data},
})
}
func (ad *GameLogic) SetDataSync(Uid int, Op int, Data interface{}) error {
_, err := ad.VarMgr.Call(&MsgMod.Msg{
From: Uid,
To: Uid,
Type: MsgMod.HANDLE_TYPE_VAR_EXPIRE_SET,
SendT: GoUtil.Now(),
Extra: VarOpration{Type: Op, Data: Data},
})
return err
}
func (ad *GameLogic) SetCatnipPartner(Uid int, GameId int, PartnerUid int, EndT int64) error {
_, err := ad.VarMgr.Call(&MsgMod.Msg{
From: Uid,
To: Uid,
Type: MsgMod.HANDLE_TYPE_SET_CATNIP_PARTNER,
SendT: GoUtil.Now(),
End: EndT,
Extra: map[string]interface{}{
"uid": Uid,
"game_id": GameId,
"partner_uid": PartnerUid,
},
})
return err
}
func (ad *GameLogic) GetUserData(Uid int) *VarUserData {
result, err := ad.FriendMgr.Call(&MsgMod.Msg{
From: Uid,
To: Uid,
Type: MsgMod.HANDLE_TYPE_VAR_USER_GET,
SendT: GoUtil.Now(),
})
if err != nil {
return &VarUserData{}
}
return result.(*VarUserData)
}
func (ad *GameLogic) FriendMgrCall(m *MsgMod.Msg) interface{} {
result, err := ad.FriendMgr.Call(m)
if err != nil {
return nil
}
return result
}
// 排行榜管理器
func (ad *GameLogic) CreateRankMgr() {
ad.RankMgr = &RankMgr{
@ -361,6 +298,13 @@ func (ad *GameLogic) CreateMailMgr() {
ad.MailMgr.Init()
}
func (ad *GameLogic) CreateMessageMgr() {
ad.MessageMgr = &MessageMgr{
ServerMod: new(ServerMod),
}
ad.MessageMgr.MessageMgrInit()
}
func (ad *GameLogic) MailMgrSend(m *MsgMod.Msg) {
ad.MailMgr.Send(m)
}
@ -413,26 +357,6 @@ func (ad *GameLogic) VarMgrCall(m *MsgMod.Msg) interface{} {
return result
}
// 封号管理器
func (ad *GameLogic) CreateBanMgr() {
ad.BanMgr = &BanMgr{
ServerMod: new(ServerMod),
}
ad.BanMgr.Init()
}
func (ad *GameLogic) BanMgrSend(m *MsgMod.Msg) {
ad.BanMgr.Send(m)
}
func (ad *GameLogic) BanMgrCall(m *MsgMod.Msg) interface{} {
result, err := ad.BanMgr.Call(m)
if err != nil {
return nil
}
return result
}
func (ad *GameLogic) GetSimplePlayerByUid(Id int) *PlayerSimpleData {
if Id == 0 {
return nil
@ -546,12 +470,14 @@ func G_getGameLogic() *GameLogic {
G_GameLogicPtr.InitActivity() // 初始化活动
G_GameLogicPtr.GetVersion() // 获取版本号
G_GameLogicPtr.CreateLogManager() //加载日志管理器
if conf.Server.ServerType == "center" {
G_GameLogicPtr.CreateFriendMgr() //创建好友管理器
G_GameLogicPtr.CreateRankMgr() //创建排行榜管理器
G_GameLogicPtr.CreateMailMgr() //创建邮件管理器
G_GameLogicPtr.CreateChampshipMgr() // 创建竞标赛管理器
G_GameLogicPtr.CreateVarMgr() // 创建变量管理器
G_GameLogicPtr.CreateBanMgr() // 创建封号管理器
}
G_GameLogicPtr.CreateRankMgr() //创建排行榜管理器
G_GameLogicPtr.CreateMailMgr() //创建邮件管理器
G_GameLogicPtr.CreateMessageMgr() // 创建消息管理器
ClusterMgrInit() //初始化集群
G_GameLogicPtr.StartTime = time.Now().Unix()
// G_GameLogicPtr.CreateHttpManager()
@ -656,7 +582,6 @@ func (ad *GameLogic) ReplaceExistPlayerAndAgent(a gate.Agent, player *Player) er
if ok {
Timer.Stop()
}
player.SyncFriendMsg()
log.Debug("player %d 重连", player.M_DwUin)
return nil
}
@ -733,7 +658,6 @@ func (ad *GameLogic) RegisterNetWorkFunc() {
RegisterMsgProcessFunc("ReqSetPetName", ReqSetPetName) // 设置宠物名字
RegisterMsgProcessFunc("ReqSetFacebookUrl", ReqSetFacebookUrl) // 设置facebook地址
RegisterMsgProcessFunc("ReqPlayerBaseInfo", ReqPlayerBaseInfofunction) // 请求玩家基本信息
RegisterMsgProcessFunc("UpdateBaseItemInfo", UpdateBaseItemInfofunction) // 保存引导
RegisterMsgProcessFunc("ReqKv", ReqKv) // 保存客户端数据
RegisterMsgProcessFunc("ReqGetEnergyByAD", ReqGetEnergyByAD) // 看广告获取能量
RegisterMsgProcessFunc("ReqBuyEnergy", ReqBuyEnergy) // 购买能量
@ -989,11 +913,9 @@ func (ad *GameLogic) GetStartTime() int64 {
}
func NotifyPlayer(Uid int, m *MsgMod.Msg) {
p := G_GameLogicPtr.GetPlayer(int64(Uid))
if p == nil || p.stop {
return
}
p.Send(m)
m.To = Uid
m.HandleType = MsgMod.HANDLE_MOD_PLAYER_MSG
CenterPlayerMsgHandler(m)
}
func Destroy() {
@ -1009,7 +931,6 @@ func Destroy() {
G_GameLogicPtr.ChampshipMgr.SaveData()
G_GameLogicPtr.MailMgr.SaveData()
G_GameLogicPtr.VarMgr.SaveData()
G_GameLogicPtr.BanMgr.SaveData()
G_GameLogicPtr.MLogManager.Close()
}
log.Debug("服务器下线完成")

View File

@ -1,7 +1,6 @@
package game
import (
"fmt"
activityCfg "server/conf/activity"
catnipCfg "server/conf/catnip"
guesscolorCfg "server/conf/guess_color"
@ -360,34 +359,33 @@ func (p *Player) CatnipBackData() {
}
tmpData := make(map[int]*msg.CatnipInvite)
InviteList := make([]*msg.CatnipInvite, 0)
for Uid, Info := range CatnipMod.InviteList {
tmpData[Uid] = &msg.CatnipInvite{
Uid: int64(Uid),
Time: Info.Time,
for uid, info := range CatnipMod.InviteList {
tmpData[uid] = &msg.CatnipInvite{
Uid: int64(uid),
Time: info.Time,
Type: 1,
}
}
for Uid, Info := range CatnipMod.BeInvitedList {
tmpData[Uid] = &msg.CatnipInvite{
Uid: int64(Uid),
Time: Info.Time,
for uid, info := range CatnipMod.BeInvitedList {
tmpData[uid] = &msg.CatnipInvite{
Uid: int64(uid),
Time: info.Time,
Type: 2,
}
}
for Uid := range FriendMod.NewFriendList {
key := fmt.Sprintf("catnip_partner_%d", Uid)
Var := G_GameLogicPtr.VarMgr.GetExpireVar(key)
if len(GoUtil.IntSlice(Var.D)) >= 4 {
tmpData[Uid] = &msg.CatnipInvite{
Uid: int64(Uid),
for uid := range FriendMod.NewFriendList {
partnerList := p.GetCatnipPartner(uid)
if len(GoUtil.IntSlice(partnerList)) >= 4 {
tmpData[uid] = &msg.CatnipInvite{
Uid: int64(uid),
Type: 3,
}
continue
}
if _, ok := tmpData[Uid]; !ok {
tmpData[Uid] = &msg.CatnipInvite{
Uid: int64(Uid),
if _, ok := tmpData[uid]; !ok {
tmpData[uid] = &msg.CatnipInvite{
Uid: int64(uid),
Type: 0,
}
}
@ -417,14 +415,3 @@ func (p *Player) CatnipBackData() {
}
p.PushClientRes(res)
}
// 设置猫草大作战游戏锁
func (p *Player) SetCatnipGameLock(Uid int, GameId int) error {
ActivityInfo := p.GetActivityInfoById(activity.ACT_TYPE_CATNIP)
return G_GameLogicPtr.SetDataSync(int(p.M_DwUin), VAR_OP_CATNIP_LOCK, CatnipLock{
Uid: int(p.M_DwUin),
Partner: Uid,
GameId: GameId,
End: int(ActivityInfo.EndT), // 锁
})
}

View File

@ -100,7 +100,7 @@ func VerifyUser(accountInfo *db.Db_Account, detail *msg.ReqLogin) (ResLogin *msg
return
}
if G_GameLogicPtr.BanMgr.IsBanned(playerbaseinfo.DwUin) {
if playerbaseinfo.Ban > GoUtil.Now() || playerbaseinfo.Ban == -1 {
ResLogin = &msg.ResLogin{
ResultCode: MergeConst.Protocol_Error_Account_Ban,
DwUin: 0,
@ -176,7 +176,7 @@ func AdminPlayerInfo(args []interface{}) error {
res["Cumulative"] = player.PlayMod.getBaseMod().Cumulative
res["RegisterTime"] = player.GetPlayerBaseMod().GetRegisterTime()
res["TodayCumulative"] = player.PlayMod.getBaseMod().TodayCumulative
res["Ban"] = G_GameLogicPtr.BanMgr.GetBanInfo(player.M_DwUin).EndTime
res["Ban"] = db.GetPlayerBan(player.PlayMod.getBaseMod().Account)
if online {
res["Cumulative"] = int64(player.PlayMod.getBaseMod().Cumulative) + GoUtil.Now() - int64(player.PlayMod.getBaseMod().LoginTime)
res["TodayCumulative"] = int64(player.PlayMod.getBaseMod().TodayCumulative) + GoUtil.Now() - int64(player.PlayMod.getBaseMod().LoginTime)
@ -283,7 +283,7 @@ func ReqAdminBan(args []interface{}) error {
res := make(map[string]interface{})
res["Code"] = 0
res["Msg"] = "ok"
G_GameLogicPtr.BanMgr.BanUser(req.Uid, int64(req.Time), req.Reason)
db.UpdatePlayerBan(req.Uid, int64(req.Time))
AdminPlayerBack(a, res)
return nil
}

View File

@ -1,69 +0,0 @@
package game
import (
"encoding/gob"
GoUtil "server/game_util"
)
type BanMgr struct {
*ServerMod
}
type BanData struct {
NewBanList map[int64]*BanInfo // 新增的封禁列表
}
type BanInfo struct {
UserId int64 // 玩家ID
EndTime int64 // 封禁结束时间0表示永久封禁
Reason string // 封禁原因
}
func (f *BanMgr) Init() {
gob.Register(&BanData{})
f.key = BAN_MGR_KEY
f.data = &BanData{
NewBanList: make(map[int64]*BanInfo),
}
// 注册处理函数
f.init()
if f.data.(*BanData).NewBanList == nil {
f.data.(*BanData).NewBanList = make(map[int64]*BanInfo)
}
}
func (f *BanMgr) IsBanned(userId int64) bool {
if f.data.(*BanData).NewBanList == nil {
return false
}
Info, banned := f.data.(*BanData).NewBanList[userId]
if !banned {
return false
}
return Info.EndTime > GoUtil.Now() || Info.EndTime == -1 // 如果EndTime为0表示永久封禁
}
func (f *BanMgr) GetBanInfo(userId int64) *BanInfo {
if f.data.(*BanData).NewBanList == nil {
return &BanInfo{}
}
Info, banned := f.data.(*BanData).NewBanList[userId]
if !banned {
return &BanInfo{}
}
return Info
}
func (f *BanMgr) BanUser(userId int64, endTime int64, reason string) {
f.data.(*BanData).NewBanList[userId] = &BanInfo{
UserId: userId,
EndTime: endTime,
Reason: reason,
}
f.SaveData()
}
func (f *BanMgr) UnbanUser(userId int64) {
delete(f.data.(*BanData).NewBanList, userId)
f.SaveData()
}

View File

@ -81,67 +81,53 @@ func (c *ChampshipMgr) Init() {
}
// 注册处理函数
c.init()
c.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_GROUP, c.group)
c.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_INRANK, c.inRank)
c.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_AI, c.ai)
c.RegisterHandler(msg.SERVER_ZERO_UPDATE, c.ZeroUpdate)
c.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY2, c.NotifyAll)
Now := GoUtil.Now()
ZeroTime := GoUtil.ZeroTimestamp()
if c.getData().ZeroTime != ZeroTime {
c.ZeroUpdate(&msg.Msg{})
c.ZeroUpdate()
}
Remain := Now - ZeroTime
Remain1 := 1800 - Remain%1800
c.mDispatr.AfterFunc(time.Duration(Remain1)*time.Second, func() { // 30分钟后重新分组
c.Send(&msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_GROUP,
})
c.group()
})
c.mDispatr.AfterFunc(time.Duration(60)*time.Second, func() {
c.Send(&msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_AI,
})
c.ai()
})
c.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
c.Send(&msg.Msg{
Type: msg.SERVER_ZERO_UPDATE,
})
c.ZeroUpdate()
})
}
func (c *ChampshipMgr) NotifyAll(m *msg.Msg) (interface{}, error) {
G_GameLogicPtr.NotifyAll(&msg.Msg{
func (c *ChampshipMgr) NotifyAll() (interface{}, error) {
NotifyAllPlayerMsg(&msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY,
HandleType: msg.HANDLE_MOD_PLAYER_MSG,
})
return nil, nil
}
func (c *ChampshipMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) {
func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) {
log.Debug("ChampshipMgr ZeroUpdate")
c.getData().ZeroTime = GoUtil.ZeroTimestamp()
c.getData().PreRank = c.getData().Rank
c.getData().PreRobot = c.getData().Robot
c.getData().PreGroupInfo = c.getData().GroupInfo
c.getData().AutoId = 0
c.getData().RobotId = 1
c.getData().Robot = make(map[int]*ChampshipRobot, 0)
c.getData().Rank = make(map[int][]*ChampshipRank, 0)
c.getData().GroupInfo = make(map[int]int, 0)
c.update = true
c.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
c.Send(&msg.Msg{
Type: msg.SERVER_ZERO_UPDATE,
})
c.ZeroUpdate()
})
c.NotifyPlayer()
c.mDispatr.AfterFunc(time.Duration(1800)*time.Second, func() {
c.Send(&msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY2,
})
c.NotifyAll()
})
return nil, nil
}
@ -158,7 +144,7 @@ func (c *ChampshipMgr) NotifyPlayer() {
}
}
func (c *ChampshipMgr) ai(m *msg.Msg) (interface{}, error) {
func (c *ChampshipMgr) ai() (interface{}, error) {
ChampshipData := c.getData()
Now := GoUtil.Now()
for k, v := range ChampshipData.Rank {
@ -205,9 +191,7 @@ func (c *ChampshipMgr) ai(m *msg.Msg) (interface{}, error) {
ChampshipData.Rank[k] = v
}
c.mDispatr.AfterFunc(time.Duration(60)*time.Second, func() {
c.Send(&msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_AI,
})
c.ai()
})
return nil, nil
}
@ -265,6 +249,8 @@ func (c *ChampshipMgr) GetPreRankMsg(Uid int) *proto.ResChampshipPreRank {
RankList: RL,
}
}
// TODO 待优化
func (c *ChampshipMgr) GetRankMsg(Uid int) *proto.ResChampshipRank {
ChampshipData := c.getData()
GroupId := ChampshipData.GroupInfo[Uid]
@ -320,11 +306,9 @@ func (c *ChampshipMgr) GetRankMsg(Uid int) *proto.ResChampshipRank {
}
// 分组
func (c *ChampshipMgr) group(m *msg.Msg) (interface{}, error) {
func (c *ChampshipMgr) group() (interface{}, error) {
c.mDispatr.AfterFunc(time.Duration(1800)*time.Second, func() { // 30分钟后重新分组
c.Send(&msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_GROUP,
})
c.group()
})
Now := GoUtil.Now()
Zero := GoUtil.ZeroTimestamp()

View File

@ -35,7 +35,7 @@ func (p *Player) Charge(ChargeId int) {
}
func (p *Player) SendCharge(d *ChargeExtra) {
G_GameLogicPtr.FriendMgrSend(&MsgMod.Msg{
FriendMgrSend(&MsgMod.Msg{
From: int(p.M_DwUin),
Type: MsgMod.HANDLE_TYPE_SEND_CHARGE,
To: int(d.Uid),

View File

@ -11,20 +11,12 @@ func ClusterMgrInit() {
go func() {
for {
m := <-mergeCluster.MsgChan
clusterHandlerProcess(m)
MessageHandle(m)
}
}()
}
func clusterHandlerProcess(m *msg.Msg) {
if fun, ok := clusterHandler[m.Type]; ok {
fun(m)
} else {
FriendMgrSend(m)
}
}
func RegisterClusterHandler(t int, fun func(*msg.Msg) error) {
clusterHandler[t] = fun
}

View File

@ -3,7 +3,6 @@ package game
import (
"encoding/gob"
"fmt"
"server/MergeConst"
mergeCluster "server/cluster"
"server/conf"
"server/game/mod/card"
@ -45,7 +44,6 @@ func (f *FriendMgr) Init() {
f.RegisterHandler(msg.HANDLE_TYPE_APPLY, f.sendToPlayer)
f.RegisterHandler(msg.HADNLE_TYPE_AGREE, f.sendToPlayer)
f.RegisterHandler(msg.HANDLE_TYPE_DEL, f.sendToPlayer)
f.RegisterHandler(msg.HANDLE_TYPE_SYNC, f.sync)
f.RegisterHandler(msg.HANDLE_TYPE_REFUSE, f.sendToPlayer)
f.RegisterHandler(msg.HANDLE_TYPE_INVITE_ADD_FRIEND, f.sendToPlayer)
f.RegisterHandler(msg.HANDLE_TYPE_INVITE_FRIEND, f.sendToPlayer)
@ -87,11 +85,6 @@ func (f *FriendMgr) Init() {
f.RegisterHandler(msg.HANDLE_TYPE_PLAYROOM_KISS, f.sendToPlayerOnline)
f.RegisterHandler(msg.HANDLE_TYPE_PLAYROOM_GAME, f.sendToPlayer)
f.RegisterHandler(msg.HANDLE_TYPE_VAR_USER_GET, f.GetVarUserData)
f.RegisterHandler(msg.HANDLE_TYPE_VAR_USER_SET, f.SetVarUserData)
f.RegisterHandler(msg.HANDLE_TYPE_VAR_EXPIRE_SET, f.SetExpireVarData)
f.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_LOGIN, f.SendMsgToCenter)
f.RegisterHandler(msg.HANDLE_TYPE_CHAMPSHIP_INRANK, f.SendMsgToCenter)
}
@ -138,71 +131,6 @@ func (f *FriendMgr) sendToPlayerOnline(m *msg.Msg) (interface{}, error) {
return nil, nil
}
// 同步信息
func (f *FriendMgr) sync(m *msg.Msg) (interface{}, error) {
data := f.getData().List[m.From]
return data, nil
}
func (f *FriendMgr) GetVarUserData(m *msg.Msg) (interface{}, error) {
Key := GoUtil.GetUserKey(int64(m.To))
data := G_GameLogicPtr.VarMgr.GetUserVar(Key)
if data == nil {
data = &VarUserData{
Upvote: 0,
}
}
return data, nil
}
func (f *FriendMgr) SetVarUserData(m *msg.Msg) (interface{}, error) {
VarOp := m.Extra.(VarOpration)
Key := GoUtil.GetUserKey(int64(m.To))
data := G_GameLogicPtr.VarMgr.GetUserVar(Key)
switch VarOp.Type {
case VAR_OP_UPVOTE:
data.Upvote++
case VAR_OP_CHIP:
data.Chip += VarOp.Data.(int)
case VAR_OP_CHIP_SET:
data.Chip = VarOp.Data.(int)
case VAR_OP_KISS:
data.Kiss = VarOp.Data.(int)
}
return &VarOpration{
Data: data,
Code: MergeConst.SUCCESS,
}, nil
}
func (f *FriendMgr) SetExpireVarData(m *msg.Msg) (interface{}, error) {
VarOp := m.Extra.(VarOpration)
switch VarOp.Type {
case VAR_OP_CATNIP_LOCK:
data := VarOp.Data.(CatnipLock)
MyKey := GoUtil.GetCatnipLockKey(data.Uid, data.GameId)
OtherKey := GoUtil.GetCatnipLockKey(data.Partner, data.GameId)
ExpireData := G_GameLogicPtr.VarMgr.GetExpireVar(OtherKey)
if _, ok := ExpireData.D.(*CatnipLock); ok {
return nil, fmt.Errorf("catnip lock already exists for %d in game %d", data.Uid, data.GameId)
}
G_GameLogicPtr.VarMgr.SetExpireVar(MyKey, &VarExpireData{
T: int64(data.End + 24*3600), // 设置过期时间
D: &data,
})
G_GameLogicPtr.VarMgr.SetExpireVar(OtherKey, &VarExpireData{
T: int64(data.End + 24*3600), // 设置过期时间
D: &CatnipLock{
Uid: data.Partner,
Partner: data.Uid,
GameId: data.GameId,
End: data.End,
},
})
}
return nil, nil
}
// 发送消息给玩家
func sendToPlayer(m *msg.Msg) error {
p := G_GameLogicPtr.GetPlayer(int64(m.To))
@ -222,24 +150,6 @@ func sendToPlayerOnline(m *msg.Msg) error {
return nil
}
func FriendMgrSend(m1 *msg.Msg) error {
if m1.SendT == 0 {
m1.SendT = GoUtil.Now()
}
m := m1.Clone()
ToServer := GoUtil.GetServerIdByUid(m.To)
if ToServer != conf.Server.ServerID {
err := mergeCluster.SendServerMsg(m, ToServer)
if err != nil { // 区服不在线
G_GameLogicPtr.FriendMgrSend(m)
return err
}
return nil
}
G_GameLogicPtr.FriendMgrSend(m)
return nil
}
// 集群好友消息同步
func ClusterFriendSync(m *msg.Msg) error {
if v, ok := G_GameLogicPtr.FriendMgr.getData().ClusterMsg[m.To]; ok {
@ -264,24 +174,3 @@ func (f *FriendMgr) SendMsgToCenter(m *msg.Msg) (interface{}, error) {
func (f *FriendMgr) CallMsgToCenter(m *msg.Msg) (interface{}, error) {
return mergeCluster.CallServerMsg(m, conf.Server.CenterNode)
}
func FriendMgrCall(m *msg.Msg) interface{} {
ToServer := GoUtil.GetServerIdByUid(m.To)
if ToServer != conf.Server.ServerID {
r, err := mergeCluster.CallServerMsg(m, ToServer)
if err != nil { // 区服不在线
log.Debug("FriendMgrCall err %v", err)
return nil
}
return r
}
return G_GameLogicPtr.FriendMgrCall(m.Clone())
}
func SendMsgToCenter(m *msg.Msg) error {
return mergeCluster.SendServerMsg(m, conf.Server.CenterNode)
}
func CallMsgToCenter(m *msg.Msg) (interface{}, error) {
return mergeCluster.CallServerMsg(m, conf.Server.CenterNode)
}

View File

@ -2,9 +2,13 @@ package game
import (
"encoding/gob"
"server/game/mod/card"
"server/game/mod/friend"
"server/game/mod/item"
limitedTimeEvent "server/game/mod/limited_time_event"
"server/game/mod/msg"
proto "server/msg"
"sync"
)
type PlayerSimpleData struct {
@ -49,11 +53,21 @@ type VarUserData struct {
Upvote int
Chip int
Kiss int
mu sync.Mutex
}
type VarExpireData struct {
D interface{}
T int64
T int64 // 过期时间戳
U int64 // 最后更新时间
mu sync.Mutex
}
type CatnipPartner struct {
Uid int
Partner int
GameId int
EndTime int64
}
const (
@ -108,8 +122,13 @@ func init() {
gob.Register(&VarUserData{})
gob.Register(&ActivityInfo{})
gob.Register(&ChargeExtra{})
gob.Register(&GameResult{})
gob.Register(CatnipMsg{})
gob.Register(&CatnipLock{})
gob.Register(CRank{})
gob.Register(&proto.ResChampshipRank{})
gob.Register(&proto.ResChampshipPreRank{})
gob.Register(card.CardInfo{})
gob.Register(item.Item{})
gob.Register([]*item.Item{}) // 注册 []*item.Item 类型
gob.Register(friend.ReplyInfo{})
}

View File

@ -46,7 +46,7 @@ func ReqGmCommand_(player *Player, Command string) error {
// log.Error("ReqGmCommand panic: %v", err)
// }
// }()
if conf.Server.GameName != "pet_home" && conf.Server.GameName != "merge_pet_sdk" && conf.Server.GameName != "Merge_Pet_Local" {
if conf.Server.GameName != "pet_home" && conf.Server.GameName != "merge_pet_sdk" && conf.Server.GameName != "Merge_Pet_Local" && conf.Server.GameName != "pet_home_local" {
return fmt.Errorf("Player %d ReqGmCommand not support in game %s, command %s", player.M_DwUin, conf.Server.GameName, Command)
}
player.TeLog("gm", map[string]interface{}{
@ -393,13 +393,8 @@ func ReqGmCommand_(player *Player, Command string) error {
}
player.PushClientRes(CardMod.NotifyCard())
case "resetRankUser":
O := G_GameLogicPtr.RankMgr.getAllRank(RANK_TYPE_USER)
for _, v := range O {
Uid := strconv.Itoa(v.Uid)
TimeSort := fmt.Sprintf("0.%d", RANK_TIME_SORT-GoUtil.Now())
TimeSortF, _ := strconv.ParseFloat(TimeSort, 64)
db.RedisZAdd(RANK_USER, Uid, v.Score+TimeSortF)
}
db.RedisDelKey(RANK_USER)
db.RedisDelKey(fmt.Sprintf("%s_%s", RANK_COUNTRY_USER, conf.Server.CountryCode))
case "addFriendStar":
FriendTreasureMod := player.PlayMod.getFriendTreasureMod()
FriendTreasureMod.AddStar(200)
@ -513,6 +508,7 @@ func ReqGmCommand_(player *Player, Command string) error {
BaseMod.Uid = player.M_DwUin
BaseMod.NickName = player.PlayMod.getBaseMod().NickName
BaseMod.LoginTime = GoUtil.Now()
BaseMod.AddCode = fmt.Sprintf("MMM-%s-%s", "156", GoUtil.UniqueStringFromInt(int(BaseMod.Uid)))
// deep copy p1.PlayMod.mod_list to avoid sharing internal pointers
var modCopy PlayerModList
var buf bytes.Buffer

View File

@ -509,38 +509,6 @@ func (p *Player) handle(m *msg.Msg) error {
return nil
}
// 同步好友请求
func (p *Player) SyncFriendMsg() {
MsgList := G_GameLogicPtr.FriendMgrCall(&msg.Msg{Type: msg.HANDLE_TYPE_SYNC, From: int(p.M_DwUin)})
FriendMod := p.PlayMod.getFriendMod()
MsgId := FriendMod.GetSyncId()
if MsgList == nil {
return
}
ml := MsgList.([]*msg.Msg)
if len(ml) == 0 {
return
}
sort.Slice(ml, func(i, j int) bool {
return ml[i].Id < ml[j].Id
})
maxId := int64(0)
for _, v := range ml {
maxId = max(maxId, v.Id)
if v.H == 1 {
continue
}
if v.Id > 0 && v.Id <= MsgId {
continue
}
log.Debug("uid : %d, handle friend msg : %v", p.M_DwUin, v)
p.handle(v)
v.H = 1
}
FriendMod.SetSyncId(maxId)
p.PlayMod.save()
}
func SyncMailMsg(p *Player) {
ServerMailList := G_GameLogicPtr.MailMgr.Sync(int(p.M_DwUin), p.GetPlayerBaseMod().GetRegisterTime())
MailMod := p.PlayMod.getMailMod()
@ -736,7 +704,7 @@ func NotifyChampshipResult(Uid, Rank int) {
SendT: GoUtil.Now(),
Extra: []int{Rank, GoUtil.GetServerOpenDay()},
}
FriendMgrSend(Msg)
CenterPlayerMsgHandler(Msg)
}
}
@ -1302,3 +1270,18 @@ func (player *Player) IsWeeklyDiscount() bool {
LimitEventMod := player.PlayMod.getLimitedTimeEventMod()
return ChargeMod.IsWeeklyDiscountDay() || LimitEventMod.CheckExist(limitedTimeEvent.EVENT_TYPE_CAT_DAY_SALE)
}
func (p *Player) SetCatnipPartner(GameId, Partner int, EndTime int64) error {
_, err := SendMsgToCenterSync(&msg.Msg{
From: int(p.M_DwUin),
To: int(p.M_DwUin),
Type: msg.HANDLE_MOD_CATNIP_PARTNER,
Extra: CatnipPartner{
GameId: GameId,
Partner: Partner,
EndTime: EndTime,
Uid: int(p.M_DwUin),
},
})
return err
}

View File

@ -1,26 +1,315 @@
package game
import (
"context"
"encoding/gob"
"fmt"
"runtime/debug"
mergeCluster "server/cluster"
"server/conf"
"server/game/mod/msg"
GoUtil "server/game_util"
"server/pkg/github.com/name5566/leaf/log"
"sync"
"time"
)
// 中间件函数类型
type MessageMiddleware func(MessageHandlerFunc) MessageHandlerFunc
type MessageMgr struct {
*ServerMod
middlewares []MessageMiddleware
workerPool *WorkerPool
handler map[int]MessageHandlerFunc
}
type MessageData struct {
MessageList map[int64][]*msg.Msg
MessageList map[int64]*MessageList
PlayerList map[int64]int
mu sync.Mutex
}
type MessageList struct {
Messages []*msg.Msg
mu sync.Mutex
}
// Worker Pool 结构
type WorkerPool struct {
workers int
taskQueue chan *MessageTask
wg sync.WaitGroup
ctx context.Context
cancel context.CancelFunc
maxQueue int
}
// 消息任务
type MessageTask struct {
Msg *msg.Msg
Handler MessageHandlerFunc
Result chan *TaskResult
}
// 任务结果
type TaskResult struct {
Data interface{}
Error error
}
func (m *MessageMgr) MessageMgrInit() {
m.key = MESSAGE_MGR_KEY
m.data = &MessageData{}
m.data = &MessageData{
MessageList: make(map[int64]*MessageList),
PlayerList: make(map[int64]int),
}
gob.Register(msg.VarData{})
gob.Register(GameResult{})
// 注册处理函数
m.init()
m.handler = make(map[int]MessageHandlerFunc)
m.middlewares = []MessageMiddleware{}
// 初始化 Worker Pool (10个worker, 1000个队列大小)
m.workerPool = NewWorkerPool(10, 1000)
// 注册默认中间件
m.Use(RecoveryMiddleware())
m.Use(LoggingMiddleware())
m.Use(TimeoutMiddleware(5 * time.Second))
m.NodeRegister()
m.CenterRegister()
}
// 注册处理器
func (s *MessageMgr) RegisterHandler(HandlerType int, fun MessageHandlerFunc) {
s.handler[HandlerType] = fun
}
func (m *MessageMgr) NodeRegister() {
if conf.Server.ServerType == "node" {
m.RegisterHandler(msg.HANDLE_MOD_PLAYER_MSG, MessageHandlerFunc(PlayerMsgHandler))
m.RegisterHandler(msg.HANDLE_MOD_REPLY_PLAYER_MSG, MessageHandlerFunc(PlayerReplyMsgHandler))
m.RegisterHandler(msg.HANDLE_MOD_CLUSTER_SYNC, MessageHandlerFunc(ClusterSyncHandler))
}
}
func (m *MessageMgr) CenterRegister() {
if conf.Server.ServerType == "center" {
m.RegisterHandler(msg.HANDLE_MOD_PLAYER_LOGIN, MessageHandlerFunc(PlayerLoginHandler))
m.RegisterHandler(msg.HANDLE_MDO_PLAYER_LOGOUT, MessageHandlerFunc(PlayerLogoutHandler))
m.RegisterHandler(msg.HANDLE_MOD_PLAYER_MSG, MessageHandlerFunc(CenterPlayerMsgHandler))
m.RegisterHandler(msg.HANDLE_MOD_COMSUME_MSG, MessageHandlerFunc(ComsumerMsgHandler))
m.RegisterHandler(msg.HANDLE_MOD_VAR_SET, MessageHandlerFunc(SetVarDataHandler))
m.RegisterHandler(msg.HANDLE_MOD_VAR_GET, MessageHandlerFunc(GetVarDataHandler))
m.RegisterHandler(msg.HANDLE_MOD_USER_VAR_SET, MessageHandlerFunc(SetUserVarDataHandler))
m.RegisterHandler(msg.HANDLE_MOD_USER_VAR_GET, MessageHandlerFunc(GetUserVarDataHandler))
m.RegisterHandler(msg.HANDLE_MOD_CATNIP_PARTNER, MessageHandlerFunc(CatnipPartnerHandler))
m.RegisterHandler(msg.HANDLE_MDO_CHAMPSHIP_INRANK, MessageHandlerFunc(ChampshipInRankHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_RANK_INFO, MessageHandlerFunc(ChampshipRankInfoHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_RANK_LIST, MessageHandlerFunc(ChampshipRankListHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_PRE_RANK, MessageHandlerFunc(ChampshipRankPreHandler))
}
}
func getMessageData() *MessageData {
return G_GameLogicPtr.MessageMgr.data.(*MessageData)
}
// ----------------------------------- 处理函数实现 ---------------------------
func ChampshipRankPreHandler(data *msg.Msg) (interface{}, error) {
PlayerId := data.From
PreRankMsg := G_GameLogicPtr.ChampshipMgr.GetPreRankMsg(PlayerId)
ReplyPlayerMsgASync(data, PreRankMsg)
return nil, nil
}
func ChampshipRankListHandler(data *msg.Msg) (interface{}, error) {
PlayerId := data.From
RankMsg := G_GameLogicPtr.ChampshipMgr.GetRankMsg(PlayerId)
ReplyPlayerMsgASync(data, RankMsg)
return nil, nil
}
func ChampshipRankInfoHandler(data *msg.Msg) (interface{}, error) {
PlayerId := data.From
MyRank := G_GameLogicPtr.ChampshipMgr.getMyRank(PlayerId)
MyPreRank := G_GameLogicPtr.ChampshipMgr.getLastMyRank(PlayerId)
ReplyPlayerMsgASync(data, []int{MyRank, MyPreRank})
return nil, nil
}
func NotifyAllPlayerMsg(m *msg.Msg) {
messageMgrData := getMessageData()
for PlayerId, node := range messageMgrData.PlayerList {
m.To = int(PlayerId)
go SendMsgToNodeAsync(m, node)
}
}
func ChampshipInRankHandler(data *msg.Msg) (interface{}, error) {
G_GameLogicPtr.ChampshipMgr.inRank(data)
return nil, nil
}
func CatnipPartnerHandler(data *msg.Msg) (interface{}, error) {
m, ok := data.Extra.(*CatnipPartner)
if !ok {
return nil, fmt.Errorf("invalid catnip partner data")
}
return G_GameLogicPtr.VarMgr.HandleCatnipPartner(m.Uid, m.Partner, m.GameId, m.EndTime)
}
func ReplyPlayerMsgASync(m *msg.Msg, reply interface{}) (interface{}, error) {
clone := m.Reply(reply)
messageMgrData := getMessageData()
if node, ok := messageMgrData.PlayerList[int64(m.From)]; ok {
go SendMsgToNodeAsync(clone, node)
}
return nil, nil
}
// 节点连接时,同步消息
func ClusterSyncHandler(data *msg.Msg) (interface{}, error) {
// 遍历所有玩家,发送登录消息
G_GameLogicPtr.M_Players.Range(func(k, v interface{}) bool {
SendMsgToCenterAsync(&msg.Msg{
From: int(v.(*Player).M_DwUin),
HandleType: msg.HANDLE_MOD_PLAYER_LOGIN,
Extra: conf.Server.ServerID,
})
return true
})
// 发送暂存区消息
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock()
TempMessageList := messageMgrData.MessageList
messageMgrData.MessageList = make(map[int64]*MessageList)
for PlayerId, Message := range TempMessageList {
for _, msgItem := range Message.Messages {
go SendMsgToNodeAsync(msgItem, messageMgrData.PlayerList[PlayerId])
}
}
return nil, nil
}
func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
// 关闭 Worker Pool
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock()
messageMgrData.PlayerList[int64(data.From)] = data.Extra.(int)
if _, ok := messageMgrData.MessageList[int64(data.From)]; !ok {
messageMgrData.MessageList[int64(data.From)] = &MessageList{
Messages: []*msg.Msg{},
}
}
log.Debug("[Middleware] Player login success player id: %v, node: %v", data.From, data.Extra.(int))
node := data.Extra.(int)
messageMgrData.PlayerList[int64(data.From)] = node
// 发送离线消息
messages := messageMgrData.MessageList[int64(data.From)]
messages.mu.Lock()
defer messages.mu.Unlock()
for _, message := range messages.Messages {
go sendMessageAsync(message, node)
}
return nil, nil
}
func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) {
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock()
delete(messageMgrData.PlayerList, int64(data.From))
log.Debug("[Middleware] Player logout success player id: %v", data.From)
return nil, nil
}
func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) {
messageMgrData := getMessageData()
Message, ok := messageMgrData.MessageList[int64(data.To)]
if !ok {
return nil, nil
}
Message.mu.Lock()
defer Message.mu.Unlock()
for i, msgItem := range Message.Messages {
if msgItem.UniKey == data.UniKey {
// 删除消息
Message.Messages = append(Message.Messages[:i], Message.Messages[i+1:]...)
log.Debug("[Middleware] Comsume message success type: %d, player id: %v", msgItem.Type, msgItem.From)
break
}
}
return nil, nil
}
func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) {
PlayerId := int64(data.To)
messageMgrData := getMessageData()
// 遍历消息列表,发送消息给在线玩家
messages, ok := messageMgrData.MessageList[int64(PlayerId)]
if !ok {
messageMgrData.mu.Lock()
messages = &MessageList{
Messages: []*msg.Msg{},
}
messageMgrData.MessageList[int64(PlayerId)] = messages
messageMgrData.mu.Unlock()
}
messages.mu.Lock()
defer messages.mu.Unlock()
messages.Messages = append(messages.Messages, data)
if node, ok := messageMgrData.PlayerList[int64(PlayerId)]; ok {
for _, message := range messages.Messages {
go SendMsgToNodeAsync(message, node)
}
}
return nil, nil
}
func PlayerMsgHandler(data *msg.Msg) (interface{}, error) {
p := G_GameLogicPtr.GetPlayer(int64(data.To))
// 不在线 不处理
if p == nil || p.stop {
return nil, nil
}
p.lock.Lock()
defer p.lock.Unlock()
p.Send(data.Clone())
// 处理完后发送消费消息
if data.HandleType == msg.HANDLE_MOD_PLAYER_MSG {
data.HandleType = msg.HANDLE_MOD_COMSUME_MSG
go SendMsgToCenterAsync(data)
}
return nil, nil
}
func PlayerReplyMsgHandler(data *msg.Msg) (interface{}, error) {
// 先处理同步回调
if data.UniKey != "" {
if chanel, ok := mergeCluster.CallbackChan[data.UniKey]; ok {
log.Debug("reply message ")
chanel <- data
}
}
return nil, nil
}
// 添加中间件
func (m *MessageMgr) Use(middleware MessageMiddleware) {
m.middlewares = append(m.middlewares, middleware)
}
// 应用所有中间件到处理函数
func (m *MessageMgr) applyMiddlewares(handler MessageHandlerFunc) MessageHandlerFunc {
// 从后往前应用中间件
for i := len(m.middlewares) - 1; i >= 0; i-- {
handler = m.middlewares[i](handler)
}
return handler
}
type MessageHandlerFunc func(message *msg.Msg) (interface{}, error)
@ -31,21 +320,311 @@ func (m *MessageMgr) RegisterMessageHandler(hType int, handler MessageHandlerFun
func (m *MessageMgr) Handle(msg *msg.Msg) (interface{}, error) {
if fun, ok := m.handler[msg.Type]; ok {
return fun.(MessageHandlerFunc)(msg)
return fun(msg)
}
log.Error("server mod key:%s handle not exist handle type:%d", m.key, msg.Type)
return nil, fmt.Errorf("server mod handler err")
}
func SendMessage(m1 *msg.Msg) error {
if m1.SendT == 0 {
m1.SendT = GoUtil.Now()
// 异步处理消息 (多线程版本)
func (m *MessageMgr) MessageHandleAsync(message *msg.Msg) error {
if fun, ok := m.handler[message.HandleType]; ok {
// 应用中间件
handlerWithMiddleware := m.applyMiddlewares(fun)
// 创建任务
task := &MessageTask{
Msg: message,
Handler: handlerWithMiddleware,
Result: make(chan *TaskResult, 1),
}
m := m1.Clone()
err := mergeCluster.SendServerMsg(m, 1)
if err != nil { // 区服不在线
G_GameLogicPtr.FriendMgrSend(m)
// 提交到 Worker Pool
if err := m.workerPool.Submit(task); err != nil {
log.Error("Failed to submit message task: %v", err)
return err
}
// 可以选择等待结果或直接返回
go func() {
result := <-task.Result
if result.Error != nil {
log.Error("Message handle error: %v", result.Error)
}
}()
return nil
}
log.Error("server mod key:%s handle not exist handle type:%d", m.key, message.Type)
return fmt.Errorf("server mod handler err")
}
// 兼容旧版本的函数
func MessageHandle(m *msg.Msg) error {
log.Debug("RecvMessage m %v", m)
// 这里可以调用 MessageMgr 的处理方法
G_GameLogicPtr.MessageMgr.MessageHandleAsync(m)
return nil
}
// ==================== Worker Pool 实现 ====================
// 创建 Worker Pool
func NewWorkerPool(workers, maxQueue int) *WorkerPool {
ctx, cancel := context.WithCancel(context.Background())
pool := &WorkerPool{
workers: workers,
taskQueue: make(chan *MessageTask, maxQueue),
ctx: ctx,
cancel: cancel,
maxQueue: maxQueue,
}
pool.start()
return pool
}
// 启动 Worker Pool
func (p *WorkerPool) start() {
for i := 0; i < p.workers; i++ {
p.wg.Add(1)
go p.worker(i)
}
}
// Worker 工作函数
func (p *WorkerPool) worker(id int) {
defer p.wg.Done()
log.Debug("Worker %d started", id)
for {
select {
case <-p.ctx.Done():
log.Debug("Worker %d stopped", id)
return
case task, ok := <-p.taskQueue:
if !ok {
log.Debug("Worker %d: task queue closed", id)
return
}
// 执行任务
result, err := task.Handler(task.Msg)
// 发送结果
task.Result <- &TaskResult{
Data: result,
Error: err,
}
close(task.Result)
}
}
}
// 提交任务
func (p *WorkerPool) Submit(task *MessageTask) error {
select {
case <-p.ctx.Done():
return fmt.Errorf("worker pool is closed")
case p.taskQueue <- task:
return nil
default:
return fmt.Errorf("task queue is full")
}
}
// 关闭 Worker Pool
func (p *WorkerPool) Shutdown() {
log.Debug("Shutting down worker pool...")
p.cancel()
close(p.taskQueue)
p.wg.Wait()
log.Debug("Worker pool shut down complete")
}
// ==================== 中间件实现 ====================
// 日志中间件
func LoggingMiddleware() MessageMiddleware {
return func(next MessageHandlerFunc) MessageHandlerFunc {
return func(message *msg.Msg) (interface{}, error) {
start := time.Now()
log.Debug("[Middleware] Processing message type: %d, time: %v", message.Type, start)
result, err := next(message)
duration := time.Since(start)
if err != nil {
log.Error("[Middleware] Message type: %d failed, duration: %v, error: %v", message.Type, duration, err)
} else {
log.Debug("[Middleware] Message type: %d success, duration: %v", message.Type, duration)
}
return result, err
}
}
}
// 恢复 Panic 中间件
func RecoveryMiddleware() MessageMiddleware {
return func(next MessageHandlerFunc) MessageHandlerFunc {
return func(message *msg.Msg) (result interface{}, err error) {
defer func() {
if r := recover(); r != nil {
log.Error("[Middleware] Panic recovered: %v\nStack: %s", r, debug.Stack())
err = fmt.Errorf("panic recovered: %v", r)
}
}()
return next(message)
}
}
}
// 超时中间件
func TimeoutMiddleware(timeout time.Duration) MessageMiddleware {
return func(next MessageHandlerFunc) MessageHandlerFunc {
return func(message *msg.Msg) (interface{}, error) {
resultChan := make(chan *TaskResult, 1)
go func() {
result, err := next(message)
resultChan <- &TaskResult{Data: result, Error: err}
}()
select {
case result := <-resultChan:
return result.Data, result.Error
case <-time.After(timeout):
log.Error("[Middleware] Message type: %d timeout after %v", message.Type, timeout)
return nil, fmt.Errorf("message handler timeout")
}
}
}
}
// 重试中间件
func RetryMiddleware(maxRetries int) MessageMiddleware {
return func(next MessageHandlerFunc) MessageHandlerFunc {
return func(message *msg.Msg) (interface{}, error) {
var result interface{}
var err error
for i := 0; i <= maxRetries; i++ {
result, err = next(message)
if err == nil {
return result, nil
}
if i < maxRetries {
log.Debug("[Middleware] Retry %d/%d for message type: %d, error: %v", i+1, maxRetries, message.Type, err)
time.Sleep(time.Millisecond * 100 * time.Duration(i+1))
}
}
return result, fmt.Errorf("failed after %d retries: %w", maxRetries, err)
}
}
}
// 验证中间件
func ValidationMiddleware() MessageMiddleware {
return func(next MessageHandlerFunc) MessageHandlerFunc {
return func(message *msg.Msg) (interface{}, error) {
// 添加消息验证逻辑
if message == nil {
return nil, fmt.Errorf("message is nil")
}
if message.Type <= 0 {
return nil, fmt.Errorf("invalid message type: %d", message.Type)
}
return next(message)
}
}
}
// ----------------------------------- 发送消息相关函数 ---------------------------
func SendMsgToCenterAsync(m *msg.Msg) {
go sendMessageAsync(m, conf.Server.CenterNode)
}
func SendMsgToCenterSync(m *msg.Msg) (*msg.Msg, error) {
return sendMessageSync(m, conf.Server.CenterNode)
}
func SendMsgToNodeAsync(m *msg.Msg, node int) {
go sendMessageAsync(m, node)
}
func SendMsgToNodeSync(m *msg.Msg, node int) (*msg.Msg, error) {
return sendMessageSync(m, node)
}
func SendPlayerMsgAsync(m *msg.Msg) error {
if m.SendT == 0 {
m.SendT = GoUtil.Now()
}
clone := m.Clone()
clone.HandleType = msg.HANDLE_MOD_PLAYER_MSG
SendMsgToCenterAsync(clone)
return nil
}
func SendPlayerMsgSync(m *msg.Msg) (interface{}, error) {
clone := m.Clone()
clone.HandleType = msg.HANDLE_MOD_PLAYER_MSG
return SendMsgToCenterSync(clone)
}
func FriendMgrSend(m1 *msg.Msg) error {
SendPlayerMsgAsync(m1)
return nil
}
// 异步发送消息到指定节点 节点不在线则保存消息
func sendMessageAsync(m *msg.Msg, node int) error {
err := mergeCluster.SendServerMsg(m, node)
if err != nil {
saveMessage(m)
return err
}
return nil
}
// 同步消息到指定节点 节点不在线则保存消息
func sendMessageSync(m *msg.Msg, node int) (*msg.Msg, error) {
msg, err := mergeCluster.CallServerMsg(m, node)
if err != nil && conf.Server.ServerType == "center" {
saveMessage(m)
return nil, err
}
return msg, nil
}
// 保存消息到本地
func saveMessage(m *msg.Msg) error {
data := getMessageData()
data.mu.Lock()
defer data.mu.Unlock()
if _, ok := data.MessageList[int64(m.To)]; !ok {
data.MessageList[int64(m.To)] = &MessageList{
Messages: []*msg.Msg{},
}
}
data.MessageList[int64(m.To)].mu.Lock()
defer data.MessageList[int64(m.To)].mu.Unlock()
data.MessageList[int64(m.To)].Messages = append(data.MessageList[int64(m.To)].Messages, m)
return nil
}
func GetUserData(PlayerId int64, Key string) (*msg.Msg, error) {
return SendMsgToCenterSync(&msg.Msg{
From: int(PlayerId),
HandleType: msg.HANDLE_MOD_USER_VAR_GET,
Extra: msg.VarData{Key: Key},
})
}
// func GetServerData(Key string) (*msg.Msg, error) {
// return SendMsgToCenterSync(&msg.Msg{
// HandleType: msg.HANDLE_MOD_VAR_GET,
// Extra: msg.VarData{Key: Key},
// })
// }

View File

@ -219,6 +219,11 @@ func (f *FriendMod) SetNpc(id int) error {
if !friendCfg.IsNpcFriend(id) {
return fmt.Errorf("not npc friend")
}
for _, v := range f.Npc {
if v == id {
return fmt.Errorf("npc already exist")
}
}
f.Npc = append(f.Npc, id)
return nil
}

View File

@ -16,9 +16,40 @@ type Msg struct {
HandleType int //处理类型
}
type VarData struct {
Key string
Value interface{}
SetType int // 操作类型 0 设置 1 增加 2 减少 3 覆盖
}
const (
VAR_OP_ADD = 1
VAR_OP_SUB = 2
VAR_OP_SET = 3
)
var MSG_ZERO_UPDATE = &Msg{Type: SERVER_ZERO_UPDATE}
var MSG_NOON_UPDATE = &Msg{Type: SERVER_NOON_UPDATE}
const (
HANDLE_MOD_PLAYER_MSG = 20001 // 玩家消息
HANDLE_MOD_CLUSTER_MSG = 20002 // 集群消息
HANDLE_MOD_PLAYER_LOGIN = 20003 // 玩家登录消息
HANDLE_MOD_COMSUME_MSG = 20004 // 消费消息
HANDLE_MOD_CLUSTER_SYNC = 20005 // 集群同步消息
HANDLE_MDO_PLAYER_LOGOUT = 20006 // 玩家登出消息
HANDLE_MOD_VAR_GET = 20007 // 获取变量
HANDLE_MOD_VAR_SET = 20008 // 设置变量
HANDLE_MOD_CATNIP_PARTNER = 20009 // 猫薄荷伙伴
HANDLE_MOD_USER_VAR_GET = 20010 // 获取玩家变量
HANDLE_MOD_USER_VAR_SET = 20011 // 设置玩家变量
HANDLE_MOD_REPLY_PLAYER_MSG = 20012 // 回复玩家消息
HANDLE_MDO_CHAMPSHIP_INRANK = 20013 // 锦标赛入榜
HANDLE_MOD_CHAMPSHIP_RANK_INFO = 20014 // 锦标赛排名信息
HANDLE_MOD_CHAMPSHIP_RANK_LIST = 20015 // 锦标赛排行榜
HANDLE_MOD_CHAMPSHIP_PRE_RANK = 20016 // 锦标赛上期排名
)
const (
//好友操作
HANDLE_TYPE_APPLY = iota //申请好友
@ -114,6 +145,8 @@ const (
HANDLE_TYPE_SET_CATNIP_PARTNER // 设置猫薄荷伙伴
HANDLE_TYPE_CATNIP_SEND_EMOJI // 发送猫薄荷表情
HANDLE_TYPE_CHAMPSHIP_MY_RANK // 锦标赛我的排名
HANDLE_TYPE_LOGIN // 玩家登录处理
)
const (
@ -141,6 +174,21 @@ func (m *Msg) Clone() *Msg {
}
}
func (m *Msg) Reply(data interface{}) *Msg {
return &Msg{
Type: m.Type,
To: m.From,
Item: m.Item,
SendT: m.SendT,
End: m.End,
Extra: data,
Id: m.Id,
H: m.H,
UniKey: m.UniKey,
HandleType: HANDLE_MOD_REPLY_PLAYER_MSG,
}
}
func Handle(fun func(Msg) error, m Msg) error {
return fun(m)
}

View File

@ -5,6 +5,7 @@ import (
playroomCfg "server/conf/playroom"
"server/game/mod/item"
limitedTimeEvent "server/game/mod/limited_time_event"
"server/game/mod/msg"
GoUtil "server/game_util"
proto "server/msg"
)
@ -113,7 +114,6 @@ func (p *Player) PlayroomBackData() {
ItemId: int32(k),
})
}
data := G_GameLogicPtr.GetUserData(int(p.M_DwUin))
r.Dress = Dress
r.DressSet = GoUtil.MapIntToInt32(PlayroomMod.GetDressSet())
@ -156,7 +156,7 @@ func (p *Player) PlayroomBackData() {
r.Unlock = PlayroomMod.GetUnlockIds()
r.DailyTaskReward = GoUtil.IntToInt32(PlayroomMod.DailyTaskReward)
r.DailyTask = PlayroomMod.BackDataTask()
r.Kiss = int32(data.Kiss)
r.Kiss = int32(p.GetPlayroomKiss())
r.Revenge = PlayroomMod.RevengeUid
r.InteractNum = int32(PlayroomMod.InteractNum)
r.AdItem = AdWatch
@ -195,18 +195,16 @@ func (p *Player) PlayroomVisit(Uid int) {
r.Upvote = GoUtil.InArray(Uid, PlayroomMod.UpvoteList)
r.Items = Items
r.Status = int32(PlayroomMod.GameStatus)
data := G_GameLogicPtr.GetUserData(Uid)
r.UpvoteCount = int32(data.Upvote)
r.Chip = int32(data.Chip)
r.Kiss = int32(data.Kiss)
r.UpvoteCount = int32(p.GetPlayroomUpvote())
r.Chip = int32(p.GetPlayroomChip())
r.Kiss = int32(p.GetPlayroomKiss())
r.DressSet = GoUtil.MapIntToInt32(PlayerData.DressSet)
p.PushClientRes(r)
}
func (p *Player) NotifyPlayroomKiss() {
data := G_GameLogicPtr.GetUserData(int(p.M_DwUin))
m := &proto.NotifyPlayroomKiss{
Kiss: int32(data.Kiss),
Kiss: int32(p.GetPlayroomKiss()),
}
p.PushClientRes(m)
}
@ -297,8 +295,16 @@ func (p *Player) ChargeBackData() {
func (p *Player) BackChampship() {
ChampshipMod := p.PlayMod.getChampshipMod()
MyRank := G_GameLogicPtr.ChampshipMgr.getMyRank(int(p.M_DwUin))
MyPreRank := G_GameLogicPtr.ChampshipMgr.getLastMyRank(int(p.M_DwUin))
MyRank := 0
MyPreRank := 0
res, _ := SendMsgToCenterSync(&msg.Msg{
From: int(p.M_DwUin),
HandleType: msg.HANDLE_MOD_CHAMPSHIP_RANK_INFO,
})
if res != nil {
MyRank = res.Extra.([]int)[0]
MyPreRank = res.Extra.([]int)[1]
}
p.PushClientRes(ChampshipMod.BackData(MyRank, MyPreRank))
}

View File

@ -43,7 +43,7 @@ func (p *PlayerBaseData) BackUp() msg.ResPlayerBaseInfo {
Guild: p.Data.Guild,
PackUnlockCount: p.Data.PackUnlockCount,
LastPlayTime: p.Data.LastPlayTime,
EnergyBuyCount: p.Data.EnergyBuyCount,
Ban: p.Data.Ban,
LoginTime: p.Data.LoginTime,
UserName: p.Data.UserName,
LogoutTime: p.Data.LogoutTime,
@ -70,7 +70,7 @@ func (p *PlayerBaseData) Recover(old *PlayerBaseData) *PlayerBaseData {
Guild: p.Data.Guild,
PackUnlockCount: p.Data.PackUnlockCount,
LastPlayTime: p.Data.LastPlayTime,
EnergyBuyCount: p.Data.EnergyBuyCount,
Ban: p.Data.Ban,
LoginTime: p.Data.LoginTime,
UserName: p.Data.UserName,
LogoutTime: p.Data.LogoutTime,
@ -104,7 +104,7 @@ func (p *PlayerBaseData) LoadDataFromDB(UserName interface{}) bool {
p.Data.Guild = sqlStruck.Guild
p.Data.PackUnlockCount = sqlStruck.PackUnlockCount
p.Data.LastPlayTime = sqlStruck.LastPlayTime
p.Data.EnergyBuyCount = sqlStruck.EnergyBuyCount
p.Data.Ban = sqlStruck.Ban
p.Data.UserName = sqlStruck.UserName
p.Data.LogoutTime = sqlStruck.LogoutTime
p.Data.Todayolinetime = sqlStruck.Todayolinetime
@ -132,7 +132,7 @@ func (p *PlayerBaseData) SaveDataFromDB(Key interface{}) bool {
sqlStruck.Guild = p.Data.Guild
sqlStruck.PackUnlockCount = p.Data.PackUnlockCount
sqlStruck.LastPlayTime = p.Data.LastPlayTime
sqlStruck.EnergyBuyCount = p.Data.EnergyBuyCount
sqlStruck.Ban = int64(p.Data.Ban)
sqlStruck.LoginTime = int32(BaseMod.LoginTime)
sqlStruck.UserName = p.Data.UserName
sqlStruck.LogoutTime = int32(BaseMod.LogoutTime)
@ -163,22 +163,6 @@ func (p *PlayerBaseData) GetMaxEnergy() int {
}
// 更新游戏道具
func (p *PlayerBaseData) UpdateBaseItemInfo(update *msg.UpdateBaseItemInfo) {
for k, v := range update.MUpdateItem {
switch k {
case 4:
p.Data.EnergyBuyCount = v
case 8:
p.Data.Guild = v
case 9:
p.Data.PackUnlockCount = v
case 10:
p.Data.EmitOrderCnt = v
case 11:
p.Data.LastPlayTime = v
}
}
}
func (p *PlayerBaseData) ReqRemoveAd(player *Player, buf []byte) {
req := &msg.ReqRemoveAd{}
@ -654,7 +638,7 @@ func (p *PlayerBaseData) GetDataByUid(Uid interface{}) bool {
p.Data.Guild = sqlStruck.Guild
p.Data.PackUnlockCount = sqlStruck.PackUnlockCount
p.Data.LastPlayTime = sqlStruck.LastPlayTime
p.Data.EnergyBuyCount = sqlStruck.EnergyBuyCount
p.Data.Ban = sqlStruck.Ban
p.Data.LoginTime = sqlStruck.LoginTime
p.Data.UserName = sqlStruck.UserName
p.Data.LogoutTime = sqlStruck.LogoutTime

View File

@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"math"
"server/conf"
activityCfg "server/conf/activity"
cardCfg "server/conf/card"
chargeCfg "server/conf/charge"
@ -101,12 +102,13 @@ func (p *Player) CallEvent(Duration time.Duration, F func(), Label string) {
}
// 异步请求
func (p *Player) Send(m *MsgMod.Msg) {
func (p *Player) Send(m *MsgMod.Msg) error {
if m == nil {
return
return nil
}
p.wg.Add(1)
p.msgChan <- m
return nil
}
func (p *Player) Call(m MsgMod.Msg) {
@ -252,7 +254,6 @@ func (p *Player) InitPlayer(UserName string) error {
p.NoonUpdate(nil)
p.Login()
p.OrderShip()
p.SyncFriendMsg()
p.UpdateUserInfo()
// fix bug
ChargeMod := p.PlayMod.getChargeMod()
@ -451,11 +452,16 @@ func (p *Player) ClearData() {
log.Debug("ClearData BeginTx failed:", err)
return
}
Uid := int(p.M_DwUin)
p.PlayerBaseMod.ClearData()
p.PlayMod.ClearData(p)
tx.Commit()
p.Stop()
G_GameLogicPtr.DelPlayer(p)
SendMsgToCenterAsync(&MsgMod.Msg{
From: Uid,
HandleType: MsgMod.HANDLE_MDO_PLAYER_LOGOUT,
})
}
func (p *Player) AutoSaveData() {
@ -863,6 +869,11 @@ func (p *Player) HandleItem(itemList []*item.Item, Label string) error {
// 登录返回数据
func (p *Player) LoginBackData() {
SendMsgToCenterAsync(&MsgMod.Msg{
From: int(p.M_DwUin),
HandleType: MsgMod.HANDLE_MOD_PLAYER_LOGIN,
Extra: conf.Server.ServerID,
})
p.PushClientRes(p.PlayMod.mod_list.Base.BackData())
p.PushClientRes(p.PlayMod.mod_list.Handbook.BackData())
p.PushClientRes(p.PlayMod.mod_list.Base.BackData())
@ -975,7 +986,7 @@ func (p *Player) UpdateUserInfo() {
//TODO 存储到redis 在新版本中将优化成gob进行压缩
value, _ := json.Marshal(simple)
IdStr := strconv.Itoa(int(p.M_DwUin))
IdStr := GoUtil.String(p.M_DwUin)
go db.RedisSetKeyBytes(IdStr, value, 0)
}
@ -1013,8 +1024,9 @@ func (p *Player) HandleInChampshipRank() {
H: ChampshipMod.GetH(),
N: ChampshipMod.GetN(),
},
HandleType: MsgMod.HANDLE_MDO_CHAMPSHIP_INRANK,
}
G_GameLogicPtr.ChampshipMgrSend(m)
SendMsgToCenterAsync(m)
}
func (p *Player) AddLog(Uid int, Type int, Param string, Time int64) {

View File

@ -119,17 +119,6 @@ func ReqRemoveAdFunc(player *Player, buf []byte) error {
return nil
}
// 更新玩家物品
func UpdateBaseItemInfofunction(player *Player, buf []byte) error {
detail := &msg.UpdateBaseItemInfo{}
err := proto.Unmarshal(buf, detail)
if err != nil {
return err
}
player.PlayerBaseMod.UpdateBaseItemInfo(detail)
return nil
}
// 请求玩家棋盘信息
func ReqPlayerChessDataFunc(player *Player, buf []byte) error {
detail := &msg.ReqPlayerChessData{}
@ -1785,15 +1774,14 @@ func ReqLimitSenceReward(player *Player, buf []byte) error {
}
func ReqGetGoldCard(player *Player, buf []byte) error {
data := G_GameLogicPtr.VarMgr.GetVar(VAR_GOLD_CARD)
if data == nil {
gold := player.GetGoldCard()
if gold == nil {
player.SendErrClienRes(&msg.ResGetGoldCard{
Four: 0,
Five: 0,
})
return fmt.Errorf("not exist")
}
gold := data.(*VarGoldCard)
player.PushClientRes(&msg.ResGetGoldCard{
Four: int32(gold.Four),
Five: int32(gold.Five),
@ -1870,13 +1858,13 @@ func ReqApplyFriend(player *Player, buf []byte) error {
})
return fmt.Errorf("already friend")
}
if FriendMod.AddSendApply(Uid) {
player.SendErrClienRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_FAIL,
Msg: "already apply",
})
return fmt.Errorf("already apply")
}
// if FriendMod.AddSendApply(Uid) {
// player.SendErrClienRes(&msg.ResApplyFriend{
// Code: msg.RES_CODE_FAIL,
// Msg: "already apply",
// })
// return fmt.Errorf("already apply")
// }
if req.Type == 1 {
Items, err := FriendMod.GetSponsorReward()
if err != nil {
@ -2576,7 +2564,18 @@ func ReqChampshipRank(player *Player, buf []byte) error {
if err != nil {
return err
}
m := G_GameLogicPtr.ChampshipMgr.GetRankMsg(int(player.M_DwUin))
res, err := SendMsgToCenterSync(&MsqMod.Msg{
From: int(player.M_DwUin),
HandleType: MsqMod.HANDLE_MOD_CHAMPSHIP_RANK_LIST,
})
if err != nil {
return err
}
if res == nil {
player.PushClientRes(&msg.ResChampshipRank{})
return nil
}
m := res.Extra.(*msg.ResChampshipRank)
player.PushClientRes(m)
return nil
}
@ -2587,7 +2586,18 @@ func ReqChampshipPreRank(player *Player, buf []byte) error {
if err != nil {
return err
}
m := G_GameLogicPtr.ChampshipMgr.GetPreRankMsg(int(player.M_DwUin))
res, err := SendMsgToCenterSync(&MsqMod.Msg{
From: int(player.M_DwUin),
HandleType: MsqMod.HANDLE_MOD_CHAMPSHIP_PRE_RANK,
})
if err != nil {
return err
}
if res == nil {
player.PushClientRes(&msg.ResChampshipPreRank{})
return nil
}
m := res.Extra.(*msg.ResChampshipPreRank)
player.PushClientRes(m)
return nil
}
@ -3279,7 +3289,7 @@ func ReqSelfInvited(player *Player, buf []byte) error {
if err != nil {
return err
}
G_GameLogicPtr.FriendMgrSend(&MsqMod.Msg{
FriendMgrSend(&MsqMod.Msg{
Type: MsqMod.HANDLE_TYPE_INVITE_FRIEND,
From: int(player.M_DwUin),
To: int(req.InviterId),
@ -3346,7 +3356,7 @@ func ReqAutoAddInviteFriend(player *Player, buf []byte) error {
player.PushClientRes(&msg.ResAutoAddInviteFriend{
ResultCode: 1,
})
G_GameLogicPtr.FriendMgrSend(&MsqMod.Msg{
FriendMgrSend(&MsqMod.Msg{
From: int(player.M_DwUin),
To: Uid,
Type: MsqMod.HANDLE_TYPE_INVITE_ADD_FRIEND,
@ -3390,7 +3400,7 @@ func ReqAutoAddInviteFriend2(player *Player, buf []byte) error {
player.PushClientRes(&msg.ResAutoAddInviteFriend2{
ResultCode: 1,
})
G_GameLogicPtr.FriendMgrSend(&MsqMod.Msg{
FriendMgrSend(&MsqMod.Msg{
From: int(player.M_DwUin),
To: Uid,
Type: MsqMod.HANDLE_TYPE_INVITE_ADD_FRIEND,
@ -3790,7 +3800,7 @@ func ReqPlayroomInteract(player *Player, buf []byte) error {
return err
}
if GoUtil.InArray(int(req.Id), playroomCfg.GetInteractIdBath()) {
G_GameLogicPtr.SetUserData(int(req.Id), VAR_OP_KISS, 0)
player.SetPlayroomKiss(0)
}
PExp := playroomCfg.GetInteractPExp(int(req.Id))
_, err = player.GetPlayerBaseMod().AddExp(player, 0, PExp)
@ -3804,7 +3814,6 @@ func ReqPlayroomInteract(player *Player, buf []byte) error {
PlayroomMod.AddInteractNum(BaseMod.GetLevel())
player.QuestTrigger(&quest.Trigger{Label: quest.TRIGGER_LABEL_INTERACT, A: []interface{}{int(req.Id)}})
player.PlayMod.save()
G_GameLogicPtr.SetUserData(int(player.M_DwUin), VAR_OP_KISS, 0)
player.LimitedTimePlayroomTrigger_(PType)
player.NotifyPlayroomKiss()
player.TeLog("playroom_interact", map[string]interface{}{
@ -3868,7 +3877,7 @@ func ReqPlayroomGame(player *Player, buf []byte) error {
})
return err
}
G_GameLogicPtr.FriendMgrSend(&MsqMod.Msg{
FriendMgrSend(&MsqMod.Msg{
From: int(player.M_DwUin),
To: Target,
Type: MsqMod.HANDLE_TYPE_PLAYROOM_GAME,
@ -3928,7 +3937,7 @@ func ReqPlayroomSelectReward(player *Player, buf []byte) error {
})
return fmt.Errorf("no game or target")
}
G_GameLogicPtr.FriendMgrSend(&MsqMod.Msg{
FriendMgrSend(&MsqMod.Msg{
From: int(player.M_DwUin),
To: Target,
Type: MsqMod.HANDLE_TYPE_PLAYROOM_LOSE,
@ -3943,7 +3952,7 @@ func ReqPlayroomSelectReward(player *Player, buf []byte) error {
if LimitedTimeEventMod.CheckExist(limitedTimeEvent.EVENT_TYPE_PET_THIEF) {
player.GetPetThiefReward(Target)
}
G_GameLogicPtr.SetUserData(Target, VAR_OP_CHIP, 1)
player.AddPlayroomChip(int(req.Id))
player.TeLog("finish_mini_game", map[string]interface{}{
"mini_game_type": PlayroomMod.GetGameId(),
"is_chip": true,
@ -4083,8 +4092,9 @@ func ReqPlayroomChip(player *Player, buf []byte) error {
player.TeLog("remove_chip", map[string]interface{}{
"remove_chip_number": ChipNum,
})
G_GameLogicPtr.SetUserData(int(player.M_DwUin), VAR_OP_CHIP_SET, len(PlayroomMod.ChipList))
for range ChipNum {
player.SubPlayroomChip(int(player.M_DwUin))
}
player.PlayMod.save()
player.PlayroomBackData()
player.PushClientRes(&msg.ResPlayroomChip{
@ -4156,7 +4166,7 @@ func ReqPlayroomFlipReward(player *Player, buf []byte) error {
})
return err
}
G_GameLogicPtr.FriendMgrSend(&MsqMod.Msg{
FriendMgrSend(&MsqMod.Msg{
From: int(player.M_DwUin),
To: Target,
Type: MsqMod.HANDLE_TYPE_PLAYROOM_LOSE,
@ -4258,8 +4268,8 @@ func ReqPlayroomUpvote(player *Player, buf []byte) error {
Type: MsqMod.HANDLE_TYPE_PLAYROOM_KISS,
SendT: GoUtil.Now(),
})
G_GameLogicPtr.SetUserData(int(req.Id), VAR_OP_UPVOTE, 1)
G_GameLogicPtr.SetUserData(int(req.Id), VAR_OP_KISS, 1)
player.AddPlayroomUpvote(int(req.Id))
player.SetPlayroomKiss(1)
player.TeLog("visit_like", map[string]interface{}{
"user_id": req.Id,
})
@ -4621,7 +4631,7 @@ func ReqFriendTreasureEnd(player *Player, buf []byte) error {
if v.Status == 1 {
ItemNum = FriendItemNum
}
G_GameLogicPtr.FriendMgrSend(&MsqMod.Msg{
FriendMgrSend(&MsqMod.Msg{
From: int(player.M_DwUin),
To: int(v.Uid),
Type: MsqMod.FRIEND_TREASURE_HANDLE,
@ -5449,7 +5459,7 @@ func ReqCatnipAgree(player *Player, buf []byte) error {
})
return err
}
err = G_GameLogicPtr.SetCatnipPartner(int(player.M_DwUin), int(req.Id), int(req.Uid), ActivityInfo.EndT)
err = player.SetCatnipPartner(int(req.Id), int(req.Uid), ActivityInfo.EndT)
if err != nil {
player.SendErrClienRes(&msg.ResCatnipAgree{
Code: msg.RES_CODE_FAIL,
@ -5769,7 +5779,7 @@ func ReqFriendReplyHandle(player *Player, buf []byte) error {
case friend.REPLY_TYPE_CATNIP: // 猫草大作战同意邀请
GameId := GoUtil.Int(ReplyInfo.Param)
activityInfo := player.GetActivityInfo(player.GetActivityId(activity.ACT_TYPE_CATNIP))
err := G_GameLogicPtr.SetCatnipPartner(int(player.M_DwUin), GameId, ReplyInfo.Uid, activityInfo.EndT)
err := player.SetCatnipPartner(GameId, ReplyInfo.Uid, activityInfo.EndT)
if err == nil {
CatnipMod := player.PlayMod.getCatnipMod()
ActivityId := player.GetActivityId(activity.ACT_TYPE_MINING)

182
src/server/game/var.go Normal file
View File

@ -0,0 +1,182 @@
package game
import (
"fmt"
"server/db"
"server/game/mod/msg"
GoUtil "server/game_util"
"server/pkg/github.com/name5566/leaf/log"
)
const (
VAR_KEY_FRIEND_MSG = "friend_msg" // 好友消息
VAR_GOLD_CARD = "gold_card"
VAR_PLAYROOM_UPVOTE = "playroom_upvote"
VAR_PLAYROOM_CHIP = "playroom_chip"
VAR_PLAYROOM_KISS = "playroom_kiss"
VAR_USER_DATA = "user_data"
VAR_CATNIP_PARTNER = "catnip_partner"
)
func (p *Player) GetVarData(key string) interface{} {
cache := &VarExpireData{}
err := LoadCacheVarData(key, cache)
if err != nil {
log.Error("GetVarData err : %s, key: %s", err, key)
return nil
}
return cache.D
}
func (p *Player) GetUserVarData(key string) interface{} {
cache := map[string]*VarExpireData{}
err := LoadCacheVarData(GoUtil.GetVarKey(int(p.M_DwUin)), &cache)
if err != nil {
log.Error("GetUserVarData err : %s, key: %s", err, key)
return nil
}
data, ok := cache[key]
if !ok {
return nil
}
return data.D
}
// func GetServerVarData(key string) interface{} {
// data, err := GetServerData(key)
// if err != nil {
// log.Error("GetServerVarData err : %s", err)
// return nil
// }
// return data.Extra
// }
func (p *Player) OpVarDataAsync(key string, value interface{}, opType int) {
SendMsgToCenterAsync(&msg.Msg{
From: int(p.M_DwUin),
HandleType: msg.HANDLE_MOD_USER_VAR_SET,
Extra: msg.VarData{
Key: key,
Value: value,
SetType: opType,
},
})
}
func (p *Player) OpVarDataSync(key string, value interface{}, opType int) (*msg.Msg, error) {
return SendMsgToCenterSync(&msg.Msg{
From: int(p.M_DwUin),
HandleType: msg.HANDLE_MOD_USER_VAR_SET,
Extra: msg.VarData{
Key: key,
Value: value,
SetType: opType,
},
})
}
func (p *Player) OpServerVarDataAsync(key string, Value interface{}, opType int) {
SendMsgToCenterSync(&msg.Msg{
HandleType: msg.HANDLE_MOD_VAR_SET,
Extra: msg.VarData{Key: key, Value: Value, SetType: opType},
})
}
func (p *Player) OpServerVarDataSync(key string, Value interface{}, opType int) (*msg.Msg, error) {
return SendMsgToCenterSync(&msg.Msg{
HandleType: msg.HANDLE_MOD_VAR_SET,
Extra: msg.VarData{Key: key, Value: Value, SetType: opType},
})
}
func (p *Player) SetVarDataAsync(key string, value interface{}) {
p.OpVarDataAsync(key, value, msg.VAR_OP_SET)
}
func (p *Player) AddVarDataAsync(key string) {
p.OpVarDataAsync(key, nil, msg.VAR_OP_ADD)
}
func (p *Player) SubVarDataAsync(key string) {
p.OpVarDataAsync(key, nil, msg.VAR_OP_SUB)
}
func (p *Player) AddPlayroomUpvote(PlayerId int) {
p.AddVarDataAsync(VAR_PLAYROOM_UPVOTE)
}
func (p *Player) AddPlayroomChip(PlayerId int) {
p.AddVarDataAsync(VAR_PLAYROOM_CHIP)
}
func (p *Player) SubPlayroomChip(PlayerId int) {
p.SubVarDataAsync(VAR_PLAYROOM_CHIP)
}
func (p *Player) GetPlayroomUpvote() int {
data := p.GetUserVarData(VAR_PLAYROOM_UPVOTE)
if data == nil {
return 0
}
return data.(int)
}
func (p *Player) GetPlayroomChip() int {
data := p.GetUserVarData(VAR_PLAYROOM_CHIP)
if data == nil {
return 0
}
return data.(int)
}
func (p *Player) SetPlayroomKiss(Kiss int) {
p.SetVarDataAsync(VAR_PLAYROOM_KISS, Kiss)
}
func (p *Player) GetPlayroomKiss() int {
data := p.GetUserVarData(VAR_PLAYROOM_KISS)
if data == nil {
return 0
}
return data.(int)
}
func (p *Player) GetGoldCard() *VarGoldCard {
data := p.GetVarData(VAR_GOLD_CARD)
if data == nil {
return &VarGoldCard{}
}
return data.(*VarGoldCard)
}
func (p *Player) GetCatnipPartner(Uid int) []int {
data, err := GetUserData(p.M_DwUin, VAR_CATNIP_PARTNER)
if err != nil {
log.Error("GetVarData err : %s", err)
return nil
}
if data == nil {
return nil
}
return GoUtil.IntSlice(data.Extra)
}
func SaveCacheVarData(key string, value interface{}) {
data, err := GoUtil.GobMarshal(value)
if err != nil {
log.Error("SaveCacheVarData GobMarshal err : %s", err)
return
}
db.RedisSetKeyBytes(key, data, 0)
}
func LoadCacheVarData(key string, value interface{}) error {
data, err := db.RedisGetKeyBytes(key)
if err != nil {
return err
}
if data == nil {
return fmt.Errorf("no data")
}
return GoUtil.GobUnmarshal(data, value)
}

View File

@ -6,6 +6,8 @@ import (
"server/game/mod/card"
"server/game/mod/msg"
GoUtil "server/game_util"
"strings"
"sync"
"time"
)
@ -17,14 +19,13 @@ type VarData struct {
Var map[string]interface{}
VarExpire map[string]*VarExpireData
UserVar map[string]*VarUserData
ZeroTime int64
}
const (
VAR_GOLD_CARD = "gold_card"
VAR_PLAYROOM_UPVOTE = "playroom_upvote"
VAR_USER_DATA = "user_data"
)
NewVar map[string]*VarExpireData
NewUseVar map[int]map[string]*VarExpireData
ZeroTime int64
Version int64
mu sync.Mutex
}
const (
VAR_OP_UPVOTE = 1
@ -36,14 +37,18 @@ const (
func (f *VarMgr) Init() {
gob.Register(&VarGoldCard{})
gob.Register(&VarExpireData{})
f.key = VAR_MGR_KEY
f.data = &VarData{
Var: map[string]interface{}{},
NewVar: map[string]*VarExpireData{},
NewUseVar: map[int]map[string]*VarExpireData{},
}
// 注册处理函数
f.init()
if f.data.(*VarData).Var == nil {
f.data.(*VarData).Var = make(map[string]interface{})
// 版本更新 重构
f.version()
if f.data.(*VarData).NewVar == nil {
f.data.(*VarData).NewVar = make(map[string]*VarExpireData)
}
if f.data.(*VarData).UserVar == nil {
f.data.(*VarData).UserVar = make(map[string]*VarUserData)
@ -52,23 +57,37 @@ func (f *VarMgr) Init() {
f.data.(*VarData).VarExpire = make(map[string]*VarExpireData)
}
if f.getData().ZeroTime == GoUtil.ZeroTimestamp() {
f.ZeroUpdate(&msg.Msg{})
f.ZeroUpdate()
}
f.RegisterHandler(msg.SERVER_ZERO_UPDATE, f.ZeroUpdate)
f.RegisterHandler(msg.HANDLE_TYPE_SET_CATNIP_PARTNER, f.SetCatnipPartner)
f.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
f.Send(&msg.Msg{
Type: msg.SERVER_ZERO_UPDATE,
})
f.ZeroUpdate()
})
}
func (f *VarMgr) SetGlobalData(m *msg.Msg) (interface{}, error) {
return nil, nil
func (f *VarMgr) version() {
switch v := f.getData().Version; v {
case 0:
// future version update
data := f.getData()
data.mu.Lock()
defer data.mu.Unlock()
// set to next version
for k, v := range data.UserVar {
if v != nil {
uidStr := strings.Split(k, "_")[2]
uid := GoUtil.Int(uidStr)
f.SetUserVar(uid, VAR_PLAYROOM_UPVOTE, v.Upvote)
f.SetUserVar(uid, VAR_PLAYROOM_CHIP, v.Chip)
f.SetUserVar(uid, VAR_PLAYROOM_KISS, v.Kiss)
delete(data.UserVar, k)
}
}
f.getData().Version = 1
}
}
func (f *VarMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) {
func (f *VarMgr) ZeroUpdate() {
f.getData().ZeroTime = GoUtil.ZeroTimestamp()
// 随机生成两个金卡
Card1, Card2 := card.RankGoldCard()
@ -76,72 +95,82 @@ func (f *VarMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) {
Four: Card1,
Five: Card2,
})
for k, v := range f.getData().VarExpire {
for k, v := range f.getData().NewVar {
if v.T < GoUtil.ZeroTimestamp() {
delete(f.getData().VarExpire, k)
delete(f.getData().Var, k)
}
}
return nil, nil
f.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
f.ZeroUpdate()
})
}
func (f *VarMgr) SetCatnipPartner(m *msg.Msg) (interface{}, error) {
if Param, ok := m.Extra.(map[string]interface{}); ok {
MyUid := GoUtil.Int(Param["uid"])
CatnipGameId := GoUtil.Int(Param["game_id"])
CatnipPartnerId := GoUtil.Int(Param["partner_uid"])
myKey := fmt.Sprintf("catnip_partner_%d", MyUid)
key := fmt.Sprintf("catnip_partner_%d", CatnipPartnerId)
OtherPartnerInfo := f.GetExpireVar(key)
MyPartnerInfo := f.GetExpireVar(myKey)
func (f *VarMgr) HandleCatnipPartner(Uid, Partner, GameId int, EndTime int64) (interface{}, error) {
data := f.getData()
data.mu.Lock()
defer data.mu.Unlock()
OtherPartnerInfo := f.GetUserVar(Uid, VAR_CATNIP_PARTNER)
MyPartnerInfo := f.GetUserVar(Partner, VAR_CATNIP_PARTNER)
MyOfPartnerList := GoUtil.IntSlice(MyPartnerInfo.D)
OtherOfPartnerList := GoUtil.IntSlice(OtherPartnerInfo.D)
if len(MyOfPartnerList) > 4 || len(OtherOfPartnerList) > 4 {
return nil, fmt.Errorf("catnip partner already full for uid %d in game %d", CatnipPartnerId, CatnipGameId)
return nil, fmt.Errorf("catnip partner already full for uid %d in game %d", Partner, GameId)
}
f.SetExpireVar(key, &VarExpireData{
D: append(OtherOfPartnerList, MyUid),
T: m.End,
f.SetUserVar(Partner, VAR_CATNIP_PARTNER, &VarExpireData{
D: append(OtherOfPartnerList, Uid),
T: EndTime,
})
f.SetExpireVar(myKey, &VarExpireData{
D: append(MyOfPartnerList, CatnipPartnerId),
T: m.End,
f.SetUserVar(Uid, VAR_CATNIP_PARTNER, &VarExpireData{
D: append(MyOfPartnerList, Partner),
T: EndTime,
})
return nil, nil
}
func (f *VarMgr) SetUserVar(uid int, key string, value interface{}) {
varData := f.getData().NewUseVar[uid]
if varData == nil {
varData = make(map[string]*VarExpireData)
f.getData().NewUseVar[uid] = varData
}
return nil, fmt.Errorf("invalid parameters for setting catnip partner")
ved, ok := varData[key]
if !ok {
ved = &VarExpireData{}
}
ved.D = value
varData[key] = ved
f.getData().NewUseVar[uid] = varData
SaveCacheVarData(GoUtil.GetVarKey(uid), varData)
}
func (f *VarMgr) GetUserVar(uid int, key string) *VarExpireData {
varData := f.getData().NewUseVar[uid]
if varData == nil {
varData = make(map[string]*VarExpireData)
f.getData().NewUseVar[uid] = varData
}
ved, ok := varData[key]
if !ok {
ved = &VarExpireData{}
varData[key] = ved
}
return ved
}
func (f *VarMgr) SetVar(key string, value interface{}) {
f.getData().Var[key] = value
f.getData().NewVar[key] = &VarExpireData{
D: value,
}
SaveCacheVarData(key, f.getData().NewVar[key])
}
func (f *VarMgr) GetVar(key string) interface{} {
return f.getData().Var[key]
}
func (f *VarMgr) SetExpireVar(key string, value *VarExpireData) {
f.getData().VarExpire[key] = value
}
func (f *VarMgr) GetExpireVar(key string) *VarExpireData {
if v, ok := f.getData().VarExpire[key]; ok {
func (f *VarMgr) GetVar(key string) *VarExpireData {
if v, ok := f.getData().NewVar[key]; ok {
return v
}
data := &VarExpireData{}
f.getData().VarExpire[key] = data
return data
}
func (f *VarMgr) SetUserVar(key string, value *VarUserData) {
f.getData().UserVar[key] = value
}
func (f *VarMgr) GetUserVar(key string) *VarUserData {
if v, ok := f.getData().UserVar[key]; ok {
return v
}
data := &VarUserData{}
f.getData().UserVar[key] = data
f.getData().NewVar[key] = data
return data
}
@ -152,3 +181,121 @@ func (f *VarMgr) DelVar(key string) {
func (f *VarMgr) getData() *VarData {
return f.data.(*VarData)
}
func getVarData() *VarData {
return G_GameLogicPtr.VarMgr.getData()
}
func SetVarDataHandler(m *msg.Msg) (interface{}, error) {
data := getVarData()
data.mu.Lock()
defer data.mu.Unlock()
if v, ok := m.Extra.(msg.VarData); ok {
ved, ok := data.NewVar[v.Key]
if !ok {
ved = &VarExpireData{}
}
switch v.SetType {
case msg.VAR_OP_SET:
ved.D = v.Value
case msg.VAR_OP_ADD:
if num, ok := ved.D.(int); ok {
ved.D = num + 1
} else {
ved.D = 1
}
case msg.VAR_OP_SUB:
if num, ok := ved.D.(int); ok {
if num > 0 {
ved.D = num - 1
} else {
ved.D = 0
}
} else {
ved.D = 0
}
}
ved.U = time.Now().Unix()
if m.End > 0 {
ved.T = m.End
}
data.Var[v.Key] = ved
SaveCacheVarData(v.Key, ved)
}
return nil, nil
}
func GetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
data := getVarData()
userVar := &VarExpireData{}
if v, ok := m.Extra.(msg.VarData); ok {
if varData, ok := data.NewUseVar[m.From]; ok {
userVar, _ = varData[v.Key]
}
if userVar == nil {
userVar = &VarExpireData{}
}
ReplyPlayerMsgASync(m, userVar.D)
return userVar, nil
}
return nil, fmt.Errorf("invalid parameters for getting var data")
}
func SetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
data := getVarData()
data.mu.Lock()
defer data.mu.Unlock()
if v, ok := m.Extra.(msg.VarData); ok {
varData := data.NewUseVar[m.From]
if varData == nil {
varData = make(map[string]*VarExpireData)
data.NewUseVar[m.From] = varData
}
ved, ok := varData[v.Key]
if !ok {
ved = &VarExpireData{}
}
switch v.SetType {
case msg.VAR_OP_SET:
ved.D = v.Value
case msg.VAR_OP_ADD:
if num, ok := ved.D.(int); ok {
ved.D = num + 1
} else {
ved.D = 1
}
case msg.VAR_OP_SUB:
if num, ok := ved.D.(int); ok {
if num > 0 {
ved.D = num - 1
} else {
ved.D = 0
}
} else {
ved.D = 0
}
}
ved.U = time.Now().Unix()
if m.End > 0 {
ved.T = m.End
}
data.Var[v.Key] = ved
}
// 保存到缓存中
SaveCacheVarData(GoUtil.GetVarKey(m.From), data.NewUseVar[m.From])
return nil, nil
}
func GetVarDataHandler(m *msg.Msg) (interface{}, error) {
data := getVarData()
varData := &VarExpireData{}
if v, ok := m.Extra.(msg.VarData); ok {
varData, _ = data.NewVar[v.Key]
if varData == nil {
varData = &VarExpireData{}
}
ReplyPlayerMsgASync(m, varData.D)
return varData, nil
}
return nil, fmt.Errorf("invalid parameters for getting var data")
}

View File

@ -300,10 +300,6 @@ func UniKey(seed string) string {
return fmt.Sprintf("%x", hash.Sum(nil))
}
func GetUserKey(Uid int64) string {
return fmt.Sprintf("user_data_%d", Uid)
}
func GetCatnipLockKey(Uid, GameId int) string {
return fmt.Sprintf("catnip_lock_%d_%d", Uid, GameId)
}
@ -535,3 +531,7 @@ func GetISOCodeByIP(ip string) (string, error) {
}
return GetISOCodeByCountry(country)
}
func GetVarKey(Uid int) string {
return fmt.Sprintf("var_%d", Uid)
}

View File

@ -2628,7 +2628,7 @@ type ResPlayerBaseInfo struct {
Guild int32 `protobuf:"varint,10,opt,name=guild,proto3" json:"guild,omitempty"`
PackUnlockCount int32 `protobuf:"varint,11,opt,name=pack_unlock_count,json=packUnlockCount,proto3" json:"pack_unlock_count,omitempty"`
LastPlayTime int32 `protobuf:"varint,12,opt,name=last_play_time,json=lastPlayTime,proto3" json:"last_play_time,omitempty"`
EnergyBuyCount int32 `protobuf:"varint,13,opt,name=EnergyBuyCount,proto3" json:"EnergyBuyCount,omitempty"`
Ban int64 `protobuf:"varint,13,opt,name=ban,proto3" json:"ban,omitempty"`
UserName string `protobuf:"bytes,14,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`
LoginTime int32 `protobuf:"varint,15,opt,name=login_time,json=loginTime,proto3" json:"login_time,omitempty"`
LogoutTime int32 `protobuf:"varint,16,opt,name=logout_time,json=logoutTime,proto3" json:"logout_time,omitempty"`
@ -2758,9 +2758,9 @@ func (x *ResPlayerBaseInfo) GetLastPlayTime() int32 {
return 0
}
func (x *ResPlayerBaseInfo) GetEnergyBuyCount() int32 {
func (x *ResPlayerBaseInfo) GetBan() int64 {
if x != nil {
return x.EnergyBuyCount
return x.Ban
}
return 0
}
@ -27717,7 +27717,7 @@ const file_proto_Gameapi_proto_rawDesc = "" +
"ResultCode\x18\x01 \x01(\x05R\n" +
"ResultCode\")\n" +
"\x11ReqPlayerBaseInfo\x12\x14\n" +
"\x05dwUin\x18\x01 \x01(\x03R\x05dwUin\"\x93\x06\n" +
"\x05dwUin\x18\x01 \x01(\x03R\x05dwUin\"\xfd\x05\n" +
"\x11ResPlayerBaseInfo\x12\x14\n" +
"\x05dwUin\x18\x01 \x01(\x03R\x05dwUin\x12\x16\n" +
"\x06energy\x18\x02 \x01(\x05R\x06energy\x12\x12\n" +
@ -27732,8 +27732,8 @@ const file_proto_Gameapi_proto_rawDesc = "" +
"\x05guild\x18\n" +
" \x01(\x05R\x05guild\x12*\n" +
"\x11pack_unlock_count\x18\v \x01(\x05R\x0fpackUnlockCount\x12$\n" +
"\x0elast_play_time\x18\f \x01(\x05R\flastPlayTime\x12&\n" +
"\x0eEnergyBuyCount\x18\r \x01(\x05R\x0eEnergyBuyCount\x12\x1b\n" +
"\x0elast_play_time\x18\f \x01(\x05R\flastPlayTime\x12\x10\n" +
"\x03ban\x18\r \x01(\x03R\x03ban\x12\x1b\n" +
"\tuser_name\x18\x0e \x01(\tR\buserName\x12\x1d\n" +
"\n" +
"login_time\x18\x0f \x01(\x05R\tloginTime\x12\x1f\n" +