package main

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"io"
	"strconv"
	"time"

	"github.com/globalsign/mgo/bson"
	"mongo.games.com/goserver/core/basic"
	"mongo.games.com/goserver/core/logger"
	"mongo.games.com/goserver/core/netlib"
	"mongo.games.com/goserver/core/task"

	"mongo.games.com/game/common"
	"mongo.games.com/game/model"
	"mongo.games.com/game/proto"
	login_proto "mongo.games.com/game/protocol/login"
	"mongo.games.com/game/srvdata"
)

/*
登录功能：
记录账号登录状态和连接状态（一个玩家可能多客户端登录，会有多个连接，实现顶号）
连接有两种状态，登录中，登录完成
登录流程：
1.判断连接是否已经存在（存在说明已经登录过了），存在则不用处理，这是单连接重复登录
2.判断账号是否有正在登录的连接，有的话则断开当前连接，从账号登录的角度讲只能一个客户端在登录中
3.判断是否有已经登录完成并且正在游戏中的连接，如果有则断开当前连接（游戏中的连接不会被断开）
4.判断是否有已经登录完成的连接但是没有在游戏中，则当前连接可以登录（因为登录是异步的，登录完成后可以再判断一下3），记录账号信息和连接状态，登录完成断开其它连接（顶号）
5.没有其他连接，正常登录
*/

type CSLoginPacketFactory struct {
}

type CSLoginHandler struct {
}

func (this *CSLoginPacketFactory) CreatePacket() interface{} {
	pack := &login_proto.CSLogin{}
	return pack
}

