pet_home_server/src/server/game/player_data.go
2026-03-17 15:25:25 +08:00

1426 lines
39 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package game
import (
"context"
"database/sql"
"encoding/json"
"errors"
"math"
"server/conf"
activityCfg "server/conf/activity"
cardCfg "server/conf/card"
chargeCfg "server/conf/charge"
fur_cfg "server/conf/fur"
guesscolorCfg "server/conf/guess_color"
itemCfg "server/conf/item"
limitedTimeEventCfg "server/conf/limited_time_event"
mergeDataCfg "server/conf/merge_data"
miningCfg "server/conf/mining"
orderCfg "server/conf/order"
playroomCfg "server/conf/playroom"
"server/db"
"server/ga"
"server/game/mod/activity"
"server/game/mod/friend"
"server/game/mod/item"
limitedTimeEvent "server/game/mod/limited_time_event"
MsgMod "server/game/mod/msg"
"server/game/mod/order"
"server/game/mod/playroom"
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
telog "server/thinkdata"
"strconv"
"sync"
"time"
"server/pkg/github.com/name5566/leaf/gate"
"server/pkg/github.com/name5566/leaf/log"
"server/pkg/github.com/name5566/leaf/timer"
"github.com/robfig/cron/v3"
"google.golang.org/protobuf/proto"
)
// import "reflect"
//"fmt"
type Player struct {
PlayerBaseMod *PlayerBaseData
PlayMod PlayerMod
M_DwUin int64
agent gate.Agent
lock sync.Mutex
stopSignal chan bool
Msg []PlayerMsg
Trigger []*quest.Trigger
MDispatr *timer.Dispatcher
McronSave *cron.Cron
McronSaveID cron.EntryID
msgChan chan *MsgMod.Msg
args map[string]interface{}
timerList map[string]*timer.Timer
activity map[int]*ActivityInfo
stop bool
wg sync.WaitGroup
dispatcherWg sync.WaitGroup
stopOnce sync.Once
msgChanOnce sync.Once
func_time int
}
type PlayerBackUp struct {
Data msg.ResPlayerBaseInfo
PlayMod []byte
}
type PlayerMsg struct {
F string
B []byte
}
func (p *Player) Stop() {
p.wg.Wait()
p.signalDispatcherStop()
p.msgChanOnce.Do(func() {
close(p.msgChan)
})
for _, timer := range p.timerList {
timer.Stop()
}
p.McronSave.Stop()
p.stop = true
}
func (p *Player) signalDispatcherStop() {
p.stopOnce.Do(func() {
close(p.stopSignal)
})
}
func (p *Player) CallEvent(Duration time.Duration, F func(), Label string) {
if v, ok := p.timerList[Label]; ok {
v.Stop()
}
t := p.MDispatr.AfterFunc(Duration, F)
p.timerList[Label] = t
}
// 异步请求
func (p *Player) Send(m *MsgMod.Msg) error {
if m == nil {
return nil
}
p.wg.Add(1)
p.msgChan <- m
return nil
}
func (p *Player) Call(m MsgMod.Msg) {
p.HandleMsg(m.Clone())
}
func (p *Player) SendClientRes() {
for _, v := range p.Msg {
G_GameLogicPtr.PackResInfo(p.GetAgent(), v.F, v.B)
}
p.Msg = make([]PlayerMsg, 0)
}
func (p *Player) PushClientRes(m proto.Message) {
key := GetStructName(m)
buff, _ := proto.Marshal(m)
p.Msg = append(p.Msg, PlayerMsg{
F: key,
B: buff,
})
}
func (p *Player) PushAndSendClienRes(m proto.Message) {
key := GetStructName(m)
buff, _ := proto.Marshal(m)
G_GameLogicPtr.PackResInfo(p.GetAgent(), key, buff)
}
func (p *Player) SendErrClienRes(m proto.Message) {
key := GetStructName(m)
buff, _ := proto.Marshal(m)
G_GameLogicPtr.PackResInfo(p.GetAgent(), key, buff)
}
func (p *Player) QuestTrigger(tr *quest.Trigger) {
p.Trigger = append(p.Trigger, tr)
}
func (p *Player) QuestTriggerList(tr []*quest.Trigger) {
p.Trigger = append(p.Trigger, tr...)
}
func (p *Player) ProcessTrigger() {
IsDailyBack := false
DailyTaskMod := p.PlayMod.getDailyTaskMod()
MailMod := p.PlayMod.getMailMod()
PlayroomMod := p.PlayMod.getPlayroomMod()
GuideTaskMod := p.PlayMod.getGuideTaskMod()
IsPlayroomBack := false
IsMailBack := false
IsGuideTask := false
for _, tr := range p.Trigger {
if DailyTaskMod.Trigger(tr) {
IsDailyBack = true
}
if p.MailTrigger(tr) {
IsMailBack = true
}
if PlayroomMod.QuestTrigger(tr) {
IsPlayroomBack = true
}
if GuideTaskMod.Trigger(tr) {
IsGuideTask = true
}
}
if IsDailyBack {
p.PushClientRes(DailyTaskMod.BackData())
}
if IsMailBack {
p.PushClientRes(MailMod.BackData())
}
if IsPlayroomBack {
p.NotifyPlayroomTask()
}
if IsGuideTask {
p.PushClientRes(GuideTaskMod.BackData())
}
p.Trigger = make([]*quest.Trigger, 0)
}
// 接口请求之前备份数据
func (p *Player) BackUp() *PlayerBackUp {
BackUp := PlayerBackUp{}
p.PlayMod.BackUp(&BackUp)
BackUp.Data = p.GetPlayerBaseMod().BackUp()
return &BackUp
}
// 接口发生错误时 还原数据
func (p *Player) Recover(backUp *PlayerBackUp) {
// p.GetPlayerBaseMod().Data = backUp.Data
p.PlayMod.Recover(backUp)
p.Msg = make([]PlayerMsg, 0)
}
func (p *Player) InitPlayer(UserName string) error {
p.lock.Lock()
defer p.lock.Unlock()
p.msgChan = make(chan *MsgMod.Msg, 100)
p.Msg = make([]PlayerMsg, 0)
p.args = make(map[string]interface{})
p.timerList = make(map[string]*timer.Timer)
p.MDispatr = timer.NewDispatcher(100)
p.stopSignal = make(chan bool)
p.stopOnce = sync.Once{}
p.msgChanOnce = sync.Once{}
Base := &PlayerBaseData{p: p}
// 玩家基础数据
ok := Base.LoadDataFromDB(UserName)
if !ok {
log.Debug("load PlayerBaseData failed:%s", UserName)
return errors.New("load PlayerBaseData failed")
}
p.PlayerBaseMod = Base
p.M_DwUin = Base.Data.DwUin
// 棋盘数据
// 玩家模块数据
modData := &PlayerModData{PlayerData: NewPlayerData("PlayerModData", p)}
ok = modData.LoadDataFromDB(Base.Data.DwUin)
if !ok {
log.Debug("load PlayerModData failed:%s", UserName)
return errors.New("load PlayerModData failed")
}
IsUpdate, err := modData.InitMod(p)
if err != nil {
log.Debug("InitMod failed:", err)
return err
}
p.PlayMod.mod_list = modData.ModList
p.PlayMod.is_update = IsUpdate
// 启动定时器
p.DispatcherHandle()
p.McronSave = cron.New()
_, err = p.McronSave.AddFunc("@every 1m", p.AutoSaveData)
if err != nil {
log.Debug("AddFunc failed:", err)
}
p.McronSave.Start()
p.InitActivity()
p.ZeroUpdate(nil)
p.NoonUpdate(nil)
p.Login()
p.OrderShip()
p.UpdateUserInfo()
// fix bug
ChargeMod := p.PlayMod.getChargeMod()
ChessMod := p.PlayMod.getChessMod()
ChargeMod.FixBug(ChessMod.GetEmitList())
p.FixOrderBug()
p.FixDecorate()
p.FixPlayroomPyhical()
return nil
}
func (p *Player) InitPlayerByUid(Uid int) error {
p.lock.Lock()
defer p.lock.Unlock()
p.msgChan = make(chan *MsgMod.Msg, 100)
p.Msg = make([]PlayerMsg, 0)
p.args = make(map[string]interface{})
p.timerList = make(map[string]*timer.Timer)
p.MDispatr = timer.NewDispatcher(100)
p.stopSignal = make(chan bool)
p.stopOnce = sync.Once{}
p.msgChanOnce = sync.Once{}
Base := &PlayerBaseData{p: p}
// 玩家基础数据
ok := Base.LoadDataFromDBByUid(Uid)
if !ok {
log.Debug("load PlayerBaseData failed:%d", Uid)
return errors.New("load PlayerBaseData failed")
}
p.PlayerBaseMod = Base
p.M_DwUin = Base.Data.DwUin
// 棋盘数据
// 玩家模块数据
modData := &PlayerModData{PlayerData: NewPlayerData("PlayerModData", p)}
ok = modData.LoadDataFromDB(Base.Data.DwUin)
if !ok {
log.Debug("load PlayerModData failed:%d", Uid)
return errors.New("load PlayerModData failed")
}
IsUpdate, err := modData.InitMod(p)
if err != nil {
log.Debug("InitMod failed:", err)
return err
}
p.PlayMod.mod_list = modData.ModList
p.PlayMod.is_update = IsUpdate
// 启动定时器
p.DispatcherHandle()
p.McronSave = cron.New()
_, err = p.McronSave.AddFunc("@every 1m", p.AutoSaveData)
if err != nil {
log.Debug("AddFunc failed:", err)
}
p.McronSave.Start()
p.InitActivity()
p.ZeroUpdate(nil)
p.NoonUpdate(nil)
p.Login()
p.OrderShip()
p.UpdateUserInfo()
// fix bug
ChargeMod := p.PlayMod.getChargeMod()
ChessMod := p.PlayMod.getChessMod()
ChargeMod.FixBug(ChessMod.GetEmitList())
p.FixOrderBug()
p.FixDecorate()
return nil
}
func (p *Player) OrderShip() {
OrderList, err := db.GetPlayerChargeDataList(int(p.M_DwUin))
if err != nil {
return
}
// 避免为每个订单创建 goroutine改为批量处理或同步处理
for _, OrderInfo := range OrderList {
// 直接同步处理,避免创建过多 goroutine
go p.TriggerShippingOrderOrigin(&msg.ReqShippingOrder{
OrderSn: OrderInfo.OrderId,
})
}
}
// 零点更新
func (p *Player) ZeroUpdate(a []interface{}) {
VarMod := p.PlayMod.getVarMod()
zeroTimestamp := GoUtil.ZeroTimestamp()
PlayerBaseMod := p.GetPlayerBaseMod()
// 零点更新
if VarMod.DailyResetTime < zeroTimestamp {
VarMod.DailyResetTime = zeroTimestamp
VarMod.DailyVar = make(map[int]interface{})
//卡牌 赛季结束补发图鉴奖励
HandbookItem := p.PlayMod.getCardMod().ZeroUpdate(G_GameLogicPtr.SeverInfo.OpenTime)
p.HandleItem(HandbookItem, msg.ITEM_POP_LABEL_AllCollectRewardHB.String())
p.PushClientRes(p.PlayMod.getCardMod().BackData())
// 能量商店
p.PlayMod.getBaseMod().ZeroUpdate()
p.PushClientRes(p.PlayMod.getBaseMod().BackData())
// 七日签到
p.PlayMod.getSevenLoginMod().ZeroUpdate(PlayerBaseMod.GetSevenLoginAdd(), PlayerBaseMod.GetLastLoginTime(), p.GetOrderFactor())
p.PushClientRes(p.PlayMod.getSevenLoginMod().BackData())
// 礼包充值
ChessMod := p.PlayMod.getChessMod()
ChargeMod := p.PlayMod.getChargeMod()
ChargeMod.ZeroUpdate(ChessMod.GetEmitList())
p.ChargeBackData()
// 无尽礼包
p.PlayMod.getEndlessMod().ZeroUpdate(p.PlayMod.getChargeMod().GetMaxCharge(), p.PlayMod.getBaseMod().GetLevel())
p.PushClientRes(p.PlayMod.getEndlessMod().BackData())
// 宠物宝箱
p.PlayMod.getFriendTreasureMod().ZeroUpdate()
// p.PushClientRes(p.PlayMod.getFriendTreasureMod().BackData())
// 好友功能
p.PlayMod.getFriendMod().ZeroUpdate()
p.PlayMod.getLimitedTimeEventMod().ZeroUpdate(p.GetPlayerBaseMod().GetLevel())
// playroom
PlayroomMod := p.PlayMod.getPlayroomMod()
PlayroomMod.ZeroUpdate()
if ChargeMod.IsWeeklyDiscountDay() {
PlayroomMod.ResetWeeklyDiscount()
}
p.PlayroomBackData()
p.PlayMod.getChampshipMod().ZeroUpdate()
p.InitActivity()
p.ActivityZeroUpdate()
// 每日任务
p.PlayMod.getDailyTaskMod().ZeroUpdate(p.GetPlayerBaseMod().GetLevel(), p.PlayMod.getDecorateMod().GetAreaId(), p.GetDailyTaskActivityId())
p.PushClientRes(p.PlayMod.getDailyTaskMod().BackData())
p.QuestTrigger(&quest.Trigger{Label: quest.TRIGGER_LABEL_LOGIN})
p.PlayMod.save()
}
// 周更新
weekZeroTimestamp := GoUtil.WeekZeroTimestamp()
if VarMod.WeeklyResetTime < weekZeroTimestamp {
VarMod.WeeklyResetTime = weekZeroTimestamp
VarMod.WeeklyVar = make(map[int]interface{})
p.PlayMod.getDailyTaskMod().WeekUpdate(p.GetOrderFactor())
p.PushClientRes(p.PlayMod.getDailyTaskMod().BackData())
p.PlayMod.getLimitedTimeEventMod().WeekUpdate()
p.PlayMod.save()
}
}
// 十二点更新
func (p *Player) NoonUpdate(a []interface{}) {
VarMod := p.PlayMod.getVarMod()
noonTimestamp := GoUtil.NoonTimestamp()
// 零点更新
if VarMod.NoonResetTime < noonTimestamp {
VarMod.NoonResetTime = noonTimestamp
ChessMod := p.PlayMod.getChessMod()
// 礼包充值
p.PlayMod.getChargeMod().NoonUpdate(ChessMod.GetEmitList())
p.ChargeBackData()
p.PlayMod.save()
}
}
func (p *Player) Login() {
// 添加定时器
// 限时事件触发
p.LimitedTimeEventTrigger(0)
// 猪猪银行触发
p.LimitedTimePiggyBankTrigger()
BaseMod := p.PlayMod.getBaseMod()
FaceMod := p.PlayMod.getFaceMod()
ChargeMod := p.PlayMod.getChargeMod()
AvatarMod := p.PlayMod.getAvatarMod()
PlayBaseMod := p.GetPlayerBaseMod()
GuideTaskMod := p.PlayMod.getGuideTaskMod()
// playroom触发
p.LimitedTimePlayroomTrigger() // playroom数值变化
LimitedTimePlayroomWorkTrigger(p) // playroom打工
LimitedTimeEnergyAdd(p) // 能量定时处理
p.ActivityLogin() // 活动登录
p.Compensation()
SyncMailMsg(p) // 同步邮件
Duration := BaseMod.Login()
ChargeMod.Login(Duration)
GuideTaskMod.Login()
FaceMod.Login(PlayBaseMod.GetRegisterTime())
AvatarMod.Login(PlayBaseMod.GetRegisterTime())
HandbookItem := p.PlayMod.getCardMod().Login(G_GameLogicPtr.SeverInfo.OpenTime)
p.HandleItem(HandbookItem, msg.ITEM_POP_LABEL_AllCollectRewardHB.String())
// 每周优惠特殊处理
WeeklyStartTime, WeeklyEndTime := chargeCfg.GetWeeklyDiscountStartEnd()
now := GoUtil.Now()
if now >= WeeklyStartTime && now <= WeeklyEndTime {
ChargeMod.WeeklyEndTime = WeeklyEndTime
}
if WeeklyStartTime > now {
p.CallEvent(time.Duration(WeeklyStartTime-now)*time.Second, func() {
ChargeMod.WeeklyEndTime = WeeklyEndTime
ChargeMod.ResetWeeklyDiscount()
PlayroomMod := p.PlayMod.getPlayroomMod()
PlayroomMod.ResetWeeklyDiscount()
p.ChargeBackData()
p.PlayroomBackData()
}, "WeeklyDiscountStart")
}
if WeeklyEndTime > now {
p.CallEvent(time.Duration(WeeklyEndTime-now)*time.Second, func() {
ChargeMod.WeeklyEndTime = 0
p.ChargeBackData()
p.PlayroomBackData()
LimitEventMod := p.PlayMod.getLimitedTimeEventMod()
LimitEventMod.EndCatDaySale()
p.PushClientRes(LimitEventMod.BackData())
}, "WeeklyDiscountEnd")
}
if Duration > 604800 {
FriendMod := p.PlayMod.getFriendMod()
FriendMod.AddActLog(friend.ACT_LOG_TYPE_LOST_USER_RETURN, "")
p.UpdateUserInfo()
}
}
func (p *Player) Outline() {
PlayroomMod := p.PlayMod.getPlayroomMod()
PlayroomMod.Outline()
PlayerBaseMod := p.GetPlayerBaseMod()
Now := GoUtil.Now()
Cacumulative := Now - PlayerBaseMod.GetLoginTime()
BaseMod := p.PlayMod.getBaseMod()
BaseMod.Outline(int(Cacumulative))
p.PlayMod.save()
type orderLogout struct {
Id int
Order order.Order
}
orderList := []orderLogout{}
for id, order := range p.PlayMod.getOrderMod().GetOrderList() {
orderList = append(orderList, orderLogout{
Id: id,
Order: order,
})
}
p.TeLog("logout", map[string]interface{}{
"caccumulative": Cacumulative,
"order_list": orderList,
"after_level": p.PlayMod.getBaseMod().GetLevel(),
"tmp_diamond": p.PlayMod.getBaseMod().GetDiamond(),
"tmp_energy": p.PlayMod.getBaseMod().GetEnergy(),
})
p.UpdateUserInfo()
}
// 离线 保存数据
func (p *Player) ClearData() {
log.Release("uid: %d, outline save data", p.M_DwUin)
p.Outline()
ctx := context.Background()
txOptions := &sql.TxOptions{}
tx, err := db.SqlDb.BeginTx(ctx, txOptions)
if err != nil {
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_MOD_PLAYER_LOGOUT,
})
}
func (p *Player) AutoSaveData() {
p.lock.Lock()
defer p.lock.Unlock()
//保存数据
ctx := context.Background()
txOptions := &sql.TxOptions{}
tx, err := db.SqlDb.BeginTx(ctx, txOptions)
if err != nil {
log.Debug("AutoSaveData BeginTx failed:", err)
return
}
p.PlayerBaseMod.SaveDataFromDB("")
p.PlayMod.ClearData(p)
err = tx.Commit()
if err != nil {
log.Debug("AutoSaveData Commit failed:", err)
}
log.Release("uid: %d, auto save data", p.M_DwUin)
}
// 重新连接
func (p *Player) Reconnect() {
}
// 获取conn连接
func (p *Player) GetAgent() gate.Agent {
return p.agent
}
// 设置conn连接
func (p *Player) SetAgent(a gate.Agent) {
p.agent = a
}
func (p *Player) GetPlayerBaseMod() *PlayerBaseData {
return p.PlayerBaseMod
}
func (p *Player) GetAgentByPlayer() gate.Agent {
return p.agent
}
// 处理物品
func (p *Player) HandleLoseItem(itemList []*item.Item, Label string) error {
if itemList == nil {
return nil
}
for _, v := range itemList {
if v.Num > 0 {
v.Num = -v.Num
}
}
return p.HandleItem(itemList, Label)
}
func (p *Player) HandleItem(itemList []*item.Item, Label string) error {
if itemList == nil {
return nil
}
is_update := false
ResCard := make([]*msg.CardPack, 0)
ResItem := make([]*msg.ItemInfo, 0)
ItemMod := p.PlayMod.getItemMod()
AvatarMod := p.PlayMod.getAvatarMod()
EmojiMod := p.PlayMod.getEmojiMod()
FaceMod := p.PlayMod.getFaceMod()
BackDataType := map[int]struct{}{}
for _, v := range itemList {
if v.Num == 0 {
continue
}
if v.Num > 0 && Label != "" {
ResItem = append(ResItem, &msg.ItemInfo{Id: int32(v.Id), Num: int32(v.Num)})
}
var change_type string
if v.Num < 0 {
change_type = "consume"
} else {
change_type = "gain"
}
IType := itemCfg.GetItemType(v.Id)
if IType == 0 {
return errors.New("item type error, item id :" + strconv.Itoa(v.Id))
}
switch IType {
case item.ITEM_TYPE_ENERGY: // 能量
err := p.GetPlayerBaseMod().AddEnergy(p, v.Num)
p.TeLog("asset_change", map[string]interface{}{
"item_id": v.Id,
"change_type": change_type,
"change_num": math.Abs(float64(v.Num)),
"change_after": p.GetPlayerBaseMod().GetEnergy(),
"change_reason": Label,
})
is_update = true
if err != nil {
return err
}
case item.ITEM_TYPE_STAR: // 星星
err := p.GetPlayerBaseMod().AddStar(p, v.Num)
is_update = true
if err != nil {
return err
}
p.TeLog("asset_change", map[string]interface{}{
"item_id": v.Id,
"change_type": change_type,
"change_num": math.Abs(float64(v.Num)),
"change_after": p.GetPlayerBaseMod().GetStar(),
"change_reason": Label,
})
case item.ITEM_TYPE_DIAMOND: // 钻石
err := p.GetPlayerBaseMod().AddDiamond(v.Num)
is_update = true
if err != nil {
return err
}
if v.Num < 0 {
p.QuestTrigger(&quest.Trigger{Label: quest.TRIGGER_LABEL_DIAMOND, A: []interface{}{-v.Num}})
}
p.TeLog("asset_change", map[string]interface{}{
"item_id": v.Id,
"change_type": change_type,
"change_num": math.Abs(float64(v.Num)),
"change_after": p.GetPlayerBaseMod().GetDiamond(),
"change_reason": Label,
})
case item.ITEM_TYPE_CARD: // 卡牌
Effect := itemCfg.GetItemEffect(v.Id)
p.AddCard(Effect)
case item.ITEM_TYPE_CARD_PACK: // 卡包
CardMod := p.PlayMod.getCardMod()
Effect := itemCfg.GetItemEffect(v.Id)
for i := 0; i < v.Num; i++ {
NewCard, err := CardMod.OpenCardPack(Effect)
if err != nil {
return err
}
ResCard = append(ResCard, &msg.CardPack{Id: int32(v.Id), Card: GoUtil.SliceIntToInt32(NewCard)})
IsGold := false
IsRepeat := false
Sticker := 0
for _, v := range NewCard {
Gold := cardCfg.CheckCardIsGold(v)
if Gold {
IsGold = true
}
if CardMod.GetCardNum(v) > 1 {
IsRepeat = true
Sticker++
} else {
p.TeLog("get_new_card", map[string]interface{}{
"season_id": CardMod.EndTime,
"card_id": v,
"card_typenumbers": len(CardMod.CardList),
})
}
}
p.TeLog("card_pack_open", map[string]interface{}{
"season_id": CardMod.EndTime,
"card_pack_type": v.Id,
"card_number": len(NewCard),
"card_list": NewCard,
"income_from": Label,
"is_goldcard": IsGold,
"is_repeat": IsRepeat,
"is_card_festival": CardMod.GetCardFestival(),
"sticker_number": Sticker,
})
}
case item.ITEM_TYPE_MASTER_CARD: // 万能卡
CardMod := p.PlayMod.getCardMod()
Effect := itemCfg.GetItemEffect(v.Id)
for i := 0; i < v.Num; i++ {
CardMod.AddMasterCard(Effect)
}
case item.ITEM_TYPE_CHESS: // 棋子
ChessMod := p.PlayMod.getChessMod()
if v.Num < 0 {
err := ChessMod.LosePart(v.Id, -v.Num)
if err != nil {
return err
}
p.TeLog("chess_part_consume", map[string]interface{}{
"chess_id": v.Id,
"chess_name": mergeDataCfg.GetNameById(v.Id),
"consume_num": -v.Num,
"remain_num": ChessMod.PartBag.List[v.Id].Num,
"consume_from": Label,
})
continue
}
for i := 0; i < v.Num; i++ {
ChessMod.AddChessBuff(v.Id)
}
Type := mergeDataCfg.GetTypeById(v.Id)
if Type == "Chest" || Type == "Gift" {
p.TeLog("get_chest", map[string]interface{}{
"chest_id": v.Id,
"chest_name": mergeDataCfg.GetNameById(v.Id),
"get_source": Label,
})
}
p.PushClientRes(ChessMod.BackData())
case item.ITEM_TYPE_LIMITED_TIME_EVENT: // 限时事件
EffectList := itemCfg.GetItemEffectList(v.Id)
LimitedTimeEventMod := p.PlayMod.getLimitedTimeEventMod()
if len(EffectList) < 2 {
log.Debug("Effect List error;item id :%d", v.Id)
continue
}
EndTime := LimitedTimeEventMod.AddEvent(EffectList[0], EffectList[1])
p.PushClientRes(&msg.LimitEventNotify{
Id: int32(EffectList[0]),
Type: limitedTimeEvent.EVENT_NOTIFY_TYPE_ADD,
EndTime: int32(EndTime),
Cd: int32(EffectList[1]),
})
// 触发订单事件 生成超级订单 卡牌节
p.LimitedTimeEventTrigger(EffectList[0])
p.TeLog("time_limited_event_enable", map[string]interface{}{
"event_type": limitedTimeEventCfg.GetEventName(EffectList[0]),
"enable_type": Label,
})
case item.ITEM_TYPE_PIGGY_BANK: // 猪猪银行
PiggyBankMod := p.PlayMod.getPiggyBankMod()
Effect := itemCfg.GetItemEffect(v.Id)
PiggyBankMod.AddPiggyBank(Effect)
p.LimitedTimePiggyBankTrigger()
p.PushClientRes(PiggyBankMod.BackData())
p.TeLog("piggy_bank_income", map[string]interface{}{
"piggy_bank_type": Effect,
"income_from": Label,
})
case item.ITEM_TYPE_AVATAR: // 头像框
Effect := itemCfg.GetItemEffectList(v.Id)
AvatarMod.Unlock(Effect[0], Effect[1])
p.TeLog("avatarIcon_income", map[string]interface{}{
"avatar_id": Effect[0],
"income_from": Label,
})
FriendMod := p.PlayMod.getFriendMod()
FriendMod.AddActLog(friend.ACT_LOG_TYPE_GET_NEW_AVATAR_FRAME, "")
p.UpdateUserInfo()
p.PlayerDecoLog("avatar", Effect[0], Label)
BackDataType[item.ITEM_TYPE_AVATAR] = struct{}{}
case item.ITEM_TYPE_EMOJI: // 表情
Effect := itemCfg.GetItemEffectList(v.Id)
EmojiMod.Unlock(Effect[0], Effect[1])
p.TeLog("emoji_income", map[string]interface{}{
"emoji_id": Effect[0],
"income_from": Label,
})
FriendMod := p.PlayMod.getFriendMod()
FriendMod.AddActLog(friend.ACT_LOG_TYPE_GET_NEW_EMOTION, "")
p.UpdateUserInfo()
p.PlayerDecoLog("emoji", Effect[0], Label)
BackDataType[item.ITEM_TYPE_EMOJI] = struct{}{}
case item.ITEM_TYPE_FACE: // 头像
Effect := itemCfg.GetItemEffectList(v.Id)
FaceMod.Unlock(Effect[0], Effect[1])
p.TeLog("face_income", map[string]interface{}{
"face_id": Effect[0],
"income_from": Label,
})
FriendMod := p.PlayMod.getFriendMod()
FriendMod.AddActLog(friend.ACT_LOG_TYPE_GET_NEW_AVATAR, "")
p.UpdateUserInfo()
p.PlayerDecoLog("face", Effect[0], Label)
BackDataType[item.ITEM_TYPE_FACE] = struct{}{}
case item.ITEM_TYPE_ACTIVITY_RACE: // 活动竞速
ActivityInfo := p.GetActivityInfo(activity.ACT_TYPE_RACE)
if ActivityInfo == nil {
continue
}
RaceMod := p.PlayMod.getRaceMod()
RaceMod.AddCoin(v.Num)
p.RaceBackData()
case item.ITEM_TYPE_PLAYROOM_VISIT: // 拜访玩家
Target := p.GetVisitorPlayer()
playroomMod := p.PlayMod.getPlayroomMod()
playroomMod.Target = Target
playroomMod.Status = playroom.STATUS_VISIT
// PlayroomVisit(p, Target)
p.PlayroomBackData()
case item.ITEM_TYPE_PLAYROOM_DECORATION: // playroom装饰
Effect := itemCfg.GetItemEffect(v.Id)
PlayroomMod := p.PlayMod.getPlayroomMod()
PlayroomMod.AddCollect(Effect, Label)
BackDataType[item.ITEM_TYPE_PLAYROOM_DECORATION] = struct{}{}
Type, Name := playroomCfg.GetDecoInfo(Effect)
FriendMod := p.PlayMod.getFriendMod()
FriendMod.AddActLog(friend.ACT_LOG_TYPE_GET_NEW_DECORATION, "")
p.UpdateUserInfo()
p.TeLog("room_deco_get", map[string]interface{}{
"room_deco_type": Type,
"room_deco_name": Name,
"room_deco_get_type": Label,
})
case item.ITEM_TYPE_PLAYROOM_DRESS: // playroom服饰
Effect := itemCfg.GetItemEffect(v.Id)
PlayroomMod := p.PlayMod.getPlayroomMod()
PlayroomMod.AddDress(Effect, Label)
BackDataType[item.ITEM_TYPE_PLAYROOM_DRESS] = struct{}{}
Type := playroomCfg.GetDressPart(Effect)
Name := playroomCfg.GetDressName(Effect)
FriendMod := p.PlayMod.getFriendMod()
FriendMod.AddActLog(friend.ACT_LOG_TYPE_GET_NEW_COSTUME, "")
p.UpdateUserInfo()
p.TeLog("pet_deco_get", map[string]interface{}{
"pet_deco_type": Type,
"pet_deco_name": Name,
"pet_deco_get_type": Label,
})
case item.ITEM_TYPE_PLAYROOM_DECORATION_SET: // playroom装饰套装
Effect := itemCfg.GetItemEffectList(v.Id)
PlayroomMod := p.PlayMod.getPlayroomMod()
for _, v := range Effect {
if v == 0 {
continue
}
PlayroomMod.AddCollect(v, Label)
Type, Name := playroomCfg.GetDecoInfo(v)
p.TeLog("room_deco_get", map[string]interface{}{
"room_deco_type": Type,
"room_deco_name": Name,
"room_deco_get_type": Label,
})
}
BackDataType[item.ITEM_TYPE_PLAYROOM_DECORATION_SET] = struct{}{}
case item.ITEM_TYPE_PLAYROOM_DRESS_SET: // playroom服饰套装
Effect := itemCfg.GetItemEffectList(v.Id)
PlayroomMod := p.PlayMod.getPlayroomMod()
for _, v := range Effect {
if v == 0 {
continue
}
PlayroomMod.AddDress(v, Label)
Name := playroomCfg.GetDressName(v)
Type := playroomCfg.GetDressPart(v)
p.TeLog("pet_deco_get", map[string]interface{}{
"pet_deco_type": Type,
"pet_deco_name": Name,
"pet_deco_get_type": Label,
})
}
BackDataType[item.ITEM_TYPE_PLAYROOM_DRESS_SET] = struct{}{}
case item.ITEM_TYPE_ACT_PASS: // 活动通行证
ActivityInfo := p.GetActivityInfo(activity.ACT_TYPE_PASS)
if ActivityInfo == nil {
continue
}
PassMod := p.PlayMod.getPassMod()
PassMod.AddExp(v.Num)
p.ActPassBackData()
case item.ITEM_TYPE_PET_FUR:
FurMod := p.PlayMod.getFurMod()
Effect := itemCfg.GetItemEffect(v.Id)
FurMod.AddFurInfo(Effect, GoUtil.Now(), 0)
BackDataType[item.ITEM_TYPE_PET_FUR] = struct{}{}
p.TeLog("pro_pet_fur_get", map[string]interface{}{
"pet_fur_name": fur_cfg.GetFurShopName(v.Id),
"fur_coin_cost": fur_cfg.GetFurShopCostNum(v.Id),
"pet_fur_get_type": Label,
})
case item.ITEM_TYPE_AD_CARD: // 广告卡
ChargeMod := p.PlayMod.getChargeMod()
Effect := itemCfg.GetItemEffect(v.Id)
ChargeMod.AddAdTime(Effect)
BackDataType[item.ITEM_TYPE_AD_CARD] = struct{}{}
default:
err := ItemMod.AddItem(v.Id, v.Num)
p.TeLog("asset_change", map[string]interface{}{
"item_id": v.Id,
"change_type": change_type,
"change_num": math.Abs(float64(v.Num)),
"change_after": ItemMod.GetItem(v.Id),
"change_reason": Label,
})
if err != nil {
return err
}
}
}
ResItemPopId := 0
if v, ok := p.args["ResItemPopId"]; ok {
ResItemPopId = GoUtil.Int(v)
}
if len(ResItem) != 0 || len(ResCard) != 0 {
p.PushClientRes(&msg.ResItemPop{
Id: int32(ResItemPopId),
Items: ResItem,
CardPacks: ResCard,
Lable: Label,
})
}
for k := range BackDataType {
switch k {
case item.ITEM_TYPE_AVATAR:
p.BackUserInfo()
case item.ITEM_TYPE_EMOJI:
p.BackUserInfo()
case item.ITEM_TYPE_FACE:
p.BackUserInfo()
case item.ITEM_TYPE_PLAYROOM_DECORATION,
item.ITEM_TYPE_PLAYROOM_DRESS,
item.ITEM_TYPE_PLAYROOM_DECORATION_SET,
item.ITEM_TYPE_PLAYROOM_DRESS_SET:
p.PlayroomBackData()
case item.ITEM_TYPE_PET_FUR:
FurMod := p.PlayMod.getFurMod()
p.PushClientRes(FurMod.BackData())
case item.ITEM_TYPE_AD_CARD:
p.ChargeBackData()
}
}
p.PetItemUseLog(itemList)
CardMod := p.PlayMod.getCardMod()
p.PushClientRes(CardMod.NotifyCard())
p.PushClientRes(ItemMod.NotifyItem())
p.PlayMod.save()
if is_update {
p.PushClientRes(p.GetPlayerBaseMod().BackAsset())
}
return nil
}
// 登录返回数据
func (p *Player) LoginBackData() {
SendMsgToCenterSync(&MsgMod.Msg{
From: int(p.M_DwUin),
HandleType: MsgMod.HANDLE_MOD_PLAYER_LOGIN,
Extra: conf.Server.ServerID,
})
SetFriendApplyNotification(int(p.M_DwUin), 0)
p.PushClientRes(p.PlayMod.mod_list.Base.BackData())
p.PushClientRes(p.PlayMod.mod_list.Handbook.BackData())
p.PushClientRes(p.PlayMod.mod_list.Base.BackData())
p.PushClientRes(p.PlayMod.mod_list.Chess.BackData())
p.PushClientRes(p.PlayMod.mod_list.Order.BackData())
p.PushClientRes(p.PlayMod.mod_list.Card.BackData())
p.PushClientRes(p.PlayMod.mod_list.Decorate.BackData())
p.PushClientRes(p.PlayMod.mod_list.DailyTask.BackData())
p.PushClientRes(p.PlayMod.mod_list.SevenLogin.BackData())
p.PushClientRes(p.PlayMod.mod_list.LimitedTimeEvent.ProgressBackData())
p.PushClientRes(p.PlayMod.mod_list.Charge.PetWorkBackData())
p.PushClientRes(p.PlayMod.mod_list.Endless.BackData())
p.PushClientRes(p.PlayMod.mod_list.PiggyBank.BackData())
p.PushClientRes(p.PlayMod.mod_list.Item.BackData())
p.PushClientRes(p.GetPlayerBaseMod().BackAsset())
p.PushClientRes(p.PlayMod.mod_list.Kv.BackData())
p.PushClientRes(p.PlayMod.mod_list.GuideTask.BackData())
p.PushClientRes(p.PlayMod.mod_list.Friend.BubbleBackData())
p.PushClientRes(p.PlayMod.mod_list.Guide.BackData())
p.BackDataActivity()
p.ChargeBackData()
p.BackChampship()
p.BackUserInfo()
}
func (p *Player) InitPlayerOnly() {
p.lock.Lock()
defer p.lock.Unlock()
p.Msg = make([]PlayerMsg, 0)
p.args = make(map[string]interface{})
p.timerList = make(map[string]*timer.Timer)
p.MDispatr = timer.NewDispatcher(10)
p.stopSignal = make(chan bool)
p.stopOnce = sync.Once{}
p.msgChanOnce = sync.Once{}
Base := &PlayerBaseData{p: p}
// 玩家基础数据
ok := Base.GetDataByUid(p.M_DwUin)
if !ok {
return
}
p.PlayerBaseMod = Base
p.M_DwUin = Base.Data.DwUin
// 玩家模块数据
modData := &PlayerModData{PlayerData: NewPlayerData("PlayerModData", p)}
ok = modData.LoadDataFromDB(Base.Data.DwUin)
if !ok {
return
}
modData.InitMod(p)
p.PlayMod.mod_list = modData.ModList
}
// 获取玩家简单数据
func (p *Player) GetSimpleData(Uid int, simple *PlayerSimpleData) error {
p.M_DwUin = int64(Uid)
p.InitPlayerOnly()
Base := p.GetPlayerBaseMod()
if Base == nil {
return errors.New("GetSimpleData failed")
}
simple.Name = p.PlayMod.getBaseMod().NickName
simple.Avatar = p.PlayMod.getAvatarMod().SetId
simple.Face = p.PlayMod.getFaceMod().SetId
simple.Level = p.GetPlayerBaseMod().GetLevel()
simple.Decorate = p.PlayMod.getDecorateMod().DecorateNum
simple.Login = int64(Base.Data.LoginTime)
simple.Star = p.GetPlayerBaseMod().GetStar()
simple.Loginout = int64(Base.Data.LogoutTime)
simple.FaceBook = Base.Data.FaceBookId
simple.FaceBookPic = p.PlayMod.getBaseMod().FacebookUrl
simple.Playroom = p.PlayMod.getPlayroomMod().Room
simple.Chess = p.PlayMod.getChessMod().GetUnlockChessList()
simple.WorkStart = p.PlayMod.getPlayroomMod().Starttime
simple.Chip = p.PlayMod.getPlayroomMod().GetChip()
simple.PetName = p.PlayMod.getBaseMod().PetName
simple.Emoji = p.PlayMod.getEmojiMod().Set
return nil
}
func (p *Player) UpdateUserInfo() {
simple := &PlayerSimpleData{}
Base := p.GetPlayerBaseMod()
CardMod := p.PlayMod.getCardMod()
BaseMod := p.PlayMod.getBaseMod()
simple.Name = p.PlayMod.getBaseMod().NickName
simple.Avatar = p.PlayMod.getAvatarMod().SetId
simple.Uid = int(p.M_DwUin)
simple.Star = p.GetPlayerBaseMod().GetStar()
simple.Face = p.PlayMod.getFaceMod().SetId
simple.Level = p.GetPlayerBaseMod().GetLevel()
simple.Decorate = p.PlayMod.getDecorateMod().DecorateNum
simple.Login = int64(BaseMod.LoginTime)
simple.Loginout = int64(BaseMod.LogoutTime)
simple.FaceBook = Base.Data.FaceBookId
simple.FaceBookPic = p.PlayMod.getBaseMod().FacebookUrl
simple.Playroom = p.PlayMod.getPlayroomMod().Room
simple.Chess = p.PlayMod.getChessMod().GetUnlockChessList()
simple.WorkStart = p.PlayMod.getPlayroomMod().Starttime
simple.Chip = p.PlayMod.getPlayroomMod().GetChip()
simple.PetName = p.PlayMod.getBaseMod().PetName
simple.Emoji = p.PlayMod.getEmojiMod().Set
simple.Friend = p.PlayMod.getFriendMod().GetSimpleFriendList()
simple.Upvote = p.PlayMod.getPlayroomMod().Upvote
simple.DressSet = p.PlayMod.getPlayroomMod().DressSet
simple.CardInfo = CardMod.GetCardList()
simple.ActLog = p.PlayMod.getFriendMod().GetActLogLast()
simple.Physiology = p.PlayMod.getPlayroomMod().GetPhysiologyList()
simple.Lang = int(p.PlayMod.getBaseMod().Lang)
simple.Account = p.PlayMod.getBaseMod().Account
simple.PetFur = p.PlayMod.getFurMod().GetFurSet()
simple.MaxCharge = p.PlayMod.getChargeMod().GetMaxCharge()
simple.AdWatch = p.PlayMod.getChargeMod().GetAdWatch()
//TODO 存储到redis 在新版本中将优化成gob进行压缩
value, _ := json.Marshal(simple)
IdStr := GoUtil.String(p.M_DwUin)
go db.RedisSetKeyBytes(IdStr, value, 0)
}
func (p *Player) HandleInUserRank() {
DecorateMod := p.PlayMod.getDecorateMod()
Score := float64(DecorateMod.GetDecorateNum())
BaseMod := p.PlayMod.getBaseMod()
Score += float64(BaseMod.GetLevel()) * 1000000 // 等级加成
// 更新排行榜
m := &MsgMod.Msg{
Type: MsgMod.HANDLE_TYPE_RANK,
SendT: GoUtil.Now(),
Extra: RankMsg{
Uid: int(p.M_DwUin),
Score: float64(Score),
RankType: RANK_TYPE_USER,
Extra: map[string]interface{}{
"country": p.PlayMod.getBaseMod().CountryCode,
},
},
}
G_GameLogicPtr.RankMgrSend(m)
}
func (p *Player) HandleInChampshipRank() {
ChampshipMod := p.PlayMod.getChampshipMod()
Score := float64(ChampshipMod.GetScore())
if Score <= 0 {
return
}
// 更新排行榜
m := &MsgMod.Msg{
Type: MsgMod.HANDLE_TYPE_CHAMPSHIP_INRANK,
SendT: GoUtil.Now(),
Extra: CRank{
Uid: int(p.M_DwUin),
Score: Score,
H: ChampshipMod.GetH(),
N: ChampshipMod.GetN(),
},
End: GoUtil.ZeroTimestamp() + 86400, // 第二天零点删除
HandleType: MsgMod.HANDLE_MDO_CHAMPSHIP_INRANK,
}
SendMsgToCenterAsync(m)
}
func (p *Player) AddLog(Uid int, Type int, Param string, Time int64) {
FriendMod := p.PlayMod.getFriendMod()
Id := FriendMod.AddLog(Uid, Type, Param)
p.PlayMod.save()
p.PushClientRes(&msg.NotifyFriendLog{
Info: &msg.ResFriendLog{
Player: G_GameLogicPtr.GetResSimplePlayerByUid(Uid),
Type: int32(Type),
Param: Param,
Id: int32(Id),
Time: int32(Time),
},
Bubble: FriendMod.GetBubble(Id),
})
}
func (p *Player) TeLog(Type string, Param map[string]interface{}) {
agent := p.GetAgent()
if Param == nil {
Param = make(map[string]interface{})
}
if agent != nil && Param != nil {
Param["Ip"] = agent.RemoteAddr().String()
}
//Param["#zone_offset"] = -5
// 游戏内TE日志
BaseMod := p.PlayMod.getBaseMod()
UidStr := GoUtil.String(p.M_DwUin)
go telog.Te.Track(BaseMod.Account, UidStr, Type, Param)
//途游GA
go ga.GAlogEvent(Type, BaseMod.Account, "", Param)
}
// 初始化活动
func (p *Player) InitActivity() {
p.activity = make(map[int]*ActivityInfo)
ActivityList := activityCfg.GetActivityList()
Level := p.GetPlayerBaseMod().GetLevel()
ActivityMod := p.PlayMod.getActivityMod()
now := GoUtil.Now()
var startduration int64
var minduration int64
var endduration int64
for _, v := range ActivityList {
if v.Level > Level {
continue
}
Status := ActivityMod.GetActivityStatus(v)
if Status == 0 {
continue
}
startduration = v.StartTime - now
endduration = v.EndTime - now + 1
if startduration > 0 && (minduration == 0 || minduration > startduration) {
minduration = startduration
}
if endduration > 0 && (minduration == 0 || minduration > endduration) {
minduration = endduration
}
if v.StartTime > now || v.EndTime < now {
continue
}
p.activity[v.Id] = &ActivityInfo{
StartT: v.StartTime,
EndT: v.EndTime,
Id: v.Id,
Type: v.Type,
Status: Status,
Title: v.Title,
}
}
if minduration > 0 {
p.CallEvent(time.Duration(minduration)*time.Second, p.TickActivity, "init_activity")
}
p.TeLog("activity_ids", map[string]interface{}{
"info": p.activity,
})
p.ActivityLogin()
}
func (p *Player) TickActivity() {
p.lock.Lock()
defer p.lock.Unlock()
p.InitActivity()
p.ActivityZeroUpdate()
p.BackDataActivity()
p.PushClientRes(p.GetMailMod().BackData())
p.SendClientRes()
}
func (p *Player) BackDataActivity() {
ResActivityList := make([]*msg.ActivityInfo, 0)
for _, v := range p.activity {
Red := p.GetRed(v)
ResActivityList = append(ResActivityList, &msg.ActivityInfo{
Id: int32(v.Id),
Type: int32(v.Type),
StartTime: int32(v.StartT),
EndTime: int32(v.EndT),
Status: int32(v.Status),
Title: v.Title,
Red: int32(Red),
})
}
p.PushClientRes(&msg.ResActivity{
ActiveList: ResActivityList,
})
}
func (p *Player) GetRed(AI *ActivityInfo) int {
Status := p.GetActivityStatus(AI.Type)
if Status != ACT_STATUS_START {
return 0
}
// 限时活动红点
if AI.Type == activity.ACT_TYPE_MINING {
ItemId := miningCfg.GetActivityItemId(AI.Id)
return p.PlayMod.getItemMod().GetItem(ItemId)
}
if AI.Type == activity.ACT_TYPE_GUESS_COLOR {
ItemId := guesscolorCfg.GetActivityItemId(AI.Id)
return p.PlayMod.getItemMod().GetItem(ItemId)
}
return 0
}
func (p *Player) NotifyRed(actType int) {
ActivityInfo := p.GetActivityInfo(actType)
Status := p.GetActivityStatus(actType)
if Status != ACT_STATUS_START {
return
}
if ActivityInfo == nil {
return
}
Red := p.GetRed(ActivityInfo)
p.PushClientRes(&msg.NotifyActRed{
Id: int32(ActivityInfo.Id),
Red: int32(Red),
})
}
func (p *Player) AddCard(Id int) {
CardMod := p.PlayMod.getCardMod()
CardMod.AddCard(Id)
p.TeLog("asset_change", map[string]interface{}{
"item_id": Id,
"change_type": "gain",
"change_num": 1,
"change_after": CardMod.CardList[Id],
"change_reason": "exchange_card",
})
}
func (p *Player) SubCard(Id int) error {
CardMod := p.PlayMod.getCardMod()
err := CardMod.SubCard(Id)
if err != nil {
return err
}
p.TeLog("asset_change", map[string]interface{}{
"item_id": Id,
"change_type": "gain",
"change_num": 1,
"change_after": CardMod.CardList[Id],
"change_reason": "exchange_card",
})
return nil
}
func (p *Player) GetIp() string {
if p.GetAgent() == nil {
return ""
}
return p.GetAgent().RemoteAddr().String()
}
// TODO func_exec_add 需要优化成令牌桶算法,目前的实现可能存在性能问题
func (p *Player) func_exec_add() error {
now := time.Now().Unix()
// 如果是新的一秒,重置计数
if now != int64(p.func_time) {
p.func_time = int(now)
p.args["func_exec_count"] = 1
return nil
}
// 获取当前秒内的调用次数
count := 0
if v, ok := p.args["func_exec_count"]; ok {
count = GoUtil.Int(v)
}
// 检查是否超过限制
if count >= 20 {
return errors.New("func_exec_add: call limit exceeded (20 times per second)")
}
// 增加计数
p.args["func_exec_count"] = count + 1
return nil
}
func (p *Player) DispatcherHandle() {
p.dispatcherWg.Add(1)
go func() {
defer p.dispatcherWg.Done()
var cb *timer.Timer
for {
select {
case <-p.stopSignal:
return
case cb = <-p.MDispatr.ChanTimer:
if cb != nil {
cb.Cb()
} else {
log.Debug("Timer callback or Timer is nil")
}
case msg := <-p.msgChan:
if msg != nil {
p.wg.Done()
now := time.Now()
// 直接在当前 goroutine 中处理,避免创建过多 goroutine
p.HandleMsg(msg.Clone())
log.Debug("player %d recive msg %v;handle time %v", p.M_DwUin, msg, time.Since(now))
}
}
}
}()
}
func CheckPlayerLose(Uid int) bool {
FriendSimpleData := G_GameLogicPtr.GetSimplePlayerByUid(Uid)
if FriendSimpleData == nil {
return true
}
now := GoUtil.Now()
if now-FriendSimpleData.Loginout > sevendays {
return true
}
return false
}
func (p *Player) Lock() {
p.lock.Lock()
}
func (p *Player) UnLock() {
p.lock.Unlock()
}
func (p *Player) FixPlayroomPyhical() {
if p.GetBaseMod().GetLevel() >= playroomCfg.GetUnLockLv() {
PlayroomMod := p.PlayMod.getPlayroomMod()
if len(PlayroomMod.GetPhysiologyList()) != len(playroomCfg.GetPhysiologyTypeList()) {
PlayroomMod.Physiology = make(map[int]*playroom.Physiology)
PlayroomMod.UnLock(p.GetBaseMod().GetLevel())
}
}
}
func (p *Player) GetOrderFactor() int {
return orderCfg.GetOrderFactor(p.GetDecorateMod().AreaId)
}