func register(conn *GxTcpConn, msg *GxMessage) error {
	rdClient := PopRedisClient()
	defer PushRedisClient(rdClient)

	var req LoginServerReq
	err := msg.UnpackagePbmsg(&req)
	if err != nil {
		Debug("UnpackagePbmsg error")
		return errors.New("close")
	}

	player := new(Player)
	err = player.Get(rdClient, req.Raw.GetUsername())
	if err == nil {
		Debug("user has been exists, username: %s", req.GetRaw().GetUsername())
		SendPbMessage(conn, false, 0, CmdRegister, msg.GetSeq(), RetUserExists, nil)
		return errors.New("close")
	}

	player = NewPlayer(rdClient, req.Raw.GetUsername(), req.GetRaw().GetPwd())
	player.Save(rdClient)

	Debug("new user: %s login from %s", req.Raw.GetUsername(), conn.Conn.RemoteAddr().String())
	SendPbMessage(conn, false, 0, CmdRegister, msg.GetSeq(), RetSucc, &LoginServerRsp{
		Info: &LoginRspInfo{
			Token: proto.String(player.SaveToken(rdClient)),
		},
	})
	return errors.New("close")
}
func ServerConnectGateCallback(conn *GxTcpConn, msg *GxMessage) error {
	//register server
	var req ServerConnectGateReq
	err := msg.UnpackagePbmsg(&req)
	if err != nil {
		SendPbMessage(conn, false, 0, msg.GetCmd(), msg.GetSeq(), RetFail, nil)
		return err
	}

	conn.Data = make([]interface{}, len(req.Cmds))
	mutex.Lock()
	for i := 0; i < len(req.Cmds); i++ {
		//保存自己处理的消息cmd
		conn.Data[i] = req.Cmds[i]

		cmd := uint16(req.Cmds[i])
		cmdinfo, ok := CmdServers[cmd]
		if !ok {
			CmdServers[cmd] = make(ServersInfo)
			cmdinfo, _ = CmdServers[cmd]
		}
		cmdinfo[req.GetId()] = conn
	}
	mutex.Unlock()

	SendPbMessage(conn, false, 0, msg.GetCmd(), msg.GetSeq(), RetSucc, nil)
	return nil
}
func GetRoleListCallback(conn *GxTcpConn, info *LoginInfo, msg *GxMessage) {
	rdClient := PopRedisClient()
	defer PushRedisClient(rdClient)

	var req GetRoleListReq
	var rsp GetRoleListRsp
	err := msg.UnpackagePbmsg(&req)
	if err != nil {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetFail, nil)
		return
	}
	if req.Info == nil || req.GetInfo().Token == nil || req.ServerId == nil {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetMsgFormatError, nil)
		return
	}

	playerName := CheckToken(rdClient, req.GetInfo().GetToken())
	if playerName == "" {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetTokenError, nil)
		return
	}

	player := new(Player)
	err = player.Get(rdClient, playerName)
	if err != nil {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetUserNotExists, nil)
		return
	}

	ids := GetRoleList(rdClient, playerName, req.GetServerId())
	for i := 0; i < len(ids); i++ {
		id, _ := strconv.Atoi(ids[i])

		role := new(Role)
		err = role.Get(rdClient, uint32(id))
		if err != nil {
			Debug("role %d is not existst", id)
			continue
		}
		rsp.Roles = append(rsp.Roles, &RoleCommonInfo{
			Id:         proto.Uint32(role.Id),
			Name:       proto.String(role.Name),
			Level:      proto.Uint32(role.Level),
			VocationId: proto.Uint32(role.VocationId),
		})
	}

	info.PlayerName = playerName
	info.BeginTs = time.Now().Unix()
	info.ServerId = req.GetServerId()
	SaveGateLoginInfo(rdClient, info.GateId, info.ConnId, playerName)
	info.Save(rdClient)

	SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetSucc, &rsp)
}
func SelectRoleCallback(conn *GxTcpConn, info *LoginInfo, msg *GxMessage) {
	rdClient := PopRedisClient()
	defer PushRedisClient(rdClient)

	var req SelectRoleReq

	err := msg.UnpackagePbmsg(&req)
	if err != nil {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetFail, nil)
		return
	}

	if req.RoleId == nil {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetMsgFormatError, nil)
		return
	}

	if req.Info != nil && req.GetInfo().Token != nil {
		//重新重连
		ret := DisconnLogin(rdClient, req.GetInfo().GetToken(), info)
		if ret != RetSucc {
			SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), ret, nil)
			return
		}
	}

	role := new(Role)
	err = role.Get(rdClient, req.GetRoleId())
	if err != nil {
		Debug("role %d is not existst", req.GetRoleId())
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetRoleNotExists, nil)
		return
	}

	info.RoleId = req.GetRoleId()
	info.Save(rdClient)

	SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetSucc, &SelectRoleRsp{
		Role: &RoleCommonInfo{
			Id:         proto.Uint32(role.Id),
			Name:       proto.String(role.Name),
			Level:      proto.Uint32(role.Level),
			VocationId: proto.Uint32(role.VocationId),
			Expr:       proto.Uint64(role.Expr),
			GodValue:   proto.Uint64(role.GodValue),
			Prestige:   proto.Uint64(role.Prestige),
			Gold:       proto.Uint64(role.Gold),
			Crystal:    proto.Uint64(role.Crystal),
		},
	})

}
func (conn *GxTcpConn) SaveProcessMsg(msg *GxMessage) {
	if !conn.MessageCtrl {
		return
	}

	conn.mutex.Lock()
	defer conn.mutex.Unlock()

	//服务端发送的通知seq为0
	if msg.GetMask(MessageMaskNotify) {
		return
	}

	if conn.msg == nil {
		conn.msg = msg
	} else {
		if conn.msg.GetSeq() == msg.GetSeq() && conn.msg.GetCmd() == msg.GetCmd() {
			conn.msg = nil
		}
	}

}
func CreateRoleCallback(conn *GxTcpConn, info *LoginInfo, msg *GxMessage) {
	rdClient := PopRedisClient()
	defer PushRedisClient(rdClient)

	var req CreateRoleReq

	err := msg.UnpackagePbmsg(&req)
	if err != nil {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetFail, nil)
		return
	}

	if req.Name == nil || req.VocationId == nil {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetMsgFormatError, nil)
		return
	}

	if req.Info != nil && req.GetInfo().Token != nil {
		//重新重连
		ret := DisconnLogin(rdClient, req.GetInfo().GetToken(), info)
		if ret != RetSucc {
			SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), ret, nil)
			return
		}
	}

	ids := GetRoleList(rdClient, info.PlayerName, info.ServerId)
	if len(ids) > 0 {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetRoleExists, nil)
		return
	}

	if CheckRoleNameConflict(rdClient, req.GetName()) {
		SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetRoleNameConflict, nil)
		return
	}

	role := &Role{
		Id:           NewRoleID(rdClient),
		PlayerName:   info.PlayerName,
		GameServerId: info.ServerId,
		Name:         req.GetName(),
		VocationId:   req.GetVocationId(),
		Level:        0,
		Expr:         0,
		GodValue:     0,
		Prestige:     0,
		Gold:         10000,
		Crystal:      0,
	}
	role.Save(rdClient)
	SaveRoleName(rdClient, role.Name)
	//
	info.RoleId = role.Id
	info.Save(rdClient)
	//
	SendPbMessage(conn, false, msg.GetId(), msg.GetCmd(), msg.GetSeq(), RetSucc, &CreateRoleRsp{
		Role: &RoleCommonInfo{
			Id:         proto.Uint32(role.Id),
			Name:       proto.String(role.Name),
			Level:      proto.Uint32(role.Level),
			VocationId: proto.Uint32(role.VocationId),
			Expr:       proto.Uint64(role.Expr),
			GodValue:   proto.Uint64(role.GodValue),
			Prestige:   proto.Uint64(role.Prestige),
			Gold:       proto.Uint64(role.Gold),
			Crystal:    proto.Uint64(role.Crystal),
		},
	})
}
func login(conn *GxTcpConn, msg *GxMessage) error {
	rdClient := PopRedisClient()
	defer PushRedisClient(rdClient)

	var req LoginServerReq
	var rsp LoginServerRsp
	err := msg.UnpackagePbmsg(&req)
	if err != nil {
		Debug("UnpackagePbmsg error")
		return errors.New("close")
	}

	player := new(Player)
	err = player.Get(rdClient, req.GetRaw().GetUsername())
	if err != nil {
		Debug("user is not exists, username: %s", req.GetRaw().GetUsername())
		SendPbMessage(conn, false, 0, CmdLogin, msg.GetSeq(), RetUserNotExists, nil)
		return errors.New("close")
	}

	if !player.VerifyPassword(req.GetRaw().GetPwd()) {
		SendPbMessage(conn, false, 0, CmdLogin, msg.GetSeq(), RetPwdError, nil)
		return errors.New("close")
	}

	Debug("old user: %s login from %s", req.GetRaw().GetUsername(), conn.Conn.RemoteAddr().String())

	rsp.Info = &LoginRspInfo{
		Token: proto.String(player.SaveToken(rdClient)),
	}

	var gates []*GateInfo
	GetAllGate(rdClient, &gates)
	var gate *GateInfo = nil
	for i := 0; i < len(gates); i++ {
		if (time.Now().Unix() - gates[i].Ts) > 10 {
			continue
		}
		if gate == nil {
			gate = gates[i]
		} else {
			if gate.Count > gates[i].Count {
				gate = gates[i]
			}
		}
	}
	if gate != nil {
		rsp.GetInfo().Host = proto.String(gate.Host1)
		rsp.GetInfo().Port = proto.Uint32(gate.Port1)
	}
	// 	optional uint32 index = 1; //区号.
	// optional string name = 2; //服务器名称.
	// optional uint32 statue = 3; //服务器状态.
	// optional uint32 lastts = 4; //最近登录时间.

	var servers []*GameServer
	GetAllGameServer(rdClient, &servers)
	for i := 0; i < len(servers); i++ {
		rsp.GetInfo().Srvs = append(rsp.GetInfo().Srvs, &GameSrvInfo{
			Index:  proto.Uint32(servers[i].Id),
			Name:   proto.String(servers[i].Name),
			Status: proto.Uint32(servers[i].Status),
			Lastts: proto.Uint32(0),
		})
	}

	SendPbMessage(conn, false, 0, CmdLogin, msg.GetSeq(), RetSucc, &rsp)
	return errors.New("close")
}