添加db服
This commit is contained in:
parent
02d1811d50
commit
da1f14b7dd
21
common/serialization/serialization.go
Normal file
21
common/serialization/serialization.go
Normal file
@ -0,0 +1,21 @@
|
||||
package serialization
|
||||
|
||||
import "reflect"
|
||||
|
||||
func StructToMap(obj interface{}) map[string]interface{} {
|
||||
out := make(map[string]interface{})
|
||||
v := reflect.ValueOf(obj)
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
t := v.Type()
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
key := field.Tag.Get("json") // 使用 json tag 作为字段名
|
||||
if key == "" {
|
||||
key = field.Name
|
||||
}
|
||||
out[key] = v.Field(i).Interface()
|
||||
}
|
||||
return out
|
||||
}
|
28
server/client/server/chat.go
Normal file
28
server/client/server/chat.go
Normal file
@ -0,0 +1,28 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"game/common/proto/pb"
|
||||
"github.com/fox/fox/log"
|
||||
)
|
||||
|
||||
func (s *ClientService) chat() {
|
||||
//const content = "hello world"
|
||||
//s.SendMsg(pb.ServiceTypeId_STI_Chat, int32(pb.MsgId_C2SChatId), &pb.C2SChat{
|
||||
// SrcUser: s.userId,
|
||||
// DstUser: nil,
|
||||
// Type: 0,
|
||||
// GameId: 0,
|
||||
// Content: "",
|
||||
//})
|
||||
}
|
||||
|
||||
// 收到登陆成功消息,判断是否顶号
|
||||
func (s *ClientService) onChat(cMsg *pb.ClientMsg, msg *pb.S2CUserLogin) {
|
||||
if msg.Code != pb.ErrCode_OK {
|
||||
log.ErrorF("login error: %v", msg.Code)
|
||||
return
|
||||
}
|
||||
_ = cMsg
|
||||
s.userId = msg.UserId
|
||||
log.DebugF("user:%v id:%v login success", s.username, msg.UserId)
|
||||
}
|
@ -10,21 +10,3 @@ func (s *ClientService) initProcessor() {
|
||||
pb.MsgId_S2CUserLoginId: {pb.S2CUserLogin{}, s.onLogin},
|
||||
})
|
||||
}
|
||||
|
||||
// 收到登陆成功消息,判断是否顶号
|
||||
func (s *ClientService) onChat(uid int64, msg *pb.C2SChat) {
|
||||
_ = uid
|
||||
_ = msg
|
||||
//switch msg.Type {
|
||||
//case pb.ChatType_CT_Private:
|
||||
// sName, err := s.bindService.FindServiceName(msg.DstUser.UserId, pb.ServiceTypeId_STI_Gate)
|
||||
// if err != nil {
|
||||
// log.DebugF("find user:%v in gate err: %v", uid, err)
|
||||
// return
|
||||
// }
|
||||
// s.SendServiceMsg(service.TopicEx(sName), msg.DstUser.UserId, int32(pb.MsgId_S2CChatId), msg)
|
||||
//default:
|
||||
// s.SendServiceMsg(service.TopicEx(topicName.WorldMessage), uid, int32(pb.MsgId_S2CChatId), msg)
|
||||
//}
|
||||
|
||||
}
|
||||
|
32
server/db/cmd/cmd.go
Normal file
32
server/db/cmd/cmd.go
Normal file
@ -0,0 +1,32 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"game/server/db/config"
|
||||
"game/server/db/model"
|
||||
"game/server/db/server"
|
||||
"github.com/fox/fox/log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func initRepo() {
|
||||
model.InitRedis()
|
||||
model.InitDb()
|
||||
}
|
||||
|
||||
func Run(GitCommit, GitBranch, BuildDate string) {
|
||||
config.InitLog()
|
||||
config.LoadConfig(GitCommit, GitBranch, BuildDate)
|
||||
log.Info(fmt.Sprintf("版本分支:%v,hash值:%v,编译时间:%v", GitBranch, GitCommit, BuildDate))
|
||||
initRepo()
|
||||
|
||||
server.Init()
|
||||
// 截获 SIGINT 和 SIGTERM 信号
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
||||
sig := <-c
|
||||
server.Stop()
|
||||
log.Info(fmt.Sprintf("received %s, initiating shutdown...", sig))
|
||||
}
|
37
server/db/config/config.go
Normal file
37
server/db/config/config.go
Normal file
@ -0,0 +1,37 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"game/common/config"
|
||||
"github.com/fox/fox/db"
|
||||
"github.com/fox/fox/log"
|
||||
)
|
||||
|
||||
var Command *config.Command
|
||||
var Cfg *config.Common[DbConfig]
|
||||
|
||||
type DbConfig struct {
|
||||
}
|
||||
|
||||
func InitLog() {
|
||||
log.Open("./log/db.log", log.DebugL)
|
||||
log.Info("")
|
||||
log.Info("")
|
||||
log.Info("")
|
||||
log.Info("-----init log success-----")
|
||||
}
|
||||
|
||||
func LoadConfig(GitCommit, GitBranch, BuildDate string) {
|
||||
Command = config.ParseCommand()
|
||||
rdb, err := db.InitRedis(Command.RedisPassword, Command.RedisHost, Command.RedisPort, 0)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return
|
||||
}
|
||||
defer func() { _ = rdb.Close() }()
|
||||
Cfg, err = config.LoadCommonConfig[DbConfig](rdb, GitCommit, GitBranch, BuildDate)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return
|
||||
}
|
||||
log.DebugF("load common config success")
|
||||
}
|
24
server/db/main.go
Normal file
24
server/db/main.go
Normal file
@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"game/server/db/cmd"
|
||||
"github.com/fox/fox/ksync"
|
||||
"github.com/fox/fox/log"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
GitCommit = "unknown"
|
||||
GitBranch = "unknown"
|
||||
BuildDate = "unknown"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tm, err := time.Parse("20060102150405", BuildDate)
|
||||
if err == nil {
|
||||
BuildDate = tm.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
ksync.RunSafe(func() {
|
||||
cmd.Run(GitBranch, GitCommit, BuildDate)
|
||||
}, func() { log.ErrorF("reset run") })
|
||||
}
|
59
server/db/model/db.go
Normal file
59
server/db/model/db.go
Normal file
@ -0,0 +1,59 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"game/server/db/config"
|
||||
"github.com/fox/fox/db"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
UserRedis *redis.Client
|
||||
UserDB *gorm.DB
|
||||
LogDB *gorm.DB
|
||||
)
|
||||
|
||||
func InitRedis() {
|
||||
log.Debug("init redis")
|
||||
var err error
|
||||
cfg := &config.Cfg.Redis
|
||||
UserRedis, err = db.InitRedis(cfg.Password, cfg.Host, cfg.Port, 0)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func InitDb() {
|
||||
log.Debug("init db")
|
||||
var err error
|
||||
cfg := &config.Cfg.Mysql
|
||||
UserDB, err = db.InitMysql(cfg.Username, cfg.Password, cfg.Host, cfg.Port, cfg.DbName)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
cfg = &config.Cfg.MysqlLog
|
||||
LogDB, err = db.InitMysql(cfg.Username, cfg.Password, cfg.Host, cfg.Port, cfg.DbName)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
// 自动迁移game库表结构
|
||||
err = UserDB.AutoMigrate(
|
||||
&UserAccount{},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
// 自动迁移game_log库表结构
|
||||
err = LogDB.AutoMigrate(
|
||||
&UserLoginLog{},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
148
server/db/model/tableOption.go
Normal file
148
server/db/model/tableOption.go
Normal file
@ -0,0 +1,148 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"game/common/proto/pb"
|
||||
"game/common/serialization"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
tableExpire = 7 * 24 * time.Hour // 七天后过期
|
||||
)
|
||||
|
||||
type resultT[T any] struct {
|
||||
ret T
|
||||
//err error
|
||||
}
|
||||
|
||||
type iTable interface {
|
||||
GetId() uint
|
||||
}
|
||||
|
||||
/*
|
||||
T:Table,如果不想操作redis则将rds设置为nil
|
||||
*/
|
||||
type TableOp[T iTable] struct {
|
||||
db *gorm.DB
|
||||
rds *redis.Client
|
||||
}
|
||||
|
||||
func newTableOp[T iTable](db *gorm.DB, rds *redis.Client) *TableOp[T] {
|
||||
return &TableOp[T]{db: db, rds: rds}
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) tableName() string {
|
||||
var result resultT[T]
|
||||
return s.db.Model(&result.ret).Statement.Table
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) redisKey(id uint) string {
|
||||
return fmt.Sprintf("%s:%d", s.tableName(), id)
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) findByRedis(id uint) *T {
|
||||
if s.rds == nil {
|
||||
return nil
|
||||
}
|
||||
maps, err := s.rds.HGetAll(context.Background(), s.redisKey(id)).Result()
|
||||
if err != nil {
|
||||
log.ErrorF("redis-key:%v HGetAll err: %v", s.redisKey(id), err)
|
||||
return nil
|
||||
}
|
||||
if len(maps) == 0 {
|
||||
return nil
|
||||
}
|
||||
jsonByte, _ := json.Marshal(maps)
|
||||
var result resultT[T]
|
||||
_ = json.Unmarshal(jsonByte, &result.ret)
|
||||
return &result.ret
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) writeRedis(id uint, t *T) {
|
||||
if s.rds == nil {
|
||||
return
|
||||
}
|
||||
maps := serialization.StructToMap(t)
|
||||
if len(maps) == 0 {
|
||||
log.ErrorF("table struct is empty:%v", s.tableName())
|
||||
}
|
||||
s.updateRedis(id, maps)
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) updateRedis(id uint, maps map[string]any) {
|
||||
if s.rds == nil {
|
||||
return
|
||||
}
|
||||
if err := s.rds.HMSet(context.Background(), s.redisKey(id), maps).Err(); err != nil {
|
||||
log.ErrorF("redis-key:%v HMSet err: %v", s.redisKey(id), err)
|
||||
}
|
||||
_ = s.rds.Expire(context.Background(), s.redisKey(id), tableExpire).Err()
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) deleteRedis(id uint) {
|
||||
if s.rds == nil {
|
||||
return
|
||||
}
|
||||
_ = s.rds.Del(context.Background(), s.redisKey(id)).Err()
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) Create(t *T) (*T, pb.ErrCode) {
|
||||
if err := s.db.Create(t).Error; err != nil {
|
||||
log.ErrorF("create table:%v err:%v", s.tableName(), err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
return t, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) Find(id uint) (*T, pb.ErrCode) {
|
||||
// 先从redis中查询,redis中没有则从mysql中查询
|
||||
if table := s.findByRedis(id); table != nil {
|
||||
return table, pb.ErrCode_OK
|
||||
}
|
||||
var result resultT[T]
|
||||
err := s.db.Where("id = ?", id).First(&result.ret).Error
|
||||
if err != nil {
|
||||
log.ErrorF("find table:%v id:%v err:%v", s.tableName(), id, err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
return &result.ret, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
//// 根据条件查询,只在mysql中查询,无法在redis中查询
|
||||
//func (s *TableOp[T]) FindCondition(condition map[string]any) (*T, error) {
|
||||
// var result resultT[T]
|
||||
// err := s.db.Where(condition).First(&result.ret).Error
|
||||
// if err != nil {
|
||||
// log.ErrorF("find table:%v condition:%v err:%v", s.tableName(), utils.JsonMarshal(condition), err)
|
||||
// return nil, err
|
||||
// }
|
||||
// return &result.ret, nil
|
||||
//}
|
||||
|
||||
func (s *TableOp[T]) Update(id uint, updates map[string]any) (*T, pb.ErrCode) {
|
||||
var result resultT[T]
|
||||
err := s.db.Model(&result.ret).Where("id = ?", id).Updates(updates).Error
|
||||
if err != nil {
|
||||
log.ErrorF("update table:%v id:%v err:%v", s.tableName(), id, err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
s.updateRedis(id, updates)
|
||||
return &result.ret, pb.ErrCode_OK
|
||||
}
|
||||
|
||||
func (s *TableOp[T]) Delete(id uint) (*T, pb.ErrCode) {
|
||||
var result resultT[T]
|
||||
err := s.db.Delete(&result.ret, id).Error
|
||||
if err != nil {
|
||||
log.ErrorF("delete table:%v err:%v", s.tableName(), err)
|
||||
return nil, pb.ErrCode_SystemErr
|
||||
}
|
||||
s.deleteRedis(id)
|
||||
return &result.ret, pb.ErrCode_OK
|
||||
}
|
23
server/db/model/user.go
Normal file
23
server/db/model/user.go
Normal file
@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 玩家账户表
|
||||
type User struct {
|
||||
gorm.Model
|
||||
Nickname string `gorm:"type:varchar(32);uniqueIndex;not null"` // 用户名
|
||||
AvatarUrl string `gorm:"type:varchar(255)"` // 头像
|
||||
AvatarBorder string `gorm:"type:varchar(255)"` // 头像框
|
||||
Gold int64 `gorm:"type:bigint;default:0"` // 金币
|
||||
VipExp int32 `gorm:"type:int"` // vip经验值
|
||||
}
|
||||
|
||||
func (u User) GetId() uint {
|
||||
return u.ID
|
||||
}
|
||||
|
||||
func NewUserOp() *TableOp[User] {
|
||||
return newTableOp[User](UserDB, UserRedis)
|
||||
}
|
152
server/db/model/userAccount.go
Normal file
152
server/db/model/userAccount.go
Normal file
@ -0,0 +1,152 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/fox/fox/log"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
AccountNormal = 1 // 正常
|
||||
AccountFrozen = 2 // 冻结
|
||||
AccountBanned = 3 // 封禁
|
||||
)
|
||||
|
||||
// 玩家账户表
|
||||
type UserAccount struct {
|
||||
gorm.Model
|
||||
Username string `gorm:"type:varchar(32);uniqueIndex;not null"` // 用户名
|
||||
Password string `gorm:"type:varchar(255);not null"` // 密码哈希
|
||||
Email string `gorm:"type:varchar(100)"` // 邮箱(可选)
|
||||
Phone string `gorm:"type:varchar(20)"` // 手机号(可选)
|
||||
DeviceID string `gorm:"type:varchar(64);index"` // 设备ID
|
||||
LastLoginIP string `gorm:"type:varchar(45)"` // 最后登录IP(支持IPv6)
|
||||
LastLoginTime time.Time // 最后登录时间
|
||||
Status int `gorm:"type:tinyint;default:1"` // 账号状态 1-正常 2-冻结 3-封禁
|
||||
RegisterIP string `gorm:"type:varchar(45)"` // 注册IP
|
||||
RegisterTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP"` // 注册时间
|
||||
}
|
||||
|
||||
// 玩家登录记录表
|
||||
type UserLoginLog struct {
|
||||
gorm.Model
|
||||
PlayerID uint `gorm:"index"` // 关联玩家ID
|
||||
LoginIP string `gorm:"type:varchar(45);not null"` // 登录IP
|
||||
LoginTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP"` // 登录时间
|
||||
DeviceInfo string `gorm:"type:varchar(255)"` // 设备信息(JSON格式)
|
||||
LoginResult bool // 登录结果 true-成功 false-失败
|
||||
FailReason string `gorm:"type:varchar(100)"` // 失败原因
|
||||
}
|
||||
|
||||
type UserLoginOp struct {
|
||||
db *gorm.DB
|
||||
logDb *gorm.DB
|
||||
}
|
||||
|
||||
func NewUserLoginOp() *UserLoginOp {
|
||||
return &UserLoginOp{db: UserDB, logDb: LogDB}
|
||||
}
|
||||
|
||||
var (
|
||||
ErrUserOrPassword = errors.New("user or password was error")
|
||||
ErrAccountFrozen = errors.New("account frozen")
|
||||
ErrAccountBanned = errors.New("account banned")
|
||||
)
|
||||
|
||||
func (s *UserLoginOp) Login(username, password, ip, deviceID string) (*UserAccount, error) {
|
||||
var user UserAccount
|
||||
err := s.db.Where("username = ?", username).First(&user).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 验证密码
|
||||
if err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
|
||||
s.recordLoginLog(user.ID, ip, deviceID, false, ErrUserOrPassword.Error())
|
||||
return nil, ErrUserOrPassword
|
||||
}
|
||||
// 检查账号状态
|
||||
switch user.Status {
|
||||
case AccountNormal:
|
||||
|
||||
case AccountFrozen:
|
||||
s.recordLoginLog(user.ID, ip, deviceID, false, ErrAccountFrozen.Error())
|
||||
return nil, ErrAccountFrozen
|
||||
case AccountBanned:
|
||||
s.recordLoginLog(user.ID, ip, deviceID, false, ErrAccountBanned.Error())
|
||||
return nil, ErrAccountBanned
|
||||
}
|
||||
// 更新最后登录信息
|
||||
user.LastLoginIP = ip
|
||||
user.LastLoginTime = time.Now()
|
||||
_ = s.db.Save(&user).Error
|
||||
|
||||
// 记录成功登录日志
|
||||
s.recordLoginLog(user.ID, ip, deviceID, true, "")
|
||||
|
||||
// 6. 生成访问令牌
|
||||
token, err := generateToken(user.ID, user.Username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user.Password = token
|
||||
return &user, err
|
||||
}
|
||||
|
||||
// 注册新用户
|
||||
func (s *UserLoginOp) RegisterNewUser(username, password, ip, deviceID string) (*UserAccount, error) {
|
||||
// 密码加密
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user := UserAccount{
|
||||
Username: username,
|
||||
Password: string(hashedPassword),
|
||||
DeviceID: deviceID,
|
||||
RegisterIP: ip,
|
||||
Status: 1,
|
||||
LastLoginIP: ip,
|
||||
LastLoginTime: time.Now(),
|
||||
}
|
||||
|
||||
if err := s.db.Create(&user).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.recordLoginLog(user.ID, ip, deviceID, true, "")
|
||||
|
||||
// 生成访问令牌
|
||||
token, err := generateToken(user.ID, user.Username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user.Password = token
|
||||
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// 记录登录日志
|
||||
func (s *UserLoginOp) recordLoginLog(userID uint, ip, deviceID string, success bool, failReason string) {
|
||||
logEntry := UserLoginLog{
|
||||
PlayerID: userID,
|
||||
LoginIP: ip,
|
||||
DeviceInfo: deviceID,
|
||||
LoginResult: success,
|
||||
FailReason: failReason,
|
||||
}
|
||||
|
||||
if err := s.logDb.Create(&logEntry).Error; err != nil {
|
||||
log.ErrorF("记录登录日志失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 生成JWT令牌(简化版)
|
||||
func generateToken(userID uint, username string) (string, error) {
|
||||
_ = userID
|
||||
_ = username
|
||||
// 这里应该使用JWT库生成实际令牌
|
||||
// 简化实现,实际项目中请使用安全的JWT实现
|
||||
return "generated-token-placeholder", nil
|
||||
}
|
57
server/db/server/processor.go
Normal file
57
server/db/server/processor.go
Normal file
@ -0,0 +1,57 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"game/common/proto/pb"
|
||||
"game/server/db/model"
|
||||
"github.com/fox/fox/ipb"
|
||||
"github.com/fox/fox/processor"
|
||||
"github.com/fox/fox/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (s *DbService) initProcessor() {
|
||||
s.processor.RegisterMessages(processor.RegisterMetas{
|
||||
pb.MsgId_C2SUserLoginId: {pb.C2SUserLogin{}, s.onLoginOrRegister},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *DbService) checkLoginOrRegister(req *pb.C2SUserLogin) (user *model.UserAccount, code pb.ErrCode) {
|
||||
op := model.NewUserLoginOp()
|
||||
var err error
|
||||
user, err = op.Login(req.Username, req.Password, req.Ip, req.DeviceId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
user, err = op.RegisterNewUser(req.Username, req.Password, req.Ip, req.DeviceId)
|
||||
if err != nil {
|
||||
code = pb.ErrCode_RegisterUserExist
|
||||
return
|
||||
}
|
||||
} else if errors.Is(err, model.ErrUserOrPassword) {
|
||||
code = pb.ErrCode_LoginUserOrPwdErr
|
||||
return
|
||||
} else if errors.Is(err, model.ErrAccountFrozen) {
|
||||
code = pb.ErrCode_AccountFrozen
|
||||
return
|
||||
} else if errors.Is(err, model.ErrAccountBanned) {
|
||||
code = pb.ErrCode_AccountBanned
|
||||
return
|
||||
} else {
|
||||
code = pb.ErrCode_SystemErr
|
||||
}
|
||||
}
|
||||
return user, code
|
||||
}
|
||||
|
||||
// 登录或注册
|
||||
func (s *DbService) onLoginOrRegister(iMsg *ipb.InternalMsg, req *pb.C2SUserLogin) {
|
||||
user, code := s.checkLoginOrRegister(req)
|
||||
userId := int64(0)
|
||||
rsp := &pb.S2CUserLogin{Code: code}
|
||||
if user != nil && code == pb.ErrCode_OK {
|
||||
rsp.UserId = int64(user.ID)
|
||||
rsp.Token = user.Password
|
||||
userId = rsp.UserId
|
||||
}
|
||||
s.SendServiceMsg(service.TopicEx(iMsg.ServiceName), iMsg.ConnId, userId, int32(pb.MsgId_S2CUserLoginId), rsp)
|
||||
}
|
116
server/db/server/service.go
Normal file
116
server/db/server/service.go
Normal file
@ -0,0 +1,116 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"game/common/proto/pb"
|
||||
"game/common/serviceName"
|
||||
"game/common/userBindService"
|
||||
"game/server/db/config"
|
||||
"game/server/db/model"
|
||||
"github.com/fox/fox/ipb"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/fox/fox/processor"
|
||||
"github.com/fox/fox/service"
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
var DbSrv []*DbService
|
||||
|
||||
type DbService struct {
|
||||
*service.NatsService
|
||||
processor *processor.Processor
|
||||
bindService *userBindService.UserBindService
|
||||
}
|
||||
|
||||
func Init() {
|
||||
log.DebugF("init service begin id:%v, num:%v", config.Command.ServiceId, config.Command.ServiceNum)
|
||||
for i := 0; i < config.Command.ServiceNum; i++ {
|
||||
sid := config.Command.ServiceId + i
|
||||
if srv := newLoginService(sid); srv != nil {
|
||||
DbSrv = append(DbSrv, srv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Stop() {
|
||||
for _, srv := range DbSrv {
|
||||
log.DebugF("notify stop service %v", srv.Name())
|
||||
srv.NotifyStop()
|
||||
}
|
||||
for _, srv := range DbSrv {
|
||||
srv.WaitStop()
|
||||
}
|
||||
}
|
||||
|
||||
func newLoginService(serviceId int) *DbService {
|
||||
var err error
|
||||
s := new(DbService)
|
||||
|
||||
sName := fmt.Sprintf("%v-%d", serviceName.Login, serviceId)
|
||||
if s.NatsService, err = service.NewNatsService(&service.InitNatsServiceParams{
|
||||
EtcdAddress: config.Cfg.Etcd.Address,
|
||||
EtcdUsername: "",
|
||||
EtcdPassword: "",
|
||||
NatsAddress: config.Cfg.Nats.Address,
|
||||
ServiceType: serviceName.Login,
|
||||
ServiceName: sName,
|
||||
OnFunc: s,
|
||||
TypeId: int(pb.ServiceTypeId_STI_Login),
|
||||
Version: config.Cfg.BuildDate,
|
||||
}); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
s.bindService = userBindService.NewUserBindService(model.UserRedis, s.ServiceEtcd())
|
||||
s.processor = processor.NewProcessor()
|
||||
s.initProcessor()
|
||||
s.OnInit()
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *DbService) OnInit() {
|
||||
// if err := s.NatsService.QueueSubscribe(service.GroupTopic(s), service.GroupQueue(s)); err != nil {
|
||||
// log.Error(err.Error())
|
||||
// }
|
||||
s.NatsService.Run()
|
||||
log.Debug("onInit")
|
||||
}
|
||||
|
||||
func (s *DbService) CanStop() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *DbService) OnStop() {
|
||||
s.NatsService.OnStop()
|
||||
log.Debug("OnStop")
|
||||
}
|
||||
|
||||
// 处理其它服发送过来的消息
|
||||
func (s *DbService) OnMessage(data []byte) error {
|
||||
var iMsg = &ipb.InternalMsg{}
|
||||
var err error
|
||||
if err = proto.Unmarshal(data, iMsg); err != nil {
|
||||
log.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
if req, err := s.processor.Unmarshal(iMsg.MsgId, iMsg.Msg); err == nil {
|
||||
err = s.processor.Dispatch(iMsg.MsgId, iMsg, req)
|
||||
} else {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
//log.Debug(s.Log("received message:%v", iMsg.MsgId))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 向内部服务发送消息
|
||||
func (s *DbService) SendServiceData(topic string, connId uint32, userId int64, msgId int32, data []byte) {
|
||||
iMsg := ipb.MakeMsg(s.Name(), connId, userId, msgId, data)
|
||||
_ = s.Send(topic, iMsg)
|
||||
}
|
||||
|
||||
// 向内部服务发送消息
|
||||
func (s *DbService) SendServiceMsg(topic string, connId uint32, userId int64, msgId int32, msg proto.Message) {
|
||||
data, _ := proto.Marshal(msg)
|
||||
s.SendServiceData(topic, connId, userId, msgId, data)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user