func (this *CSLoginHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSLoginHandler Process recv ", data)
	csl, ok := data.(*login_proto.CSLogin)
	if !ok {
		return nil
	}

	sendSCLogin := func(code login_proto.OpResultCode, str ...string) {
		sclogin := &login_proto.SCLogin{
			OpRetCode: code,
		}
		if len(str) == 2 {
			sclogin.ApkUrl = str[0]
			sclogin.IpaUrl = str[1]
		}
		proto.SetDefaults(sclogin)
		common.SendToGate(sid, int(login_proto.LoginPacketID_PACKET_SC_LOGIN), sclogin, s)
	}

	sendSCDisconnect := func(code int32) {
		ssDis := &login_proto.SSDisconnect{
			SessionId: proto.Int64(sid),
			Type:      proto.Int32(code),
		}
		proto.SetDefaults(ssDis)
		s.Send(int(login_proto.GatePacketID_PACKET_SS_DICONNECT), ssDis)
	}

	if csl.GetUsername() == "" || csl.GetPassword() == "" {
		sendSCLogin(login_proto.OpResultCode_OPRC_Error)
		sendSCDisconnect(common.KickReason_Freeze)
		return nil
	}

	// 根据PlatformTag包标识，获取平台信息
	// 机器人没有包标识，根据csl.GetPlatform()判断
	platform, _, promoter, _, tagkey := PlatformMgrSingleton.GetPlatformByPackageTag(csl.GetPlatformTag())
	if platform == 0 && csl.GetPlatform() != common.Platform_Rob {
		sendSCLogin(login_proto.OpResultCode_OPRC_Error)
		sendSCDisconnect(common.KickReason_Freeze)
		return nil
	}

	// 替换为后台拿到的配置数据，不再使用客户端的发送数据
	backupPromoter := ""
	if csl.GetChannel() != common.Channel_Rob {
		// platform
		if platform != 0 {
			csl.Platform = proto.String(strconv.Itoa(int(platform)))
		} else {
			csl.Platform = proto.String(DefaultPlatform)
			platform = DefaultPlatformInt
		}
		// channel
		//if channel != 0 {
		//	csl.Channel = proto.String(strconv.Itoa(int(channel)))
		//} else {
		//	csl.Channel = proto.String("")
		//}
		// promoter
		if len(csl.GetPromoter()) <= 0 {
			if promoter != 0 {
				csl.Promoter = proto.String(strconv.Itoa(int(promoter)))
			} else {
				csl.Promoter = proto.String("")
			}
		} else {
			backupPromoter = csl.GetPromoter()
		}
		//InviterId 和 PromoterTree客户端是从剪贴板上读取出来的，所以不以包上的为准
	}

	logger.Logger.Tracef("CSLoginHandler %v", csl.String())

	// 数据校验
	raw := fmt.Sprintf("%v%v%v%v%v", csl.GetUsername(), csl.GetPassword(), csl.GetTimeStamp(), csl.GetParams(), common.GetAppId())
	h := md5.New()
	io.WriteString(h, raw)
	hashsum := hex.EncodeToString(h.Sum(nil))
	if hashsum != csl.GetSign() {
		logger.Logger.Tracef("ClientSessionAttribute_State hashsum not fit!!! get:%v expect:%v rawstr:%v", csl.GetSign(), hashsum, raw)
		sendSCLogin(login_proto.OpResultCode_OPRC_Error)
		sendSCDisconnect(common.KickReason_CheckCodeErr)
		return nil
	}

	// 平台维护
	pt := PlatformMgrSingleton.GetPlatform(strconv.Itoa(int(platform)))
	if pt == nil || pt.Disable {
		sendSCLogin(login_proto.OpResultCode_OPRC_SceneServerMaintain)
		sendSCDisconnect(common.KickReason_Freeze)
		return nil
	}

	// 是否正在维护
	if model.GameParamData.SrvMaintain && SrvIsMaintaining {
		inWhiteList := false
		for i := 0; i < len(model.GMACData.WhiteList); i++ {
			if model.GMACData.WhiteList[i] == csl.GetUsername() {
				inWhiteList = true
				break
			}
		}
		//排除白名单里的玩家
		if !inWhiteList {
			sendSCLogin(login_proto.OpResultCode_OPRC_SceneServerMaintain)
			sendSCDisconnect(common.KickReason_Freeze)
			return nil
		}
	}

	// 检查版本号
	if model.GameParamData.VerifyClientVersion {
		deviceOs := csl.GetDeviceOs()
		packVers := srvdata.GetPackVers(csl.GetPlatformTag())
		if deviceOs != "" && packVers != nil {
			if cvers, ok := packVers[deviceOs]; ok {
				if csl.GetApkVer() < cvers.MinApkVer {
					appInfo := PlatformMgrSingleton.GetPackageTag(csl.PlatformTag)
					sendSCLogin(login_proto.OpResultCode_OPRC_YourAppVerIsLow, appInfo.ApkUrl, appInfo.IpaUrl)
					sendSCDisconnect(common.KickReason_AppLow)
					return nil
				}
				if csl.GetResVer() < cvers.MinResVer {
					appInfo := PlatformMgrSingleton.GetPackageTag(csl.PlatformTag)
					sendSCLogin(login_proto.OpResultCode_OPRC_YourResVerIsLow, appInfo.ApkUrl, appInfo.IpaUrl)
					sendSCDisconnect(common.KickReason_ResLow)
					return nil
				}
			}
		}
	}

	// 手机验证码登录，验证码是否正确
	var codeValid bool
	if csl.GetLoginType() == common.LoginTypeTelCode {
		if csl.GetCode() != "" {
			code := CacheMemory.Get(common.GetTelLoginCodeKey(csl.GetPlatform(), csl.GetUsername()))
			// 验证码错误
			if code != csl.GetCode() {
				sendSCLogin(login_proto.OpResultCode_OPRC_TelCodeError)
				sendSCDisconnect(common.KickReason_Freeze)
				return nil
			}
			codeValid = true
		}
	}

	// 连接正在登录
	state := LoginStateMgrSington.GetLoginStateBySid(sid)
	if state != nil {
		logger.Logger.Warnf("CSLoginHandler relogining (%v) repeated (%v) ", csl.GetUsername(), sid)
		return nil
	}

	// 玩家是否有在登录的连接
	if LoginStateMgrSington.IsLogining(csl.GetUsername(), csl.GetPlatform(), tagkey) {
		logger.Logger.Warnf("CSLoginHandler logining (%v) disconnect current(%v) ", csl.GetUsername(), sid)
		sendSCDisconnect(common.KickReason_Logining) // 登录中重复登录会被断开连接
		return nil
	}

	// 玩家已经登录完成并且在游戏中，断开当前连接
	ls := LoginStateMgrSington.GetLoginStateByName(UserKey(csl.GetUsername(), csl.GetPlatform(), tagkey))
	if ls != nil && ls.acc != nil {
		// lss 其它连接
		lss := LoginStateMgrSington.LoginFinish(csl.GetUsername(), csl.GetPlatform(), sid, ls.acc, tagkey)
		player := PlayerMgrSington.GetPlayerBySnId(ls.acc.SnId)
		if len(lss) > 0 && (player != nil && (player.scene != nil || player.thrscene != 0)) {
			sendSCLogin(login_proto.OpResultCode_OPRC_LoginOtherPlace)
			sendSCDisconnect(common.KickReason_Logining)
			return nil
		}
	}

	clog := &model.ClientLoginInfo{
		LoginType:    csl.GetLoginType(),
		ApkVer:       csl.GetApkVer(),
		ResVer:       csl.GetResVer(),
		InviterId:    csl.GetInviterId(),
		PromoterTree: csl.GetPromoterTree(),
		UserName:     csl.GetUsername(),
		PlatformTag:  csl.GetPlatformTag(),
		Promoter:     csl.GetPromoter(),
		Sid:          sid,
		HeadUrl:      csl.GetHeadUrl(),
		DeviceOS:     csl.GetDeviceOs(),
	}

	// 玩家开始登录
	if LoginStateMgrSington.StartLogin(csl.GetUsername(), csl.GetPlatform(), sid, s, clog, tagkey) {
		tl := &TaskLogin{CSLogin: csl, Session: s, Sid: sid, BackupPromoter: backupPromoter, tagkey: tagkey, codeValid: codeValid}
		t := task.New(nil, tl, tl, "TaskLogin")
		if b := t.StartByExecutor(csl.GetUsername()); !b {
			logger.Logger.Trace("login task launch failed")
			sendSCDisconnect(common.KickReason_TaskErr)
		}
		return nil
	}

	// 用缓存信息做登录，有account
	// 根据StartLogin代码，这里ls.acc一定不为nil
	ls = LoginStateMgrSington.GetLoginStateByName(UserKey(csl.GetUsername(), csl.GetPlatform(), tagkey))
	if ls != nil {
		acc := ls.acc
		// 账号冻结
		if acc.State > time.Now().Unix() {
			sendSCLogin(login_proto.OpResultCode_OPRC_AccountBeFreeze)
			sendSCDisconnect(common.KickReason_Freeze)
			//清理登录状态
			LoginStateMgrSington.LogoutBySid(sid)
			return nil
		}

		pwdIsErr := true
		switch csl.GetLoginType() {
		case common.LoginTypeGuest: //游客登录
			if acc.UserName == csl.GetUsername() && acc.Platform == csl.GetPlatform() && acc.TagKey == tagkey {
				raw := fmt.Sprintf("%v%v%v", acc.PassWord, common.GetAppId(), csl.GetTimeStamp())
				h := md5.New()
				io.WriteString(h, raw)
				pwd := hex.EncodeToString(h.Sum(nil))
				if pwd != csl.GetPassword() {
					pwdIsErr = true
				} else {
					pwdIsErr = false
				}
			}
		case common.LoginTypeAccount: //帐号登录
			if acc.UserName == csl.GetUsername() && acc.Platform == csl.GetPlatform() && acc.TagKey == tagkey {
				raw := fmt.Sprintf("%v%v%v", acc.TelPassWord, common.GetAppId(), csl.GetTimeStamp())
				ht := md5.New()
				io.WriteString(ht, raw)
				pwd := hex.EncodeToString(ht.Sum(nil))
				if pwd != csl.GetPassword() {
					pwdIsErr = true
				} else {
					pwdIsErr = false
				}
			}
		case common.LoginTypeTelCode: // 手机验证码登录
			if acc.Tel == csl.GetUsername() && acc.Platform == csl.GetPlatform() && acc.TagKey == tagkey {
				if codeValid {
					// 更新密码
					raw := fmt.Sprintf("%v%v", bson.NewObjectId().Hex(), common.GetAppId())
					h := md5.New()
					io.WriteString(h, raw)
					pwd := hex.EncodeToString(h.Sum(nil))
					acc.TelPassWord = pwd
					acc.TelPassWordExpire = time.Now().AddDate(0, 0, common.TelLoginValidDays).Unix()
					pwdIsErr = false
					var err error
					task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
						err = model.UpdateAccount(acc)
						return nil
					}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
						if err != nil {
							logger.Logger.Errorf("UpdateAccount error:%v", err)
						}
					}), "UpdateAccount").Start()
				} else {
					raw := fmt.Sprintf("%v%v%v", acc.TelPassWord, common.GetAppId(), csl.GetTimeStamp())
					ht := md5.New()
					io.WriteString(ht, raw)
					pwd := hex.EncodeToString(ht.Sum(nil))
					if pwd != csl.GetPassword() {
						pwdIsErr = true
					} else {
						pwdIsErr = false
					}
				}
			}
		}

		//密码错误
		if pwdIsErr {
			// 缓存登录失败再从数据库查询一次
			if csl.GetChannel() != common.Channel_Rob {
				//try from db login
				tl := &TaskLogin{CSLogin: csl, Session: s, Sid: sid}
				t := task.New(nil, tl, tl, "TaskLogin")
				if b := t.StartByExecutor(csl.GetUsername()); !b {
					logger.Logger.Trace("login task launch failed")
					sendSCDisconnect(common.KickReason_DBLoadAcc)
				}
				return nil
			}
			sendSCLogin(login_proto.OpResultCode_OPRC_LoginPassError)
			//清理登录状态
			LoginStateMgrSington.LogoutBySid(sid)
			return nil
		}

		SCLogin(s, sid, csl, acc, login_proto.OpResultCode_OPRC_Sucess)

		// 标记当前玩家登录成功，断开其它连接
		lss := LoginStateMgrSington.LoginFinish(csl.GetUsername(), csl.GetPlatform(), sid, acc, tagkey)
		if len(lss) != 0 {
			for k, ls := range lss {
				ssDis := &login_proto.SSDisconnect{
					SessionId: proto.Int64(k),
					Type:      proto.Int32(common.KickReason_OtherLogin),
				}
				proto.SetDefaults(ssDis)
				s.Send(int(login_proto.GatePacketID_PACKET_SS_DICONNECT), ssDis)
				LoginStateMgrSington.Logout(ls)
				logger.Logger.Warnf("==========顶号 oldsid:%v newsid:%v", k, sid)
			}
		}
	}
	return nil
}

