package game

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"fmt"
	"os"
	"server/MergeConst"
	"server/conf"
	userCfg "server/conf/user"
	GoUtil "server/game_util"
	"strconv"
	"sync"

	l "log"
	"server/db"
	"server/game/internal"

	MsgMod "server/game/mod/msg"
	"server/msg"
	"time"

	"github.com/robfig/cron/v3"

	"google.golang.org/protobuf/proto"

	"server/pkg/github.com/name5566/leaf/gate"
	"server/pkg/github.com/name5566/leaf/log"
	"server/pkg/github.com/name5566/leaf/timer"
)

var (
	G_GameLogicPtr *GameLogic
)

var isInitGameLogic = false
var RegisterNetWorkFunc = make(map[string]interface{})

const (
	SERVER_STATUS_OPEN     = 1 // 服务器状态 开放
	SERVER_STATUS_CLOSE    = 2 // 服务器状态 关闭
	SERVER_STATUS_MAINTAIN = 3 // 服务器状态 维护
	SERVER_STATUS_FULL     = 4 // 服务器状态 爆满
)

func RegisterMsgProcessFunc(key string, value1 interface{}) {
	RegisterNetWorkFunc[key] = value1
}

func RunNetProcessByKey(key string, param []interface{}) error {
	fun, ok := RegisterNetWorkFunc[key]
	if ok {
		_, player, buf := ParseArgs(param)
		err := fun.(func(*Player, []byte) error)(player, buf)
		return err
	}
	return fmt.Errorf("cant find network func %s", key)
}

type LimitActPeriod struct {
	StartCronID cron.EntryID
	EndTimer    *timer.Timer
	StartTime   int32
	EndTime     int32
}

type GameLogic struct {
	Db_AccountInfo     db.Db_Account
	DailyTaskTimestamp int64
	M_Players          sync.Map
	m_CronEntryIDs     map[int]*LimitActPeriod
	Mdispatr           *timer.Dispatcher
	M_LimitActiveList  []int
	NotInitPlayer      *Player
	Version            int32
	M_SvrGlobal        db.SqlSvrGlobalStruct
	SeverInfo          *ServerInfo

	FriendMgr    *FriendMgr    // 好友管理器
	RankMgr      *RankMgr      // 排行榜管理器
	MailMgr      *MailMgr      // 邮件管理器
	ChampshipMgr *ChampshipMgr // 锦标赛管理器
	VarMgr       *VarMgr       // 变量管理器
	StartTime    int64         // 服务器启动时间
	MessageMgr   *MessageMgr   // 消息管理器
}

type ServerInfo struct {
	ServerID int    // 服务器ID
	CenterID int    // 中心ID
	GroupID  int    // 组ID
	OpenTime int64  // 开服时间
	Name     string // 服务器名字
	Status   int    // 服务器状态
}

// 零点更新
func (gl *GameLogic) ZeroFlush() {
	gl.Mdispatr.AfterFunc(time.Second*86400, func() {
		gl.ZeroFlush()
	})
	var a1 = []interface{}{gl.DailyTaskTimestamp}
	GoUtil.CallEvent(MergeConst.Notify_Daily_Renew, a1)
	gl.NotifyAll(MsgMod.MSG_ZERO_UPDATE)
	gl.CreateDailyLogFile()
	log.Debug("Server ZeroFlush")
}

// 中午更新
func (gl *GameLogic) NoonFlush() {
	log.Debug("Server NoonFlush")
	gl.Mdispatr.AfterFunc(time.Second*86400, func() {
		gl.NoonFlush()
	})
	gl.NotifyAll(MsgMod.MSG_NOON_UPDATE)
}

func (gl *GameLogic) SetPlayer(player *Player) {
	gl.M_Players.Store(player.M_DwUin, player)
}

func (gl *GameLogic) DelPlayer(player *Player) {
	gl.M_Players.Delete(player.M_DwUin)
}

func (gl *GameLogic) GetPlayer(DwUin int64) *Player {
	if v, ok := gl.M_Players.Load(DwUin); ok {
		return v.(*Player)
	}
	return nil
}

func (gl *GameLogic) OpenTimestampTick() {
	gl.DailyTaskTimestamp = 0
	gl.Mdispatr = timer.NewDispatcher(0)
	gl.Mdispatr.AfterFunc(time.Second*time.Duration(GoUtil.NextZeroTimestampDuration()), func() {
		gl.ZeroFlush()
	})
	gl.Mdispatr.AfterFunc(time.Second*time.Duration(GoUtil.NextNoonTimestampDuration()), func() {
		gl.NoonFlush()
	})
	//gl.CreateDailyLogFile()
	go func() {
		for k := range gl.Mdispatr.ChanTimer {
			k.Cb()
		}
	}()
}

func (ad *GameLogic) IsExsitAccount(UserName string) bool {
	return ad.LoadDataFromDB(UserName)
}

func (ad *GameLogic) LoadDataFromDB(UserName string) bool {
	sqlStr := "SELECT * FROM t_account WHERE user_name = ?"
	if err := db.SqlDb.Get(&ad.Db_AccountInfo, sqlStr, UserName); err != nil {
		// log.Debug("get data failed, err:%v\n", err)
		return false
	}

	return true
}

