128 lines
3.8 KiB
Go
128 lines
3.8 KiB
Go
package server
|
||
|
||
import (
|
||
"encoding/json"
|
||
"game/common/model/user"
|
||
"game/common/proto/pb"
|
||
"game/common/rpcName"
|
||
"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](rpcName.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("收到rcp:%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,
|
||
}
|
||
rpcMsg = ipb.MakeRpcMsg[user.UserAccount](rpcName.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", rpcName.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 uint, username string) (string, error) {
|
||
_ = userID
|
||
_ = username
|
||
// 这里应该使用JWT库生成实际令牌
|
||
// 简化实现,实际项目中请使用安全的JWT实现
|
||
return "generated-token-placeholder", nil
|
||
}
|
||
|
||
// 登录或注册
|
||
func (s *LoginService) onLoginOrRegister(iMsg *ipb.InternalMsg, req *pb.C2SUserLogin) {
|
||
ksync.GoSafe(func() {
|
||
us, code, node := s.checkLoginOrRegister(req)
|
||
userId := int64(0)
|
||
rsp := &pb.S2CUserLogin{Code: code}
|
||
if us != nil && code == pb.ErrCode_OK {
|
||
rsp.UserId = int64(us.ID)
|
||
rsp.Token, _ = generateToken(us.ID, us.Username)
|
||
userId = rsp.UserId
|
||
}
|
||
s.SendServiceMsg(service.TopicEx(iMsg.ServiceName), iMsg.ConnId, userId, int32(pb.MsgId_S2CUserLoginId), rsp)
|
||
|
||
if us != nil && us.ID > 0 {
|
||
switch code {
|
||
case pb.ErrCode_LoginUserOrPwdErr:
|
||
rpcMsg := ipb.MakeRpcMsg[user.UserLoginLog](rpcName.GetUserAccount, 0, &user.UserLoginLog{
|
||
UID: us.ID,
|
||
LoginIP: us.LastLoginIP,
|
||
LoginTime: time.Now(),
|
||
DeviceInfo: us.DeviceID,
|
||
LoginResult: code == pb.ErrCode_OK,
|
||
FailReason: code.String(),
|
||
})
|
||
_, _ = s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
|
||
}
|
||
}
|
||
|
||
}, nil)
|
||
}
|