type CSCustomServicePacketFactory struct {
}

type CSCustomServiceHandler struct {
}

func (this *CSCustomServicePacketFactory) CreatePacket() interface{} {
	pack := &login_proto.CSCustomService{}
	return pack
}

func (this *CSCustomServiceHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSCustomService Process recv ", data)
	if _, ok := data.(*login_proto.CSCustomService); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSCustomServiceHandler p == nil")
			return nil
		}
		var Url string
		var customType int32
		flag := int32(0)
		platform := PlatformMgrSingleton.GetPlatform(p.Platform)
		if platform != nil {
			Url = platform.ServiceUrl
			customType = platform.CustomType
			if platform.ServiceFlag {
				flag = 1
			}
		}
		pack := &login_proto.SCCustomService{
			Url:        proto.String(Url),
			OpenFlag:   proto.Int32(flag),
			CustomType: proto.Int32(customType),
		}
		p.SendToClient(int(login_proto.LoginPacketID_PACKET_SC_CUSTOMSERVICE), pack)
		logger.Logger.Trace("SCCustomService:", pack)
	}
	return nil
}

type CSPlatFormPacketFactory struct {
}

type CSPlatFormHandler struct {
}

func (this *CSPlatFormPacketFactory) CreatePacket() interface{} {
	pack := &login_proto.CSPlatFormConfig{}
	return pack
}