func (ad *GameLogic) NewAccountInsertDataToDB() bool {
	sqlStr := "INSERT INTO t_account(user_name, user_password) VALUES(:user_name, :user_password)"
	result, err := db.SqlDb.NamedExec(sqlStr, map[string]interface{}{
		"user_name":     ad.Db_AccountInfo.UserName,
		"user_password": ad.Db_AccountInfo.UserPassword,
	})
	if err != nil {
		log.Debug("named exec failed, err:%v\n", err)
		return false
	}
	insertId, err := result.LastInsertId()
	if err != nil {
		log.Debug("get last insert id failed, err:%v\n", err)
		return false
	}

	insertId = insertId + int64(100000) + int64(conf.Server.AppID*100000000)
	playerInfo := &db.ResPlayerBaseInfo{}
	playerInfo.DwUin = int64(insertId)
	playerInfo.Energy = int32(userCfg.GetInitEnergy())
	playerInfo.Star = int32(userCfg.GetInitStar())
	playerInfo.RecoverTime = int32(time.Now().Unix())
	playerInfo.Diamond = int32(userCfg.GetInitDiamond())
	playerInfo.Level = 1
	playerInfo.Exp = 0
	playerInfo.StartOrderId = "1"
	playerInfo.MusicCode = 1
	playerInfo.Guild = 1
	playerInfo.PackUnlockCount = 5
	playerInfo.UserName = ad.Db_AccountInfo.UserName
	playerInfo.LoginTime = (int32)(time.Now().Unix())
	playerInfo.LogoutTime = 0
	playerInfo.Node = int32(conf.Server.ServerID)
	playerInfo.Rolecreatetime = (int32)(time.Now().Unix())
	playerInfo.FaceBookId = ""
	db.FormatAllMemInsertDb(playerInfo, "t_player_baseinfo")

	var buf bytes.Buffer
	encode := gob.NewEncoder(&buf)
	encode.Encode(&PlayerModList{})
	playerMod := &db.SqlModStruct{
		DwUin:      int64(insertId),
		ModData:    buf.Bytes(),
		UpdataTime: int32(time.Now().Unix()),
	}
	db.FormatAllMemInsertDb(playerMod, "t_player_mod")
	// 创建玩家日志
	player := new(Player)
	BaseMod := player.PlayMod.getBaseMod()
	BaseMod.Account = ad.Db_AccountInfo.UserName
	player.TeLog("register", nil)

	return true
}

func (ad *GameLogic) PackLoginResInfo(a gate.Agent, ResLogin *msg.ResLogin) {
	resBuff, _ := proto.Marshal(ResLogin)
	ad.PackResInfo(a, "ResLogin", resBuff)
}

func (ad *GameLogic) PackResInfo(a gate.Agent, Func string, data []byte) {
	if a == nil {
		return
	}
	response := &msg.ClientRes{}
	response.Func = Func
	response.Cid = "cid"
	response.Info = data
	a.WriteMsg(response)
}

// 创建新玩家，初始化数据
func (ad *GameLogic) CreateNewPlayer(a gate.Agent, UserName string) *Player {
	player := new(Player)
	internal.AsignPlayerToAgents(a, player) //绑定player和网络连接代理
	player.agent = a
	err := player.InitPlayer(UserName)
	if err != nil {
		data, _ := proto.Marshal(&msg.ResLogin{ResultCode: MergeConst.Protocol_Error_Account_Fail})
		G_GameLogicPtr.PackResInfo(a, "ResLogin", data)
		panic(err)
	}
	ad.SetPlayer(player)
	return player
}

func (ad *GameLogic) GetPlayerByAgent(gate gate.Agent) *Player {
	p, ok := internal.Agents.Load(gate)
	if ok {
		return p.(*Player)
	}
	return nil
}

// 好友管理器
func (ad *GameLogic) CreateFriendMgr() {
	ad.FriendMgr = &FriendMgr{
		ServerMod: new(ServerMod),
	}
	ad.FriendMgr.Init()
}

// 排行榜管理器
func (ad *GameLogic) CreateRankMgr() {
	ad.RankMgr = &RankMgr{
		ServerMod: new(ServerMod),
	}
	ad.RankMgr.Init()
}

func (ad *GameLogic) RankMgrSend(m *MsgMod.Msg) {
	ad.RankMgr.Send(m)
}

func (ad *GameLogic) RankMgrCall(m *MsgMod.Msg) interface{} {
	result, err := ad.RankMgr.Call(m)
	if err != nil {
		return nil
	}
	return result
}

// 邮件管理器
func (ad *GameLogic) CreateMailMgr() {
	ad.MailMgr = &MailMgr{
		ServerMod: new(ServerMod),
	}
	ad.MailMgr.Init()
}

func (ad *GameLogic) CreateMessageMgr() {
	ad.MessageMgr = &MessageMgr{
		ServerMod: new(ServerMod),
	}
	ad.MessageMgr.MessageMgrInit()
}

func (ad *GameLogic) MailMgrSend(m *MsgMod.Msg) {
	ad.MailMgr.Send(m)
}

func (ad *GameLogic) MailMgrCall(m *MsgMod.Msg) interface{} {
	result, err := ad.MailMgr.Call(m)
	if err != nil {
		return nil
	}
	return result
}

// 锦标赛管理器
func (ad *GameLogic) CreateChampshipMgr() {
	ad.ChampshipMgr = &ChampshipMgr{
		ServerMod: new(ServerMod),
	}
	ad.ChampshipMgr.Init()
}

func (ad *GameLogic) ChampshipMgrSend(m *MsgMod.Msg) {
	ad.ChampshipMgr.Send(m)
}

func (ad *GameLogic) ChampshipMgrCall(m *MsgMod.Msg) interface{} {
	result, err := ad.ChampshipMgr.Call(m)
	if err != nil {
		return nil
	}
	return result
}

// 变量管理器
func (ad *GameLogic) CreateVarMgr() {
	ad.VarMgr = &VarMgr{
		ServerMod: new(ServerMod),
	}
	ad.VarMgr.Init()
}

func (ad *GameLogic) VarMgrSend(m *MsgMod.Msg) {
	ad.VarMgr.Send(m)
}

func (ad *GameLogic) VarMgrCall(m *MsgMod.Msg) interface{} {
	result, err := ad.VarMgr.Call(m)
	if err != nil {
		return nil
	}
	return result
}

