983 lines
26 KiB
Go
983 lines
26 KiB
Go
package game
|
|
|
|
import (
|
|
// "server/GoUtil"
|
|
// "server/MergeConst"
|
|
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"errors"
|
|
"math"
|
|
"server/GoUtil"
|
|
activityCfg "server/conf/activity"
|
|
cardCfg "server/conf/card"
|
|
guesscolorCfg "server/conf/guessColor"
|
|
itemCfg "server/conf/item"
|
|
mergeDataCfg "server/conf/mergeData"
|
|
miningCfg "server/conf/mining"
|
|
"server/db"
|
|
"server/game/mod/activity"
|
|
"server/game/mod/item"
|
|
"server/game/mod/limitedTimeEvent"
|
|
MsgMod "server/game/mod/msg"
|
|
"server/game/mod/playroom"
|
|
"server/game/mod/quest"
|
|
"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
|
|
}
|
|
|
|
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)
|
|
}
|
|
G_GameLogicPtr.AddLog(&Log{
|
|
Uid: p.M_DwUin,
|
|
EventName: "Login_Out",
|
|
})
|
|
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) {
|
|
if m == nil {
|
|
return
|
|
}
|
|
p.wg.Add(1)
|
|
p.msgChan <- m
|
|
}
|
|
|
|
func (p *Player) Call(m MsgMod.Msg) {
|
|
HandleMsg(p, &m)
|
|
}
|
|
|
|
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()
|
|
IsMailBack := false
|
|
for _, tr := range p.Trigger {
|
|
if DailyTaskMod.Trigger(tr) {
|
|
IsDailyBack = true
|
|
}
|
|
if p.MailTrigger(tr) {
|
|
IsMailBack = true
|
|
}
|
|
}
|
|
|
|
if IsDailyBack {
|
|
p.PushClientRes(DailyTaskMod.BackData())
|
|
}
|
|
if IsMailBack {
|
|
p.PushClientRes(MailMod.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
|
|
|
|
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()
|
|
log.Debug("player %d recive msg %v", p.M_DwUin, msg)
|
|
go HandleMsg(p, msg)
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
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.LoginBackData()
|
|
// GoUtil.RegisterEvent(MergeConst.Notify_Daily_Renew, p.ZeroUpdate, p)
|
|
// GoUtil.RegisterEvent(MergeConst.Notify_Midday_Renew, p.ZeroUpdate, p)
|
|
SyncFriendMsg(p)
|
|
p.UpdateUserInfo()
|
|
return nil
|
|
}
|
|
|
|
func (p *Player) Test() {
|
|
p.PlayMod.getBaseMod().EnergyMul = 100
|
|
}
|
|
|
|
// 零点更新
|
|
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{})
|
|
//卡牌
|
|
p.PlayMod.getCardMod().ZeroUpdate()
|
|
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()
|
|
p.PlayMod.getChargeMod().ZeroUpdate(ChessMod.GetEmitList())
|
|
p.PushClientRes(p.PlayMod.getChargeMod().BackData())
|
|
|
|
// 无尽礼包
|
|
p.PlayMod.getEndlessMod().ZeroUpdate(p.PlayMod.getChargeMod().GetMaxCharge())
|
|
p.PushClientRes(p.PlayMod.getEndlessMod().BackData())
|
|
|
|
// 宠物宝箱
|
|
p.PlayMod.getFriendTreasureMod().ZeroUpdate()
|
|
// p.PushClientRes(p.PlayMod.getFriendTreasureMod().BackData())
|
|
|
|
// playroom
|
|
PlayroomMod := p.PlayMod.getPlayroomMod()
|
|
PlayroomMod.ZeroUpdate()
|
|
PlayroomBackData(p)
|
|
p.PlayMod.getChampshipMod().ZeroUpdate()
|
|
p.initAcitivity()
|
|
ActivityZeroUpdate(p)
|
|
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.PushClientRes(p.PlayMod.getChargeMod().BackData())
|
|
p.PlayMod.save()
|
|
}
|
|
|
|
}
|
|
|
|
func (p *Player) Login() {
|
|
// 添加定时器
|
|
// 限时事件触发
|
|
LimitedTimeEventTrigger(p, 0)
|
|
// 猪猪银行触发
|
|
LimitedTimePiggyBankTrigger(p)
|
|
BaseMod := p.PlayMod.getBaseMod()
|
|
FaceMod := p.PlayMod.getFaceMod()
|
|
AvatarMod := p.PlayMod.getAvatarMod()
|
|
PlayBaseMod := p.GetPlayerBaseMod()
|
|
// playroom触发
|
|
PlayroomMod := p.PlayMod.getPlayroomMod()
|
|
PlayroomMod.UnLock(BaseMod.GetLevel())
|
|
LimitedTimePlayroomTrigger(p) // playroom数值变化
|
|
LimitedTimePlayroomWorkTrigger(p) // playroom打工
|
|
LimitedTimeEnergyAdd(p) // 能量定时处理
|
|
ActivityLogin(p) // 活动登录
|
|
LoignBack(p) // 登录返回数据
|
|
SyncMailMsg(p) // 同步邮件
|
|
BaseMod.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())
|
|
}
|
|
|
|
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()
|
|
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
|
|
}
|
|
p.PlayerBaseMod.ClearData()
|
|
p.PlayMod.ClearData(p)
|
|
tx.Commit()
|
|
p.Stop()
|
|
G_GameLogicPtr.DelPlayer(p)
|
|
}
|
|
|
|
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)
|
|
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
|
|
}
|
|
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()
|
|
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_LIMIED_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]),
|
|
})
|
|
// 触发订单事件 生成超级订单 卡牌节
|
|
LimitedTimeEventTrigger(p, EffectList[0])
|
|
p.TeLog("time_limited_event_enable", map[string]interface{}{
|
|
"event_type": EffectList[0],
|
|
"enable_type": Label,
|
|
})
|
|
case item.ITEM_TYPE_PIGGY_BANK: // 猪猪银行
|
|
PiggyBankMod := p.PlayMod.getPiggyBankMod()
|
|
Effect := itemCfg.GetItemEffect(v.Id)
|
|
PiggyBankMod.AddPiggyBank(Effect)
|
|
LimitedTimePiggyBankTrigger(p)
|
|
p.PushClientRes(PiggyBankMod.BackData())
|
|
p.TeLog("piggy_bank_income", map[string]interface{}{
|
|
"piggy_bank_id": 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,
|
|
})
|
|
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,
|
|
})
|
|
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,
|
|
})
|
|
BackDataType[item.ITEM_TYPE_FACE] = struct{}{}
|
|
case item.ITEM_TYPE_ACTIVITY_RACE: // 活动竞速
|
|
ActivityInfo := GetActivityInfo(p, activity.ACT_TYPE_RACE)
|
|
if ActivityInfo == nil {
|
|
continue
|
|
}
|
|
RaceMod := p.PlayMod.getRaceMod()
|
|
RaceMod.AddCoin(v.Num)
|
|
RaceBackData(p)
|
|
case item.ITEM_TYPE_PLAYROOM_VISIT: // 拜访玩家
|
|
Target := GetVisitorPlayer(p)
|
|
playroomMod := p.PlayMod.getPlayroomMod()
|
|
playroomMod.Target = Target
|
|
playroomMod.Status = playroom.STATUS_VISIT
|
|
// PlayroomVisit(p, Target)
|
|
PlayroomBackData(p)
|
|
default:
|
|
err := ItemMod.AddItem(v.Id, v.Num)
|
|
p.TeLog("item_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 = v.(int)
|
|
}
|
|
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:
|
|
case item.ITEM_TYPE_EMOJI:
|
|
case item.ITEM_TYPE_FACE:
|
|
BackUserInfo(p)
|
|
}
|
|
}
|
|
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() {
|
|
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.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.BackData())
|
|
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.BackDataActivity()
|
|
BackChampship(p)
|
|
BackUserInfo(p)
|
|
}
|
|
|
|
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()
|
|
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()
|
|
value, _ := json.Marshal(simple)
|
|
IdStr := strconv.Itoa(int(p.M_DwUin))
|
|
db.RedisSetKey(IdStr, string(value), 0)
|
|
}
|
|
|
|
func (p *Player) HandleInUserRank() {
|
|
DecorateMod := p.PlayMod.getDecorateMod()
|
|
Score := DecorateMod.GetDecorateNum()
|
|
// 更新排行榜
|
|
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(),
|
|
},
|
|
}
|
|
G_GameLogicPtr.ChampshipMgrSend(m)
|
|
}
|
|
|
|
func (p *Player) AddLog(Uid int, Type int, Param string) {
|
|
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(GoUtil.Now()),
|
|
},
|
|
})
|
|
}
|
|
|
|
func (p *Player) TeLog(Type string, Param map[string]interface{}) {
|
|
G_GameLogicPtr.AddLog(&Log{
|
|
Uid: p.M_DwUin,
|
|
EventName: Type,
|
|
Param: Param,
|
|
})
|
|
agent := p.GetAgent()
|
|
if agent != nil {
|
|
Param["Ip"] = agent.RemoteAddr().String()
|
|
}
|
|
telog.Te.Track(p.GetPlayerBaseMod().GetName(), p.GetPlayerBaseMod().GetName(), Type, Param)
|
|
}
|
|
|
|
func (p *Player) Kafka(Type string, Param map[string]interface{}) {
|
|
G_GameLogicPtr.AddLog(&Log{
|
|
Uid: p.M_DwUin,
|
|
EventName: Type,
|
|
Param: 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 := GetActivityStatus(p, AI.Type)
|
|
if Status != ACT_STATUS_START {
|
|
return 0
|
|
}
|
|
// 限时活动红点
|
|
if AI.Type == ACT_TYPE_MINING {
|
|
ItemId := miningCfg.GetActivityItemId(AI.Id)
|
|
return p.PlayMod.getItemMod().GetItem(ItemId)
|
|
}
|
|
if AI.Type == ACT_TYPE_GUESS_COLOR {
|
|
ItemId := guesscolorCfg.GetActivityItemId(AI.Id)
|
|
return p.PlayMod.getItemMod().GetItem(ItemId)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (p *Player) NotifyRed(actType int) {
|
|
ActivityInfo := GetActivityInfo(p, actType)
|
|
Status := GetActivityStatus(p, 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
|
|
}
|