func (this *CSPlatFormHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSPlatFormHandler Process recv ", data)
	if _, ok := data.(*login_proto.CSPlatFormConfig); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSPlatFormHandler p == nil")
			return nil
		}

		//platformId, _, _ := PlatformMgrSingleton.GetPlatformByPackageTag(msg.GetPlatformTag())
		platform := PlatformMgrSingleton.GetPlatform(p.Platform)
		if platform == nil {
			scPlatForm := &login_proto.SCPlatFormConfig{
				OpRetCode: login_proto.OpResultCode_OPRC_Error,
			}
			proto.SetDefaults(scPlatForm)
			p.SendToClient(int(login_proto.LoginPacketID_PACKET_SC_PLATFORMCFG), scPlatForm)
			return nil
		}

		scPlatForm := &login_proto.SCPlatFormConfig{
			Platform:               proto.String(p.Platform),
			OpRetCode:              login_proto.OpResultCode_OPRC_Sucess,
			UpgradeAccountGiveCoin: proto.Int32(p.GetUpdateAccPrize()),
			VipRange:               platform.VipRange,
			ExchangeMin:            proto.Int32(platform.ExchangeMin),
			ExchangeLimit:          proto.Int32(platform.ExchangeLimit),
			OtherParams:            proto.String(platform.OtherParams),
			SpreadConfig:           proto.Int32(platform.SpreadConfig),
			ExchangeTax:            proto.Int32(platform.ExchangeTax),
			ExchangeFlow:           proto.Int32(GetExchangeFlow(p.PlayerData)),
			ExchangeBankMax:        proto.Int32(platform.ExchangeBankMax),
			ExchangeAlipayMax:      proto.Int32(platform.ExchangeAlipayMax),
			ExchangeMultiple:       proto.Int32(platform.ExchangeMultiple),
		}
		rebateTask := RebateInfoMgrSington.rebateTask[p.Platform]
		if rebateTask != nil {
			scPlatForm.Rebate = &login_proto.RebateCfg{
				RebateSwitch:   proto.Bool(rebateTask.RebateSwitch),
				ReceiveMode:    proto.Int32(int32(rebateTask.ReceiveMode)),
				NotGiveOverdue: proto.Int32(int32(rebateTask.NotGiveOverdue)),
			}
		}
		if platform.ClubConfig != nil { //俱乐部配置
			scPlatForm.Club = &login_proto.ClubCfg{
				IsOpenClub:              proto.Bool(platform.ClubConfig.IsOpenClub),
				CreationCoin:            proto.Int64(platform.ClubConfig.CreationCoin),
				IncreaseCoin:            proto.Int64(platform.ClubConfig.IncreaseCoin),
				ClubInitPlayerNum:       proto.Int32(platform.ClubConfig.ClubInitPlayerNum),
				CreateClubCheckByManual: proto.Bool(platform.ClubConfig.CreateClubCheckByManual),
				EditClubNoticeByManual:  proto.Bool(platform.ClubConfig.EditClubNoticeByManual),
				CreateRoomAmount:        proto.Int64(platform.ClubConfig.CreateRoomAmount),
				GiveCoinRate:            platform.ClubConfig.GiveCoinRate,
			}
		}

		proto.SetDefaults(scPlatForm)
		p.SendToClient(int(login_proto.LoginPacketID_PACKET_SC_PLATFORMCFG), scPlatForm)
	}
	return nil
}