func (ad *GameLogic) GetSimplePlayerByUid(Id int) *PlayerSimpleData {
	if Id == 0 {
		return nil
	}
	Idstr := strconv.Itoa(Id)
	Value, _ := db.RedisGetKey(Idstr)
	player := &PlayerSimpleData{}
	player.Playroom = make(map[int]int)
	player.Uid = Id
	if Value == "" {
		p := new(Player)
		err := p.GetSimpleData(Id, player)
		if err != nil {
			return nil
		}
		value, _ := json.Marshal(player)
		db.RedisSetKey(Idstr, string(value), time.Duration(300)*time.Second)
	} else {
		err := json.Unmarshal([]byte(Value), player)
		if err != nil {
			return nil
		}
	}
	return player
}

func (ad *GameLogic) GetResSimplePlayerByUid(Id int) *msg.ResPlayerSimple {
	Idstr := strconv.Itoa(Id)
	Value, _ := db.RedisGetKey(Idstr)
	player := &PlayerSimpleData{}
	player.Uid = Id
	if Value == "" {
		p := new(Player)
		err := p.GetSimpleData(Id, player)
		if err != nil {
			return nil
		}
		value, _ := json.Marshal(player)
		db.RedisSetKey(Idstr, string(value), 0)
	} else {
		err := json.Unmarshal([]byte(Value), player)
		if err != nil {
			return nil
		}
	}

	return &msg.ResPlayerSimple{
		Uid:      int64(player.Uid),
		Name:     player.Name,
		Level:    int32(player.Level),
		Avatar:   int32(player.Avatar),
		Face:     int32(player.Face),
		Decorate: int32(player.Decorate),
		Login:    int32(player.Login),
		Loginout: int32(player.Loginout),
		Emoji:    GoUtil.MapIntToInt32(player.Emoji),
	}
}

func (ad *GameLogic) GetResFriendPlayerByUid(Id int) *msg.ResFriendPlayerSimple {
	Idstr := strconv.Itoa(Id)
	Value, _ := db.RedisGetKey(Idstr)
	player := &PlayerSimpleData{}
	player.Uid = Id
	if Value == "" {
		p := new(Player)
		err := p.GetSimpleData(Id, player)
		if err != nil {
			return nil
		}
		value, _ := json.Marshal(player)
		db.RedisSetKey(Idstr, string(value), 0)
	} else {
		err := json.Unmarshal([]byte(Value), player)
		if err != nil {
			return nil
		}
	}
	last := &msg.ActLog{}
	if player.ActLog != nil {
		last = &msg.ActLog{
			Type:  int32(player.ActLog.Type),
			Time:  player.ActLog.Time,
			Param: player.ActLog.Param,
		}
	}
	return &msg.ResFriendPlayerSimple{
		Uid:        int64(player.Uid),
		Name:       player.Name,
		Level:      int32(player.Level),
		Avatar:     int32(player.Avatar),
		Face:       int32(player.Face),
		Decorate:   int32(player.Decorate),
		Login:      int32(player.Login),
		Loginout:   int32(player.Loginout),
		Emoji:      GoUtil.MapIntToInt32(player.Emoji),
		Facebook:   player.FaceBook,
		Playroom:   GoUtil.MapIntToInt32(player.Playroom),
		DressSet:   GoUtil.MapIntToInt32(player.DressSet),
		Friend:     GoUtil.IntToInt32(player.Friend),
		Physiology: GoUtil.MapIntToInt32(player.Physiology),
		Last:       last,
		PetName:    player.PetName,
	}
}

// 初始化服务器协程
func G_getGameLogic() *GameLogic {
	if !isInitGameLogic {
		G_GameLogicPtr = new(GameLogic)
		isInitGameLogic = true
		G_GameLogicPtr.Mdispatr = timer.NewDispatcher(10)
		G_GameLogicPtr.InitServerInfo()
		G_GameLogicPtr.M_Players = sync.Map{}
		G_GameLogicPtr.NotInitPlayer = new(Player)
		G_GameLogicPtr.M_LimitActiveList = []int{}
		G_GameLogicPtr.CreateMessageMgr()    // 创建消息管理器
		G_GameLogicPtr.OpenTimestampTick()   // 开启时间戳计时器
		G_GameLogicPtr.RegisterEvent()       // 注册事件
		G_GameLogicPtr.RegisterNetWorkFunc() // 注册客户端接口
		G_GameLogicPtr.InitActivity()        // 初始化活动
		if conf.Server.ServerType == "center" {
			// G_GameLogicPtr.CreateFriendMgr()    //创建好友管理器
			G_GameLogicPtr.CreateChampshipMgr() // 创建竞标赛管理器
			G_GameLogicPtr.CreateVarMgr()       // 创建变量管理器
		}
		G_GameLogicPtr.CreateRankMgr() //创建排行榜管理器
		G_GameLogicPtr.CreateMailMgr() //创建邮件管理器
		ClusterMgrInit()               //初始化集群
		G_GameLogicPtr.StartTime = time.Now().Unix()
		// G_GameLogicPtr.CreateHttpManager()
	}
	return G_GameLogicPtr
}

func (ad *GameLogic) InitServerInfo() {
	Now := time.Now().Unix()
	ServerInfo := &ServerInfo{}
	ServerInfo.ServerID = conf.Server.ServerID
	ServerInfo.OpenTime = GoUtil.ParseTime(conf.Server.ServerOpenTime)
	ServerInfo.Name = conf.Server.ServerName
	if Now < ServerInfo.OpenTime {
		ServerInfo.Status = SERVER_STATUS_CLOSE
	} else {
		ServerInfo.Status = SERVER_STATUS_OPEN
	}
	ad.SeverInfo = ServerInfo
}

