157 lines
4.7 KiB
Go
157 lines
4.7 KiB
Go
package server
|
||
|
||
import (
|
||
"encoding/json"
|
||
"game/common/model/user"
|
||
"game/common/proto/pb"
|
||
"game/common/rpc"
|
||
"game/common/utils"
|
||
"github.com/fox/fox/etcd"
|
||
"github.com/fox/fox/ipb"
|
||
"github.com/fox/fox/ksync"
|
||
"github.com/fox/fox/log"
|
||
"github.com/fox/fox/processor"
|
||
"github.com/fox/fox/service"
|
||
"time"
|
||
)
|
||
|
||
const (
|
||
timeout = time.Second * 30
|
||
)
|
||
|
||
func (s *LoginService) initProcessor() {
|
||
s.processor.RegisterMessages(processor.RegisterMetas{
|
||
pb.MsgId_C2SUserLoginId: {pb.C2SUserLogin{}, s.onLoginOrRegister},
|
||
})
|
||
}
|
||
|
||
func (s *LoginService) checkLoginOrRegister(req *pb.C2SUserLogin) (us *user.UserAccount, code pb.ErrCode, node *etcd.ServiceNode) {
|
||
var err error
|
||
node, err = s.bindService.RandServiceNode(pb.ServiceTypeId_STI_DB)
|
||
if err != nil {
|
||
log.ErrorF(s.Log("not find db service.err:%s ", err.Error()))
|
||
return nil, pb.ErrCode_SystemErr, node
|
||
}
|
||
if req.Version < "20250601123030" {
|
||
return nil, pb.ErrCode_VersionTooLow, node
|
||
}
|
||
us = &user.UserAccount{
|
||
Username: req.Username,
|
||
Password: req.Password,
|
||
DeviceID: req.DeviceId,
|
||
LastLoginIP: req.Ip,
|
||
}
|
||
rpcMsg := ipb.MakeRpcMsg[user.UserAccount](rpc.GetUserAccount, 0, us)
|
||
rspMsg, err := s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
|
||
if err != nil {
|
||
log.ErrorF(s.Log("call rpc:%v err:%s ", rpcMsg.RpcMsgId, err.Error()))
|
||
return nil, pb.ErrCode_SystemErr, node
|
||
}
|
||
_ = json.Unmarshal(rspMsg.Msg, us)
|
||
//log.DebugF("收到rpc:%v返回数据:%v", rpcName.GetUserAccount, string(rspMsg.Msg))
|
||
if us.ID == 0 {
|
||
// 没有帐号,创建帐号
|
||
us = &user.UserAccount{
|
||
Username: req.Username,
|
||
Password: req.Password,
|
||
DeviceID: req.DeviceId,
|
||
LastLoginIP: req.Ip,
|
||
LastLoginTime: time.Now(),
|
||
RegisterIP: req.Ip,
|
||
RegisterTime: time.Now(),
|
||
}
|
||
rpcMsg = ipb.MakeRpcMsg[user.UserAccount](rpc.CreateUserAccount, 0, us)
|
||
rspMsg, err = s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
|
||
if err != nil {
|
||
log.ErrorF(s.Log("call rpc:%v err:%s ", rpcMsg.RpcMsgId, err.Error()))
|
||
return nil, pb.ErrCode_SystemErr, node
|
||
}
|
||
_ = json.Unmarshal(rspMsg.Msg, us)
|
||
if us.ID == 0 {
|
||
log.ErrorF(s.Log("call rpc:%v err", rpcMsg.RpcMsgId))
|
||
return nil, pb.ErrCode_SystemErr, node
|
||
}
|
||
log.DebugF("收到rcp:%v返回数据:%v", rpc.CreateUserAccount, string(rspMsg.Msg))
|
||
}
|
||
if !utils.CheckPassword(req.Password, us.Password) {
|
||
log.ErrorF(s.Log("用户密码:%v 数据库中密码:%v", req.Password, us.Password))
|
||
return nil, pb.ErrCode_LoginUserOrPwdErr, node
|
||
}
|
||
switch us.Status {
|
||
case user.AccountFrozen:
|
||
return nil, pb.ErrCode_AccountFrozen, node
|
||
case user.AccountBanned:
|
||
return nil, pb.ErrCode_AccountBanned, node
|
||
default:
|
||
return us, pb.ErrCode_OK, node
|
||
}
|
||
}
|
||
|
||
// 生成JWT令牌(简化版)
|
||
func generateToken(userID int64, username string) (string, error) {
|
||
_ = userID
|
||
_ = username
|
||
// 这里应该使用JWT库生成实际令牌
|
||
// 简化实现,实际项目中请使用安全的JWT实现
|
||
return "generated-token-placeholder", nil
|
||
}
|
||
|
||
// 获取用户数据,如果没有则创建
|
||
func (s *LoginService) getUser(accountId int64, tName string) (*user.User, pb.ErrCode) {
|
||
us := &user.User{
|
||
AccountId: accountId,
|
||
}
|
||
rpcMsg := ipb.MakeRpcMsg[user.User](rpc.GetUserByAccountId, 0, us)
|
||
rsp, err := s.Call(service.RpcTopicEx(tName), timeout, rpcMsg)
|
||
if err != nil {
|
||
log.ErrorF(s.Log("call rpc:%v err:%s", rpcMsg.RpcMsgId, err.Error()))
|
||
return nil, pb.ErrCode_SystemErr
|
||
}
|
||
_ = json.Unmarshal(rsp.Msg, us)
|
||
if us.ID == 0 {
|
||
log.ErrorF(s.Log("call rpc:%v return:%v", rpcMsg.RpcMsgId, string(rsp.Msg)))
|
||
return us, pb.ErrCode_SystemErr
|
||
}
|
||
return us, pb.ErrCode_OK
|
||
}
|
||
|
||
// 登录或注册
|
||
func (s *LoginService) onLoginOrRegister(iMsg *ipb.InternalMsg, req *pb.C2SUserLogin) {
|
||
ksync.GoSafe(func() {
|
||
account, code, node := s.checkLoginOrRegister(req)
|
||
userId := int64(0)
|
||
rsp := &pb.S2CUserLogin{Code: code}
|
||
if account != nil && code == pb.ErrCode_OK {
|
||
// 拉取用户数据
|
||
us := &user.User{}
|
||
us, code = s.getUser(userId, req.Username)
|
||
if code == pb.ErrCode_OK {
|
||
rsp.UserId = us.ID
|
||
rsp.Token, _ = generateToken(account.ID, account.Username)
|
||
userId = rsp.UserId
|
||
}
|
||
}
|
||
s.SendServiceMsg(service.TopicEx(iMsg.ServiceName), iMsg.ConnId, userId, int32(pb.MsgId_S2CUserLoginId), rsp)
|
||
|
||
if account != nil && account.ID > 0 {
|
||
loginLog := &user.UserLoginLog{
|
||
AccountID: account.ID,
|
||
LoginIP: req.Ip,
|
||
LoginTime: time.Now(),
|
||
DeviceInfo: req.DeviceId,
|
||
LoginResult: code == pb.ErrCode_OK,
|
||
FailReason: code.String(),
|
||
}
|
||
switch code {
|
||
case pb.ErrCode_LoginUserOrPwdErr, pb.ErrCode_OK:
|
||
rpcMsg := ipb.MakeRpcMsg[user.UserLoginLog](rpc.LogUserAccountLogin, 0, loginLog)
|
||
ksync.GoSafe(func() {
|
||
_, _ = s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
|
||
}, nil)
|
||
|
||
}
|
||
}
|
||
|
||
}, nil)
|
||
}
|