//
//// 公告信息
//type CSBulletionInfoPacketFactory struct {
//}
//
//type CSBulletionInfoHandler struct {
//}
//
//func (this *CSBulletionInfoPacketFactory) CreatePacket() interface{} {
//	pack := &login_proto.CSBulletionInfo{}
//	return pack
//}
//func (this *CSBulletionInfoHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
//	logger.Logger.Trace("CSBulletionInfoHandler Process recv ", data)
//	if msg, ok := data.(*login_proto.CSBulletionInfo); ok {
//		p := PlayerMgrSington.GetPlayer(sid)
//		if p == nil {
//			logger.Logger.Trace("CSBulletionInfoHandler p == nil ")
//			return nil
//		}
//		pf, _, _, _, _ := PlatformMgrSingleton.GetPlatformByPackageTag(msg.GetPlatformTag())
//		platform := strconv.Itoa(int(pf))
//		i := 0
//		var bulletList []*login_proto.Bulletion
//		for _, v := range BulletMgrSington.BulletMsgList {
//			if v != nil && platform == v.Platform && v.State == 1 {
//				bulletList = append(bulletList, &login_proto.Bulletion{})
//				bulletList[i].Id = proto.Int32(v.Id)
//				bulletList[i].NoticeTitle = proto.String(v.NoticeTitle)
//				bulletList[i].NoticeContent = proto.String(v.NoticeContent)
//				bulletList[i].UpdateTime = proto.String(v.UpdateTime)
//				bulletList[i].Sort = proto.Int32(v.Sort)
//
//				i++
//			}
//		}
//
//		var rawpack = &login_proto.SCBulletionInfo{
//			Id:            proto.Int(0),
//			BulletionList: bulletList,
//		}
//		proto.SetDefaults(rawpack)
//		p.SendToClient(int(login_proto.LoginPacketID_PACKET_SC_BULLETIONINFO), rawpack)
//
//	}
//	return nil
//}
//
//// 招商信息 CSCustomerInfoList
//type CSCustomerInfoListPacketFactory struct {
//}
//
//type CSCustomerInfoListHandler struct {
//}
//
//func (this *CSCustomerInfoListPacketFactory) CreatePacket() interface{} {
//	pack := &login_proto.CSCustomerInfoList{}
//	return pack
//}
//func (this *CSCustomerInfoListHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
//	logger.Logger.Trace("CSCustomerInfoListHandler Process recv ", data)
//	if _, ok := data.(*login_proto.CSCustomerInfoList); ok {
//		p := PlayerMgrSington.GetPlayer(sid)
//		if p == nil {
//			logger.Logger.Trace("CSBulletionInfoHandler p == nil ")
//			return nil
//		}
//		var customerList []*login_proto.Customer
//		i := 0
//		for _, v := range CustomerMgrSington.CustomerMsgList {
//			if v != nil && v.Platform == p.Platform && v.Status == 1 {
//				customerList = append(customerList, &login_proto.Customer{})
//				customerList[i].Id = proto.Int32(v.Id)
//				customerList[i].Nickname = proto.String(v.Nickname)
//				customerList[i].Headurl = proto.String(v.Headurl)
//				customerList[i].Ext = proto.String(v.Ext)
//				customerList[i].WeixinAccount = proto.String(v.Weixin_account)
//				customerList[i].QqAccount = proto.String(v.Qq_account)
//				i++
//			}
//		}
//		var rawpack = &login_proto.SCCustomerInfoList{
//			CustomerList: customerList,
//		}
//		proto.SetDefaults(rawpack)
//		p.SendToClient(int(login_proto.LoginPacketID_PACKET_SC_CUSTOMERINFOLIST), rawpack)
//
//	}
//	return nil
//}