func (ad *GameLogic) SendServerVersion(a gate.Agent) {
	res := &msg.ResServerVersion{}
	res.Version = G_GameLogicPtr.Version
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(a, "ResServerVersion", data)
}

func (ad *GameLogic) ClearData(args []interface{}) {
	player := args[0].(*Player)
	if player != nil && player.M_DwUin != 0 {
		player.agent = nil
		log.Debug("player %d 断开连接", player.M_DwUin)
		player.CallEvent(120*time.Second, func() {
			player.lock.Lock()
			defer player.lock.Unlock()
			if player.agent == nil {
				player.ClearData()
				log.Debug("player %d 延迟120s关闭", player.M_DwUin)
			}
		}, "LateClose")
	}
}

func (ad *GameLogic) RegisterEvent() {

	GoUtil.RegisterEvent(MergeConst.Notify_Socket_Closed, ad.ClearData, nil)
	GoUtil.RegisterEvent(MergeConst.Notify_Socket_Connect, ad.NewPlayerConnect, nil)
}

func (ad *GameLogic) NewPlayerConnect(args []interface{}) {
	a := args[0].(gate.Agent)
	internal.AsignPlayerToAgents(a, ad.NotInitPlayer)
}

func (ad *GameLogic) ReplaceExistPlayerAndAgent(a gate.Agent, player *Player) error {
	if player == nil {
		return fmt.Errorf("player is nil")
	}
	player.lock.Lock()
	defer player.lock.Unlock()
	storePlayer := ad.GetPlayer(player.M_DwUin)
	if storePlayer == nil {
		return fmt.Errorf("player is delete")
	}
	if player.stop {
		return fmt.Errorf("player is stop")
	}
	agent := player.GetAgentByPlayer()
	notify := &msg.ForceKickOut{}
	data, _ := proto.Marshal(notify)
	if agent != nil && a != agent {
		G_getGameLogic().PackResInfo(agent, "ForceKickOut", data)
		internal.AsignPlayerToAgents(agent, ad.NotInitPlayer)
	}
	internal.AsignPlayerToAgents(a, player)
	player.SetAgent(a)
	// 取消延迟关闭
	Timer, ok := player.timerList["LateClose"]
	if ok {
		Timer.Stop()
	}
	log.Debug("player %d 重连", player.M_DwUin)
	return nil
}

func (ad *GameLogic) SendMassage(dwUin int64, Func string, data []byte) bool {
	player := ad.GetPlayer(dwUin)
	if player != nil {
		agent := player.GetAgentByPlayer()
		if agent != nil {
			G_getGameLogic().PackResInfo(agent, Func, data)
			return true
		}
	}
	return false
}

func (ad *GameLogic) FileExist(path string) bool {
	_, err := os.Lstat(path)
	return !os.IsNotExist(err)
}

func (ad *GameLogic) CreateDailyLogFile() {
	zero := GoUtil.ZeroTimestamp()
	now := time.Unix(zero, 0).Local()
	err := log.NewDailyLog(now, log.DEBUG_LEVEL, conf.Server.LogPath, l.LstdFlags)
	if err != nil {
		fmt.Println(err)
	}
	log.Debug("CreateDailyLogFile")
	ad.RemoveOldLogs(15)
}

func (ad *GameLogic) RemoveOldLogs(days int) {
	dir := conf.Server.LogPath
	files, err := os.ReadDir(dir)
	if err != nil {
		log.Debug("Failed to read log directory: %v", err)
		return
	}

	cutoff := time.Now().AddDate(0, 0, -days)
	for _, file := range files {
		if file.IsDir() {
			continue
		}
		fileInfo, err := file.Info()
		if err != nil {
			log.Debug("Failed to get file info: %v", err)
			continue
		}
		if fileInfo.ModTime().Before(cutoff) {
			err := os.Remove(dir + "/" + file.Name())
			if err != nil {
				log.Debug("Failed to remove old log file: %v", err)
			} else {
				log.Debug("Removed old log file: %s", file.Name())
			}
		}
	}
}

