1261 lines
34 KiB
Go
1261 lines
34 KiB
Go
package game
|
||
|
||
import (
|
||
"context"
|
||
"database/sql"
|
||
"encoding/json"
|
||
"errors"
|
||
"math"
|
||
"server/conf"
|
||
activityCfg "server/conf/activity"
|
||
cardCfg "server/conf/card"
|
||
chargeCfg "server/conf/charge"
|
||
guesscolorCfg "server/conf/guess_color"
|
||
itemCfg "server/conf/item"
|
||
limitedTimeEventCfg "server/conf/limited_time_event"
|
||
mergeDataCfg "server/conf/merge_data"
|
||
miningCfg "server/conf/mining"
|
||
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
|
||
func_time int
|
||
}
|
||
|
||
type PlayerBackUp struct {
|
||
Data msg.ResPlayerBaseInfo
|
||
PlayMod []byte
|
||
}
|
||
|
||
type PlayerMsg struct {
|
||
F string
|
||
B []byte
|
||
}
|
||
|
||
func (p *Player) Stop() {
|
||
select {
|
||
case <-p.stopSignal:
|
||
// 通道已经关闭
|
||
return
|
||
default:
|
||
p.wg.Wait()
|
||
close(p.stopSignal)
|
||
close(p.msgChan)
|
||
}
|
||
p.McronSave.Stop()
|
||
p.stop = true
|
||
}
|
||
|
||
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)
|
||
Base := &PlayerBaseData{p: p}
|
||
|
||
// 玩家基础数据
|
||
ok := Base.LoadDataFromDB(UserName)
|
||
if !ok {
|
||
log.Debug("load PlayerBaseData failed:", 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:", 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.initAcitivity()
|
||
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.getDailyTaskMod().ZeroUpdate(p.GetPlayerBaseMod().GetLevel(), p.PlayMod.getDecorateMod().GetAreaId())
|
||
p.PushClientRes(p.PlayMod.getDailyTaskMod().BackData())
|
||
|
||
// 能量商店
|
||
p.PlayMod.getBaseMod().ZeroUpdate()
|
||
p.PushClientRes(p.PlayMod.getBaseMod().BackData())
|
||
|
||
// 七日签到
|
||
p.PlayMod.getSevenLoginMod().ZeroUpdate(PlayerBaseMod.GetSevenLoginAdd(), PlayerBaseMod.GetLastLoginTime())
|
||
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.initAcitivity()
|
||
p.ActivityZeroUpdate()
|
||
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.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_MDO_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)
|
||
}
|
||
|
||
}
|
||
|
||
// 重新连接
|
||
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 {
|
||
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 len(itemList) == 0 {
|
||
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()
|
||
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()
|
||
}
|
||
}
|
||
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,
|
||
})
|
||
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)
|
||
|
||
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()
|
||
|
||
//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,
|
||
},
|
||
}
|
||
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) initAcitivity() {
|
||
p.activity = make(map[int]*ActivityInfo)
|
||
ActivityList := activityCfg.GetActivityList()
|
||
Level := p.GetPlayerBaseMod().GetLevel()
|
||
ActivityMod := p.PlayMod.getActivityMod()
|
||
for _, v := range ActivityList {
|
||
if v.Level > Level {
|
||
continue
|
||
}
|
||
Status := ActivityMod.GetActivityStatus(v)
|
||
if Status == 0 {
|
||
continue
|
||
}
|
||
p.activity[v.Id] = &ActivityInfo{
|
||
StartT: v.StartTime,
|
||
EndT: v.EndTime,
|
||
Id: v.Id,
|
||
Type: v.Type,
|
||
Status: Status,
|
||
Title: v.Title,
|
||
}
|
||
}
|
||
}
|
||
|
||
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() {
|
||
go func() {
|
||
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 > 7*24*3600 {
|
||
return true
|
||
}
|
||
return false
|
||
}
|