type CSVerifyTypePacketFactory struct {
}

type CSVerifyTypeHandler struct {
}

func (this *CSVerifyTypePacketFactory) CreatePacket() interface{} {
	pack := &login_proto.CSVerifyType{}
	return pack
}
func (this *CSVerifyTypeHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSVerifyTypeHandler Process recv ", data)
	if msg, ok := data.(*login_proto.CSVerifyType); ok {
		pf, _, _, _, _ := PlatformMgrSingleton.GetPlatformByPackageTag(msg.GetPlatformTag())
		platform := PlatformMgrSingleton.GetPlatform(strconv.Itoa(int(pf)))
		pack := &login_proto.SCVerifyType{}
		if platform == nil {
			pack.OpRetCode = login_proto.OpResultCode_OPRC_Error
		} else {
			pack.VerifyType = proto.Int32(platform.VerifyCodeType)
			pack.OpRetCode = login_proto.OpResultCode_OPRC_Sucess
			if platform.VerifyCodeType != common.CodeTypeNo && !reTelRule.MatchString(msg.GetTel()) {
				pack := &login_proto.SCVerifyType{
					OpRetCode: login_proto.OpResultCode_OPRC_TelError,
				}
				common.SendToGate(sid, int(login_proto.LoginPacketID_PACKET_SC_VERIFYTYPE), pack, s)
				return nil
			}
		}
		common.SendToGate(sid, int(login_proto.LoginPacketID_PACKET_SC_VERIFYTYPE), pack, s)
	}
	return nil
}

type CSRegisterVerifyTypePacketFactory struct {
}

type CSRegisterVerifyTypeHandler struct {
}

func (this *CSRegisterVerifyTypePacketFactory) CreatePacket() interface{} {
	pack := &login_proto.CSRegisterVerifyType{}
	return pack
}
func (this *CSRegisterVerifyTypeHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSRegisterVerifyTypeHandler Process recv ", data)
	if msg, ok := data.(*login_proto.CSRegisterVerifyType); ok {
		pf, _, _, _, _ := PlatformMgrSingleton.GetPlatformByPackageTag(msg.GetPlatformTag())
		platform := PlatformMgrSingleton.GetPlatform(strconv.Itoa(int(pf)))
		pack := &login_proto.SCRegisterVerifyType{}
		if platform == nil {
			pack.OpRetCode = login_proto.OpResultCode_OPRC_Error
		} else {
			if platform.RegisterVerifyCodeSwitch {
				pack.VerifyType = proto.Int32(common.CodeTypeNo)
			} else {
				pack.VerifyType = proto.Int32(platform.VerifyCodeType)
			}
			pack.OpRetCode = login_proto.OpResultCode_OPRC_Sucess
		}
		common.SendToGate(sid, int(login_proto.LoginPacketID_PACKET_SC_REGISTERVERIFYTYPE), pack, s)
	}
	return nil
}