func (ad *GameLogic) RegisterNetWorkFunc() {

	RegisterMsgProcessFunc("ReqRemoveAd", ReqRemoveAdFunc)
	RegisterMsgProcessFunc("ReqPlayerBriefProfileData", ReqPlayerBriefProfileDataFunc)
	RegisterMsgProcessFunc("ReqFriendPlayerSimple", ReqFriendPlayerSimple)
	// RegisterMsgProcessFunc("ReqOfflineReconnect", ReqOfflineReconnectFunc)
	RegisterMsgProcessFunc("ReqPlayerAsset", ReqPlayerAsset)
	RegisterMsgProcessFunc("ReqId2Verify", ReqId2Verify) // 身份证验证
	// 玩家
	RegisterMsgProcessFunc("ReqUserInfo", ReqUserInfo)
	RegisterMsgProcessFunc("ReqSetName", ReqSetName)                       // 设置名字
	RegisterMsgProcessFunc("ReqLang", ReqLang)                             // 设置语言
	RegisterMsgProcessFunc("ReqSetPetName", ReqSetPetName)                 // 设置宠物名字
	RegisterMsgProcessFunc("ReqSetFacebookUrl", ReqSetFacebookUrl)         // 设置facebook地址
	RegisterMsgProcessFunc("ReqPlayerBaseInfo", ReqPlayerBaseInfofunction) // 请求玩家基本信息
	RegisterMsgProcessFunc("ReqKv", ReqKv)                                 // 保存客户端数据
	RegisterMsgProcessFunc("ReqGetEnergyByAD", ReqGetEnergyByAD)           // 看广告获取能量
	RegisterMsgProcessFunc("ReqBuyEnergy", ReqBuyEnergy)                   // 购买能量
	// #region 棋盘
	RegisterMsgProcessFunc("ReqPlayerChessData", ReqPlayerChessDataFunc)
	RegisterMsgProcessFunc("UpdatePlayerChessData", UpdatePlayerChessDataFunc) // 更新棋盘数据
	RegisterMsgProcessFunc("ReqSetEnergyMul", RegSetEneryFunc)                 //设置能量倍数
	RegisterMsgProcessFunc("ReqChessEx", ReqChessEx)                           // 转换棋子
	RegisterMsgProcessFunc("ReqGetChessFromBuff", ReqGetChessFromBuff)         // 从buff中获取棋子
	RegisterMsgProcessFunc("ReqPutPartInBag", ReqPutPartInBag)                 // 把零件放入背包
	RegisterMsgProcessFunc("ReqPutChessInBag", ReqPutChessInBag)               // 把棋子放入背包
	RegisterMsgProcessFunc("ReqTakeChessOutBag", ReqTakeChessOutBag)           // 从背包中取出棋子
	RegisterMsgProcessFunc("ReqBuyChessBagGrid", ReqBuyChessBagGrid)           // 解锁背包格子
	RegisterMsgProcessFunc("ReqSourceChest", ReqSourceChest)                   // 开宝箱
	RegisterMsgProcessFunc("ReqSeparateChess", ReqSeparateChess)               // 分解棋子
	RegisterMsgProcessFunc("ReqUpgradeChess", ReqUpgradeChess)                 // 升级棋子
	RegisterMsgProcessFunc("ReqSellChessNum", ReqSellChessNum)                 //购买能量
	RegisterMsgProcessFunc("ReqGetChessRetireReward", ReqGetChessRetireReward) //领取棋子退役奖励

	//领取图鉴奖励
	RegisterMsgProcessFunc("ReqGetHandbookReward", ReqGetHandbookReward) //领取图鉴奖励
	RegisterMsgProcessFunc("RegHandbookAllReward", RegHandbookAllReward) //领取图鉴收集奖励
	//领取订单奖励
	RegisterMsgProcessFunc("ReqRewardOrder", ReqRewardOrder)       // 领取订单奖励
	RegisterMsgProcessFunc("ReqDelOrder", ReqDelOrder)             // 删除订单
	RegisterMsgProcessFunc("ReqCreatePetOrder", ReqCreatePetOrder) // 生成消耗品订单

	//装饰
	RegisterMsgProcessFunc("ReqDecorate", ReqDecorate)       // 装饰
	RegisterMsgProcessFunc("ReqDecorateAll", ReqDecorateAll) // 装饰全部
	RegisterMsgProcessFunc("ReqAreaReward", ReqAreaReward)   // 章节奖励
	//Gm命令
	RegisterMsgProcessFunc("ReqGmCommand", ReqGmCommand) // Gm命令

	// #region 卡牌
	RegisterMsgProcessFunc("ReqCardInfo", ReqCardInfo)                           // 请求卡牌信息
	RegisterMsgProcessFunc("ReqCardSeasonFirstReward", ReqCardSeasonFirstReward) // 领取赛季首次奖励
	RegisterMsgProcessFunc("ReqCardCollectReward", ReqCardCollectReward)         //领取卡牌系列收集奖励
	RegisterMsgProcessFunc("ReqExStarReward", ReqExStarReward)                   // 兑换收集星星奖励
	RegisterMsgProcessFunc("ReqAllCollectReward", ReqAllCollectReward)           // 领取全收集奖励
	RegisterMsgProcessFunc("ReqCardGive", ReqCardGive)                           // 请求赠送卡牌
	RegisterMsgProcessFunc("ReqAgreeCardGive", ReqAgreeCardGive)                 // 同意赠送卡牌
	RegisterMsgProcessFunc("ReqRefuseCardGive", ReqRefuseCardGive)               // 拒绝赠送卡牌

	RegisterMsgProcessFunc("ReqCardExchange", ReqCardExchange)             // 请求交换卡牌
	RegisterMsgProcessFunc("ReqSelectCardExchange", ReqSelectCardExchange) // 选择交换的卡牌
	RegisterMsgProcessFunc("ReqAgreeCardExchange", ReqAgreeCardExchange)   // 完成交换卡牌
	RegisterMsgProcessFunc("ReqRefuseCardSelect", ReqRefuseCardSelect)     // 拒绝选择卡牌进行交换
	RegisterMsgProcessFunc("ReqRefuseCardExchange", ReqRefuseCardExchange) // 拒绝卡牌交换
	RegisterMsgProcessFunc("ReqCardSend", ReqCardSend)                     // 直接赠送卡牌
	RegisterMsgProcessFunc("ReqGetFriendCard", ReqGetFriendCard)           // 领取好友赠送的卡牌
	RegisterMsgProcessFunc("ReqMasterCard", ReqMasterCard)                 // 万能卡兑换
	RegisterMsgProcessFunc("ReqCardHandbookReward", ReqCardHandbookReward) // 卡牌图鉴

	// 日常任务
	RegisterMsgProcessFunc("ReqGetDailyTaskReward", ReqGetDailyTaskReward) // 领取日常任务奖励
	RegisterMsgProcessFunc("ReqGetDailyWeekReward", ReqGetDailyWeekReward) // 领取周活跃奖励
	RegisterMsgProcessFunc("ReqDailyUnlock", ReqDailyUnlock)               // 日常任务解锁
	// 新手任务
	RegisterMsgProcessFunc("ReqGetGuideTaskReward", ReqGetGuideTaskReward)     // 领取日新手任务奖励
	RegisterMsgProcessFunc("ReqGetGuideActiveReward", ReqGetGuideActiveReward) // 领取活跃奖励

	// 引导奖励
	RegisterMsgProcessFunc("ReqGuideReward", ReqGuideReward)     // 领取引导奖励
	RegisterMsgProcessFunc("ReqGuidePlayroom", ReqGuidePlayroom) // 领取playroom引导奖励

	// 头像
	RegisterMsgProcessFunc("ReqSetFace", ReqSetFace) // 设置头像
	// 头像框
	RegisterMsgProcessFunc("ReqSetAvatar", ReqSetAvatar) // 设置头像框
	// 表情
	RegisterMsgProcessFunc("ReqSetEmoji", ReqSetEmoji) // 设置表情
	// 收藏室
	RegisterMsgProcessFunc("ReqCollectInfo", ReqCollectInfo) // 请求收藏室数据
	RegisterMsgProcessFunc("ReqCollect", ReqCollect)         // 领取收藏室奖励
	// 七日签到
	RegisterMsgProcessFunc("ReqGetSevenLoginReward", ReqGetSevenLoginReward) // 领取七日签到奖励
	RegisterMsgProcessFunc("ReqGetMonthLoginReward", ReqGetMonthLoginReward) // 领取月签到奖励

	// 限时事件
	RegisterMsgProcessFunc("ReqLimitEvent", ReqLimitEvent)                 // 请求限时事件数据
	RegisterMsgProcessFunc("ReqFastProduceReward", ReqFastProduceReward)   // 连击快手奖励
	RegisterMsgProcessFunc("ReqFastProduceInfo", ReqFastProduceInfo)       // 请求连击快手数据
	RegisterMsgProcessFunc("ReqLimitSenceReward", ReqLimitSenceReward)     // 获取场景转盘奖励
	RegisterMsgProcessFunc("ReqSelectLimitEvent", ReqSelectLimitEvent)     //领取Bouns限时事件进度奖励
	RegisterMsgProcessFunc("ReqGetGoldCard", ReqGetGoldCard)               //请求金卡交换信息
	RegisterMsgProcessFunc("ReqLimitEventLuckyCat", ReqLimitEventLuckyCat) //幸运猫获取奖励
	RegisterMsgProcessFunc("ReqCatTrickReward", ReqCatTrickReward)         //小猫戏法获取奖励

	// #region 好友
	RegisterMsgProcessFunc("ReqFriendList", ReqFriendList)               // 请求好友列表
	RegisterMsgProcessFunc("ReqFriendApply", ReqFriendApply)             // 请求申请好友列表
	RegisterMsgProcessFunc("ReqFriendCardMsg", ReqFriendCardMsg)         // 请求好友卡牌申请列表
	RegisterMsgProcessFunc("ReqWishApplyList", ReqWishApplyList)         // 请求好友心愿单申请列表
	RegisterMsgProcessFunc("ReqFriendTimeLine", ReqFriendTimeLine)       // 请求好友时间线
	RegisterMsgProcessFunc("ReqFriendRecommend", ReqFriendRecommend)     // 获取推荐好友
	RegisterMsgProcessFunc("ReqFriendTLUpvote", ReqFriendTLUpvote)       // 请求时间线点赞
	RegisterMsgProcessFunc("ReqFriendTReward", ReqFriendTReward)         // 获取时间线奖励
	RegisterMsgProcessFunc("ReqAddNpc", ReqAddNpc)                       // 增加npc
	RegisterMsgProcessFunc("ReqWishApply", ReqWishApply)                 // 同意好友心愿单请求
	RegisterMsgProcessFunc("ReqFriendByCode", ReqFriendByCode)           // 根据邀请码查询好友
	RegisterMsgProcessFunc("ReqFriendReplyHandle", ReqFriendReplyHandle) // 回复好友信息

	RegisterMsgProcessFunc("ReqSearchPlayer", ReqSearchPlayer) // 搜索好友
	RegisterMsgProcessFunc("ReqApplyFriend", ReqApplyFriend)   // 申请好友
	RegisterMsgProcessFunc("ReqAgreeFriend", ReqAgreeFriend)   // 同意申请
	RegisterMsgProcessFunc("ReqRefuseFriend", ReqRefuseFriend) // 拒绝申请
	RegisterMsgProcessFunc("ReqDelFriend", ReqDelFriend)       // 删除好友

	// Facebook邀请好友
	RegisterMsgProcessFunc("ReqInviteFriendData", ReqInviteFriendData)         // 请求邀请好友数据
	RegisterMsgProcessFunc("ReqSelfInvited", ReqSelfInvited)                   // 请求自己邀请的好友
	RegisterMsgProcessFunc("ReqGetInviteReward", ReqGetInviteReward)           // 领取邀请奖励
	RegisterMsgProcessFunc("ReqAutoAddInviteFriend", ReqAutoAddInviteFriend)   // 自动添加邀请好友
	RegisterMsgProcessFunc("ReqAutoAddInviteFriend2", ReqAutoAddInviteFriend2) // 自动添加邀请好友
	RegisterMsgProcessFunc("ReqBindFacebookAccount", ReqBindFacebookAccount)   // 绑定facebook账号
	RegisterMsgProcessFunc("ReqOnlyBindFacebook", ReqOnlyBindFacebook)         // 绑定唯一facebook
	RegisterMsgProcessFunc("ReqUnBindFacebook", ReqUnBindFacebook)             // 解绑facebook
	RegisterMsgProcessFunc("ReqSynGameData", ReqSynGameData)                   // 同步账号数据

	// 榜单
	RegisterMsgProcessFunc("ReqRank", ReqRank) // 请求榜单数据

	// 邮件
	RegisterMsgProcessFunc("ReqMailList", ReqMailList)           // 请求邮件数据
	RegisterMsgProcessFunc("ReqReadMail", ReqReadMail)           // 读取邮件
	RegisterMsgProcessFunc("ReqGetMailReward", ReqGetMailReward) // 领取邮件奖励
	RegisterMsgProcessFunc("ReqDeleteMail", ReqDeleteMail)       // 删除邮件

	// 商店
	RegisterMsgProcessFunc("ReqFreeShop", ReqFreeShop)                 // 领取商店免费奖励
	RegisterMsgProcessFunc("ReqBuyChessShop", ReqBuyChessShop)         // 购买商店棋子
	RegisterMsgProcessFunc("ReqBuyChessShop2", ReqBuyChessShop2)       // 购买商店棋子直接加入棋盘
	RegisterMsgProcessFunc("ReqRefreshChessShop", ReqRefreshChessShop) // 刷新棋子商店
	RegisterMsgProcessFunc("ReqAddWish", ReqAddWish)                   // 添加心愿单
	RegisterMsgProcessFunc("ReqGetWish", ReqGetWish)                   // 领取心愿单奖励
	RegisterMsgProcessFunc("ReqSendWishBeg", ReqSendWishBeg)           // 发送心愿单请求
	// 无尽礼包
	RegisterMsgProcessFunc("ReqEndless", ReqEndless)             // 请求无尽礼包数据
	RegisterMsgProcessFunc("ReqEndlessReward", ReqEndlessReward) // 领取无尽礼包免费奖励

	// 小猪存钱罐
	RegisterMsgProcessFunc("ReqPiggyBankReward", ReqPiggyBankReward) // 小猪存钱罐领取奖励

	// 锦标赛
	RegisterMsgProcessFunc("ReqChampshipReward", ReqChampshipReward)         // 领取锦标赛奖励
	RegisterMsgProcessFunc("ReqChampshipRankReward", ReqChampshipRankReward) // 领取锦标赛排行榜奖励
	RegisterMsgProcessFunc("ReqChampshipRank", ReqChampshipRank)             // 请求锦标赛排行榜
	RegisterMsgProcessFunc("ReqChampshipPreRank", ReqChampshipPreRank)       // 请求锦标赛昨日排行榜

	// #region 活动
	RegisterMsgProcessFunc("ReqActivityReward", ReqActivityReward) // 领取活动奖励
	// 挖矿
	RegisterMsgProcessFunc("ReqMining", ReqMining)             // 请求挖矿数据
	RegisterMsgProcessFunc("ReqMiningReward", ReqMiningReward) // 领取挖矿奖励
	RegisterMsgProcessFunc("ReqMiningTake", ReqMiningTake)     // 挖矿
	// 猜颜色
	RegisterMsgProcessFunc("ReqGuessColor", ReqGuessColor)             // 请求猜颜色数据
	RegisterMsgProcessFunc("ReqGuessColorReward", ReqGuessColorReward) // 领取猜颜色奖励
	RegisterMsgProcessFunc("ReqGuessColorTake", ReqGuessColorTake)     // 猜颜色
	//  三段竞赛
	RegisterMsgProcessFunc("ReqRace", ReqRace)
	RegisterMsgProcessFunc("ReqRaceReward", ReqRaceReward)
	RegisterMsgProcessFunc("ReqRaceStart", ReqRaceStart)
	// 猫草大作战
	RegisterMsgProcessFunc("ReqCatnip", ReqCatnip)                       // 请求猫草大作战数据
	RegisterMsgProcessFunc("ReqCatnipInvite", ReqCatnipInvite)           // 猫草大作战邀请好友
	RegisterMsgProcessFunc("ReqCatnipAgree", ReqCatnipAgree)             // 同意邀请
	RegisterMsgProcessFunc("ReqCatnipRefuse", ReqCatnipRefuse)           // 拒绝邀请
	RegisterMsgProcessFunc("ReqCatnipMultiply", ReqCatnipMultiply)       // 猫草大作战倍数
	RegisterMsgProcessFunc("ReqCatnipPlay", ReqCatnipPlay)               // 猫草大作战游戏转盘
	RegisterMsgProcessFunc("ReqCatnipReward", ReqCatnipReward)           // 猫草大作战领取奖励
	RegisterMsgProcessFunc("ReqCatnipGrandReward", ReqCatnipGrandReward) // 猫草大作战领取大奖
	RegisterMsgProcessFunc("ReqCatnipEmoji", ReqCatnipEmoji)
	// 活动通行证
	RegisterMsgProcessFunc("ReqActPass", ReqActPass)             // 请求活动通行证数据
	RegisterMsgProcessFunc("ReqActPassReward", ReqActPassReward) // 领取活动通行证奖励
	// #region playroom
	RegisterMsgProcessFunc("ReqPlayroom", ReqPlayroom)                             // 请求playroom数据
	RegisterMsgProcessFunc("ReqPlayroomInfo", ReqPlayroomInfo)                     // 请求playroom拜访信息
	RegisterMsgProcessFunc("ReqPlayroomDressSet", ReqPlayroomDressSet)             // 设置服装
	RegisterMsgProcessFunc("ReqPlayroomPetAirSet", ReqPlayroomPetAirSet)           // 获取宠物空气
	RegisterMsgProcessFunc("ReqPlayroomGame", ReqPlayroomGame)                     // 游戏结果
	RegisterMsgProcessFunc("ReqPlayroomInteract", ReqPlayroomInteract)             // 宠物交互
	RegisterMsgProcessFunc("ReqPlayroomSetRoom", ReqPlayroomSetRoom)               // playroom装饰
	RegisterMsgProcessFunc("ReqPlayroomSelectReward", ReqPlayroomSelectReward)     // playroom选择奖励
	RegisterMsgProcessFunc("ReqPlayroomLose", ReqPlayroomLose)                     // 处理偷取的棋子
	RegisterMsgProcessFunc("ReqPlayroomWork", ReqPlayroomWork)                     // 宠物工作
	RegisterMsgProcessFunc("ReqPlayroomRest", ReqPlayroomRest)                     // 宠物休息
	RegisterMsgProcessFunc("ReqPlayroomDraw", ReqPlayroomDraw)                     // 转盘
	RegisterMsgProcessFunc("ReqPlayroomFlip", ReqPlayroomFlip)                     // 翻牌
	RegisterMsgProcessFunc("ReqPlayroomFlipReward", ReqPlayroomFlipReward)         // 翻牌奖励
	RegisterMsgProcessFunc("ReqPlayroomChip", ReqPlayroomChip)                     // 消除碎片
	RegisterMsgProcessFunc("ReqPlayroomOutline", ReqPlayroomOutline)               // 打工离线
	RegisterMsgProcessFunc("ReqPlayroomWrokOutline", ReqPlayroomWrokOutline)       // 打工离线完成
	RegisterMsgProcessFunc("ReqPlayroomShop", ReqPlayroomShop)                     // playroom 商店
	RegisterMsgProcessFunc("ReqPlayroomBuyItem", ReqPlayroomBuyItem)               // 购买playroom物品
	RegisterMsgProcessFunc("ReqPlayroomUpvote", ReqPlayroomUpvote)                 // 点赞别人的playroom
	RegisterMsgProcessFunc("ReqPlayroomUnlock", ReqPlayroomUnlock)                 // 解锁房间
	RegisterMsgProcessFunc("ReqPlayroomTask", ReqPlayroomTask)                     // playroom任务
	RegisterMsgProcessFunc("ReqPlayroomTaskReward", ReqPlayroomTaskReward)         // 领取任务奖励
	RegisterMsgProcessFunc("ReqPlayroomGameShowReward", ReqPlayroomGameShowReward) // 展示游戏结果数据
	RegisterMsgProcessFunc("ReqPlayroomGuide", ReqPlayroomGuide)                   // 展示游戏结果数据
	// 宠物宝藏
	RegisterMsgProcessFunc("ReqFriendTreasure", ReqFriendTreasure)           // 请求好友宝藏数据
	RegisterMsgProcessFunc("ReqFriendTreasureStart", ReqFriendTreasureStart) // 开始游戏
	RegisterMsgProcessFunc("ReqFriendTreasureFilp", ReqFriendTreasureFilp)   // 翻牌
	RegisterMsgProcessFunc("ReqFriendTreasureEnd", ReqFriendTreasureEnd)     // 结束游戏

	// #region 充值
	RegisterMsgProcessFunc("ReqCreateOrderSn", ReqCreateOrderSn) // 创建订单号
	RegisterMsgProcessFunc("ReqShippingOrder", ReqShippingOrder) // 获取订单号
	RegisterMsgProcessFunc("ReqChargeReceive", ReqChargeReceive) // 礼包回复邮件
}

