工作记录

This commit is contained in:
liuxiaobo 2025-06-04 01:56:38 +08:00
parent c138d8a771
commit 9fdb2df2b6
14 changed files with 97 additions and 56 deletions

View File

@ -24,6 +24,7 @@ type resultT[T any] struct {
type iTable interface { type iTable interface {
GetId() uint GetId() uint
TableName() string
} }
/* /*
@ -40,7 +41,7 @@ func NewTableOp[T iTable](db *gorm.DB, rds *redis.Client) *TableOp[T] {
func (s *TableOp[T]) tableName() string { func (s *TableOp[T]) tableName() string {
var result resultT[T] var result resultT[T]
return s.db.Model(&result.ret).Statement.Table return result.ret.TableName()
} }
func (s *TableOp[T]) redisKey(id uint) string { func (s *TableOp[T]) redisKey(id uint) string {
@ -62,6 +63,7 @@ func (s *TableOp[T]) findByRedis(id uint) *T {
jsonByte, _ := json.Marshal(maps) jsonByte, _ := json.Marshal(maps)
var result resultT[T] var result resultT[T]
_ = json.Unmarshal(jsonByte, &result.ret) _ = json.Unmarshal(jsonByte, &result.ret)
log.DebugF("findByRedis redis-key:%v result:%v", s.redisKey(id), result.ret)
return &result.ret return &result.ret
} }
@ -110,7 +112,7 @@ func (s *TableOp[T]) Find(id uint) (*T, pb.ErrCode) {
var result resultT[T] var result resultT[T]
err := s.db.Where("id = ?", id).First(&result.ret).Error err := s.db.Where("id = ?", id).First(&result.ret).Error
if err != nil { if err != nil {
log.ErrorF("find table:%v id:%v err:%v", s.tableName(), id, err) log.DebugF("find table:%v id:%v err:%v", s.tableName(), id, err)
return nil, pb.ErrCode_SystemErr return nil, pb.ErrCode_SystemErr
} }
return &result.ret, pb.ErrCode_OK return &result.ret, pb.ErrCode_OK

View File

@ -6,7 +6,7 @@ import (
// 玩家账户表 // 玩家账户表
type User struct { type User struct {
gorm.Model gorm.Model `json:"-"`
accountId uint `gorm:"type:bigint;uniqueIndex;not null"` // 帐号id accountId uint `gorm:"type:bigint;uniqueIndex;not null"` // 帐号id
Nickname string `gorm:"type:varchar(32);uniqueIndex;not null"` // 昵称 Nickname string `gorm:"type:varchar(32);uniqueIndex;not null"` // 昵称
AvatarUrl string `gorm:"type:varchar(255)"` // 头像 AvatarUrl string `gorm:"type:varchar(255)"` // 头像
@ -17,3 +17,7 @@ type User struct {
func (u User) GetId() uint { func (u User) GetId() uint {
return u.ID return u.ID
} }
func (u User) TableName() string {
return "user"
}

View File

@ -1,7 +1,6 @@
package user package user
import ( import (
"gorm.io/gorm"
"time" "time"
) )
@ -13,34 +12,42 @@ const (
// 玩家账户表 // 玩家账户表
type UserAccount struct { type UserAccount struct {
gorm.Model ID uint `gorm:"primarykey" json:"id,omitempty"`
Username string `gorm:"type:varchar(32);uniqueIndex;not null"` // 用户名 Username string `gorm:"type:varchar(32);uniqueIndex;not null" json:"username,omitempty"` // 用户名
Password string `gorm:"type:varchar(255);not null"` // 密码哈希 Password string `gorm:"type:varchar(255);not null" json:"password,omitempty"` // 密码哈希
Email string `gorm:"type:varchar(100)"` // 邮箱(可选) Email string `gorm:"type:varchar(100)" json:"email,omitempty"` // 邮箱(可选)
Phone string `gorm:"type:varchar(20)"` // 手机号(可选) Phone string `gorm:"type:varchar(20)" json:"phone,omitempty"` // 手机号(可选)
DeviceID string `gorm:"type:varchar(64);index"` // 设备ID DeviceID string `gorm:"type:varchar(64);index" json:"device_id"` // 设备ID
LastLoginIP string `gorm:"type:varchar(45)"` // 最后登录IP(支持IPv6) LastLoginIP string `gorm:"type:varchar(45)" json:"last_login_ip"` // 最后登录IP(支持IPv6)
LastLoginTime time.Time // 最后登录时间 LastLoginTime time.Time `json:"last_login_time,omitempty"` // 最后登录时间
Status int `gorm:"type:tinyint;default:1"` // 账号状态 1-正常 2-冻结 3-封禁 Status int `gorm:"type:tinyint;default:1" json:"status,omitempty"` // 账号状态 1-正常 2-冻结 3-封禁
RegisterIP string `gorm:"type:varchar(45)"` // 注册IP RegisterIP string `gorm:"type:varchar(45)" json:"register_ip,omitempty"` // 注册IP
RegisterTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP"` // 注册时间 RegisterTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP" json:"register_time"` // 注册时间
} }
func (u UserAccount) GetId() uint { func (u UserAccount) GetId() uint {
return u.ID return u.ID
} }
func (u UserAccount) TableName() string {
return "user_account"
}
// 玩家登录记录表 // 玩家登录记录表
type UserLoginLog struct { type UserLoginLog struct {
gorm.Model ID uint `gorm:"primarykey" json:"id"`
UID uint `gorm:"index"` // 关联玩家ID UID uint `gorm:"index" json:"uid"` // 关联玩家ID
LoginIP string `gorm:"type:varchar(45);not null"` // 登录IP LoginIP string `gorm:"type:varchar(45);not null" json:"login_ip"` // 登录IP
LoginTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP"` // 登录时间 LoginTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP" json:"login_time"` // 登录时间
DeviceInfo string `gorm:"type:varchar(255)"` // 设备信息(JSON格式) DeviceInfo string `gorm:"type:varchar(255)" json:"device_info"` // 设备信息(JSON格式)
LoginResult bool // 登录结果 true-成功 false-失败 LoginResult bool `json:"login_result"` // 登录结果 true-成功 false-失败
FailReason string `gorm:"type:varchar(100)"` // 失败原因 FailReason string `gorm:"type:varchar(100)" json:"fail_reason"` // 失败原因
} }
func (u UserLoginLog) GetId() uint { func (u UserLoginLog) GetId() uint {
return u.ID return u.ID
} }
func (u UserLoginLog) TableName() string {
return "user_login_log"
}

View File

@ -6,7 +6,7 @@ import (
// 玩家账户表 // 玩家账户表
type UserResources struct { type UserResources struct {
gorm.Model gorm.Model `json:"-"`
accountId uint `gorm:"type:bigint;uniqueIndex;not null"` // 帐号id accountId uint `gorm:"type:bigint;uniqueIndex;not null"` // 帐号id
Nickname string `gorm:"type:varchar(32);uniqueIndex;not null"` // 昵称 Nickname string `gorm:"type:varchar(32);uniqueIndex;not null"` // 昵称
AvatarUrl string `gorm:"type:varchar(255)"` // 头像 AvatarUrl string `gorm:"type:varchar(255)"` // 头像
@ -17,3 +17,7 @@ type UserResources struct {
func (u UserResources) GetId() uint { func (u UserResources) GetId() uint {
return u.ID return u.ID
} }
func (u UserResources) TableName() string {
return "user_resources"
}

View File

@ -10,5 +10,11 @@ func Password(password string) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
//log.DebugF("原始密码:%v,加密后密码:%v", password, string(hashedPassword))
return string(hashedPassword), nil return string(hashedPassword), nil
} }
func CheckPassword(password, hashedPassword string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
return err == nil // 返回 true 表示密码匹配
}

View File

@ -12,14 +12,14 @@ func (s *ClientService) login() {
Password: s.password, Password: s.password,
Ip: "", Ip: "",
DeviceId: "", DeviceId: "",
Version: "", Version: "20250604123030",
}) })
} }
// 收到登陆成功消息,判断是否顶号 // 收到登陆成功消息,判断是否顶号
func (s *ClientService) onLogin(cMsg *pb.ClientMsg, msg *pb.S2CUserLogin) { func (s *ClientService) onLogin(cMsg *pb.ClientMsg, msg *pb.S2CUserLogin) {
if msg.Code != pb.ErrCode_OK { if msg.Code != pb.ErrCode_OK {
log.ErrorF("login error: %v", msg.Code) log.ErrorF("login error:%v :%v", msg.Code, msg.Code.String())
return return
} }
_ = cMsg _ = cMsg

View File

@ -50,7 +50,7 @@ func newClientService(serviceId int) *ClientService {
addr := config.Cfg.Special.Address[serviceId%size] addr := config.Cfg.Special.Address[serviceId%size]
wsAddr := fmt.Sprintf("ws://%v", addr) wsAddr := fmt.Sprintf("ws://%v", addr)
if s.client, err = ws.NewClient(wsAddr, s); err != nil { if s.client, err = ws.NewClient(wsAddr, s); err != nil {
log.Fatal(err.Error()) log.FatalF("connect url:%v err:%v", wsAddr, err.Error())
return nil return nil
} }
s.processor = processor.NewProcessor() s.processor = processor.NewProcessor()

View File

@ -75,6 +75,7 @@ func (s *UserAccountOp) CreateUserAccount(us *user.UserAccount) (*user.UserAccou
us.Password = hashedPassword us.Password = hashedPassword
var code pb.ErrCode var code pb.ErrCode
us, code = s.accountOp.Create(us) us, code = s.accountOp.Create(us)
log.DebugF("create user:%v", utils.JsonMarshal(us))
if code != pb.ErrCode_OK { if code != pb.ErrCode_OK {
return nil, code return nil, code
} }

View File

@ -44,6 +44,7 @@ func operationDb[T any](iMsg *ipb.InternalMsg, operation func(table *T) (*T, pb.
log.ErrorF("error marshalling user account %v", err) log.ErrorF("error marshalling user account %v", err)
return return
} }
log.DebugF("iMsg.Msg:%v", string(iMsg.Msg))
return return
} }

View File

@ -3,6 +3,7 @@ package cmd
import ( import (
"fmt" "fmt"
"game/server/login/config" "game/server/login/config"
"game/server/login/model"
"game/server/login/server" "game/server/login/server"
"github.com/fox/fox/log" "github.com/fox/fox/log"
"os" "os"
@ -11,7 +12,7 @@ import (
) )
func initRepo() { func initRepo() {
//model.InitRedis() model.InitRedis()
//model.InitDb() //model.InitDb()
} }

View File

@ -1,29 +1,29 @@
package model package model
//import ( import (
// "game/server/login/config" "game/server/login/config"
// "github.com/fox/fox/db" "github.com/fox/fox/db"
// "github.com/fox/fox/log" "github.com/fox/fox/log"
// "github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
// "gorm.io/gorm" )
//)
// var (
//var ( UserRedis *redis.Client
// UserRedis *redis.Client //UserDB *gorm.DB
// UserDB *gorm.DB //LogDB *gorm.DB
// LogDB *gorm.DB )
//)
// func InitRedis() {
//func InitRedis() { log.Debug("init redis")
// log.Debug("init redis") var err error
// var err error cfg := &config.Cfg.Redis
// cfg := &config.Cfg.Redis UserRedis, err = db.InitRedis(cfg.Password, cfg.Host, cfg.Port, 0)
// UserRedis, err = db.InitRedis(cfg.Password, cfg.Host, cfg.Port, 0) if err != nil {
// if err != nil { log.Fatal(err.Error())
// log.Fatal(err.Error()) return
// return }
// } }
//}
// //
//func InitDb() { //func InitDb() {
// log.Debug("init db") // log.Debug("init db")

View File

@ -48,9 +48,18 @@ func (s *LoginService) checkLoginOrRegister(req *pb.C2SUserLogin) (us *user.User
return nil, pb.ErrCode_SystemErr, node return nil, pb.ErrCode_SystemErr, node
} }
_ = json.Unmarshal(rspMsg.Msg, us) _ = json.Unmarshal(rspMsg.Msg, us)
log.DebugF("收到rcp:%v返回数据:%v", rpcName.GetUserAccount, string(rspMsg.Msg))
if us.ID == 0 { if us.ID == 0 {
// 没有帐号,创建帐号 // 没有帐号,创建帐号
rpcMsg.RpcMsgId = rpcName.CreateUserAccount 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) rspMsg, err = s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
if err != nil { if err != nil {
log.ErrorF(s.Log("call rpc:%v err:%s ", rpcMsg.RpcMsgId, err.Error())) log.ErrorF(s.Log("call rpc:%v err:%s ", rpcMsg.RpcMsgId, err.Error()))
@ -61,8 +70,10 @@ func (s *LoginService) checkLoginOrRegister(req *pb.C2SUserLogin) (us *user.User
log.ErrorF(s.Log("call rpc:%v err", rpcMsg.RpcMsgId)) log.ErrorF(s.Log("call rpc:%v err", rpcMsg.RpcMsgId))
return nil, pb.ErrCode_SystemErr, node return nil, pb.ErrCode_SystemErr, node
} }
log.DebugF("收到rcp:%v返回数据:%v", rpcName.CreateUserAccount, string(rspMsg.Msg))
} }
if pwd, _ := utils.Password(req.Password); pwd != us.Password { if !utils.CheckPassword(req.Password, us.Password) {
log.ErrorF(s.Log("用户密码:%v 数据库中密码:%v", req.Password, us.Password))
return nil, pb.ErrCode_LoginUserOrPwdErr, node return nil, pb.ErrCode_LoginUserOrPwdErr, node
} }
switch us.Status { switch us.Status {

View File

@ -99,7 +99,7 @@ func (s *LoginService) OnMessage(data []byte) error {
} else { } else {
log.Error(err.Error()) log.Error(err.Error())
} }
//log.Debug(s.Log("received message:%v", iMsg.MsgId)) log.Debug(s.Log("received message:%v", iMsg.MsgId))
return nil return nil
} }

View File

@ -5,8 +5,12 @@
1.4 客户端stop关闭连接触发服务端连接崩溃。(已修复) 1.4 客户端stop关闭连接触发服务端连接崩溃。(已修复)
2.编写db服 2.编写db服
2.1 login服向db服请求数据及向log db服写入日志。测试rpc机制。(已修改,待测试) 2.1 login服向db服请求数据及向log db服写入日志。测试rpc机制。(已验证)
2.2 login在创建帐号时还需要创建user。 2.2 db创建表时主键不会自增而是随机增加。
2.3 首次创建帐号redis没有写入帐号数据。
2.4 第二次登陆login还会走创建帐号逻辑导致db服返回重复建号失败。
2.5 清理登陆相关调试日志。
2.6 login在创建帐号时还需要创建user。
3.编写color game玩法 3.编写color game玩法
3.1 服务端玩法 3.1 服务端玩法