// 获取三方游戏配置
type CSGetThrGameCfgPacketFactory struct {
}

type CSGetThrGameCfgHandler struct {
}

func (this *CSGetThrGameCfgPacketFactory) CreatePacket() interface{} {
	pack := &login_proto.CSGetThrGameCfg{}
	return pack
}
func (this *CSGetThrGameCfgHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSGetThrGameCfgHandler Process recv ", data)
	if msg, ok := data.(*login_proto.CSGetThrGameCfg); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSGetThrGameCfgHandler p == nil")
			return nil
		}
		pack := &login_proto.SCGetThrGameCfg{}
		plf := msg.GetPlatform()
		//加载配置
		gps := PlatformMgrSingleton.GetGameFrees(plf)
		for _, v := range gps {
			if v.Status {
				if v.DbGameFree.GetGameRule() == 0 {
					pack.ThrGameCfg = append(pack.ThrGameCfg, &login_proto.LoginThrGameConfig{
						LogicId:   proto.Int32(v.DbGameFree.Id),
						LimitCoin: proto.Int64(v.DbGameFree.GetLimitCoin()),
					})
				}
			}
		}
		p.SendToClient(int(login_proto.LoginPacketID_PACKET_SC_GETTHRGAMECFG), pack)
	}
	return nil
}

func init() {
	//登录
	common.RegisterHandler(int(login_proto.LoginPacketID_PACKET_CS_LOGIN), &CSLoginHandler{})
	netlib.RegisterFactory(int(login_proto.LoginPacketID_PACKET_CS_LOGIN), &CSLoginPacketFactory{})
	//客服地址
	common.RegisterHandler(int(login_proto.LoginPacketID_PACKET_CS_CUSTOMSERVICE), &CSCustomServiceHandler{})
	netlib.RegisterFactory(int(login_proto.LoginPacketID_PACKET_CS_CUSTOMSERVICE), &CSCustomServicePacketFactory{})
	//平台配置信息
	common.RegisterHandler(int(login_proto.LoginPacketID_PACKET_CS_PLATFORMCFG), &CSPlatFormHandler{})
	netlib.RegisterFactory(int(login_proto.LoginPacketID_PACKET_CS_PLATFORMCFG), &CSPlatFormPacketFactory{})
	////公告信息
	//common.RegisterHandler(int(login_proto.LoginPacketID_PACKET_CS_BULLETIONINFO), &CSBulletionInfoHandler{})
	//netlib.RegisterFactory(int(login_proto.LoginPacketID_PACKET_CS_BULLETIONINFO), &CSBulletionInfoPacketFactory{})
	////招商信息
	//common.RegisterHandler(int(login_proto.LoginPacketID_PACKET_CS_CUSTOMERINFOLIST), &CSCustomerInfoListHandler{})
	//netlib.RegisterFactory(int(login_proto.LoginPacketID_PACKET_CS_CUSTOMERINFOLIST), &CSCustomerInfoListPacketFactory{})

	// 获取验证码配置
	common.RegisterHandler(int(login_proto.LoginPacketID_PACKET_CS_VERIFYTYPE), &CSVerifyTypeHandler{})
	netlib.RegisterFactory(int(login_proto.LoginPacketID_PACKET_CS_VERIFYTYPE), &CSVerifyTypePacketFactory{})

	// 获取登录验证码类型
	common.RegisterHandler(int(login_proto.LoginPacketID_PACKET_CS_REGISTERVERIFYTYPE), &CSRegisterVerifyTypeHandler{})
	netlib.RegisterFactory(int(login_proto.LoginPacketID_PACKET_CS_REGISTERVERIFYTYPE), &CSRegisterVerifyTypePacketFactory{})

	//获取三方游戏配置
	common.RegisterHandler(int(login_proto.LoginPacketID_PACKET_CS_GETTHRGAMECFG), &CSGetThrGameCfgHandler{})
	netlib.RegisterFactory(int(login_proto.LoginPacketID_PACKET_CS_GETTHRGAMECFG), &CSGetThrGameCfgPacketFactory{})
}