func (ad *GameLogic) InitActivity() {
	ad.m_CronEntryIDs = make(map[int]*LimitActPeriod)
}

func (ad *GameLogic) NotifyAll(m *MsgMod.Msg) {
	ad.M_Players.Range(func(k, v interface{}) bool {
		v.(*Player).Send(m)
		return true
	})
}

func (ad *GameLogic) GetPlayerNum() int {
	length := 0
	ad.M_Players.Range(func(_, _ interface{}) bool {
		length++
		return true
	})
	return length
}

func (ad *GameLogic) GetStartTime() int64 {
	return ad.StartTime
}

func NotifyPlayer(Uid int, m *MsgMod.Msg) {
	clone := *m
	clone.To = Uid
	clone.HandleType = MsgMod.HANDLE_MOD_PLAYER_MSG
	NotifyPlayerMsgAsync(&clone)
}

func Destroy() {
	log.Debug("服务器下线")
	if G_GameLogicPtr != nil {
		G_GameLogicPtr.M_Players.Range(func(k, v interface{}) bool {
			v.(*Player).PushAndSendClienRes(&msg.ForceKickOut{})
			v.(*Player).ClearData()
			log.Debug("palyer %d 断开连接 写入数据", k)
			return true
		})
		if G_GameLogicPtr.FriendMgr != nil {
			G_GameLogicPtr.FriendMgr.SaveData()
		}
		if G_GameLogicPtr.MessageMgr != nil {
			G_GameLogicPtr.MessageMgr.SaveData()
		}
		if G_GameLogicPtr.VarMgr != nil {
			G_GameLogicPtr.VarMgr.SaveData()
		}
		if G_GameLogicPtr.ChampshipMgr != nil {
			G_GameLogicPtr.ChampshipMgr.SaveData()
		}
		if G_GameLogicPtr.MailMgr != nil {
			G_GameLogicPtr.MailMgr.SaveData()
		}
		if G_GameLogicPtr.RankMgr != nil {
			G_GameLogicPtr.RankMgr.SaveData()
		}
	}
	log.Debug("服务器下线完成")
}

func GeneratedCode(Phone string) (string, error) {
	Code := GoUtil.Rand6DigitNumber()
	log.Debug("生成验证码: %s", Code)
	key := "Code_" + Phone
	value, _ := db.RedisGetKey(key)
	if value != "" {
		//return fmt.Errorf("验证码已发送，请稍后再试")
	}
	db.RedisSetKey(key, Code, 5*time.Minute)
	err := GoUtil.SmsCode(Phone, Code)
	if err != nil {
		log.Error("发送验证码失败: %v", err)
	}
	// TODO 测试用
	return Code, err
}

func VerifyCode(Phone, Code string) error {
	key := "Code_" + Phone
	value, err := db.RedisGetKey(key)
	if err != nil {
		return fmt.Errorf("验证码已失效")
	}
	if value == Code {
		db.RedisDelKey(key)
		return nil
	}
	return fmt.Errorf("验证码错误")
}
