mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
修复多账号登录
This commit is contained in:
@@ -3,7 +3,6 @@ http_port = 8080
|
|||||||
[hk4e]
|
[hk4e]
|
||||||
kcp_addr = "127.0.0.1"
|
kcp_addr = "127.0.0.1"
|
||||||
kcp_port = 22103
|
kcp_port = 22103
|
||||||
login_sdk_url = "https://api.flswld.com/api/v1/auth/login"
|
|
||||||
|
|
||||||
[logger]
|
[logger]
|
||||||
level = "DEBUG"
|
level = "DEBUG"
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ type Hk4e struct {
|
|||||||
KcpAddr string `toml:"kcp_addr"`
|
KcpAddr string `toml:"kcp_addr"`
|
||||||
ResourcePath string `toml:"resource_path"`
|
ResourcePath string `toml:"resource_path"`
|
||||||
GachaHistoryServer string `toml:"gacha_history_server"`
|
GachaHistoryServer string `toml:"gacha_history_server"`
|
||||||
LoginSdkUrl string `toml:"login_sdk_url"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 消息队列
|
// 消息队列
|
||||||
|
|||||||
@@ -46,6 +46,22 @@ func NewController(dao *dao.Dao) (r *Controller) {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Controller) authorize() gin.HandlerFunc {
|
||||||
|
return func(context *gin.Context) {
|
||||||
|
// TODO auth token或其他验证方式
|
||||||
|
ok := true
|
||||||
|
if ok {
|
||||||
|
context.Next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.Abort()
|
||||||
|
context.JSON(http.StatusOK, gin.H{
|
||||||
|
"code": "10001",
|
||||||
|
"msg": "没有访问权限",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Controller) registerRouter() {
|
func (c *Controller) registerRouter() {
|
||||||
if config.CONF.Logger.Level == "DEBUG" {
|
if config.CONF.Logger.Level == "DEBUG" {
|
||||||
gin.SetMode(gin.DebugMode)
|
gin.SetMode(gin.DebugMode)
|
||||||
@@ -130,6 +146,8 @@ func (c *Controller) registerRouter() {
|
|||||||
engine.GET("/pictures/gt/a330cf996/slice/86f9db021.png", c.slicePng)
|
engine.GET("/pictures/gt/a330cf996/slice/86f9db021.png", c.slicePng)
|
||||||
engine.GET("/static/ant/sprite2x.1.2.6.png", c.sprite2xPng)
|
engine.GET("/static/ant/sprite2x.1.2.6.png", c.sprite2xPng)
|
||||||
}
|
}
|
||||||
|
engine.Use(c.authorize())
|
||||||
|
engine.POST("/gate/token/verify", c.gateTokenVerify)
|
||||||
port := config.CONF.HttpPort
|
port := config.CONF.HttpPort
|
||||||
addr := ":" + strconv.Itoa(port)
|
addr := ":" + strconv.Itoa(port)
|
||||||
err := engine.Run(addr)
|
err := engine.Run(addr)
|
||||||
|
|||||||
49
dispatch/controller/gate_controller.go
Normal file
49
dispatch/controller/gate_controller.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"hk4e/pkg/logger"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TokenVerifyReq struct {
|
||||||
|
AccountId string `json:"accountId"`
|
||||||
|
AccountToken string `json:"accountToken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenVerifyRsp struct {
|
||||||
|
Valid bool `json:"valid"`
|
||||||
|
Forbid bool `json:"forbid"`
|
||||||
|
ForbidEndTime uint32 `json:"forbidEndTime"`
|
||||||
|
PlayerID uint32 `json:"playerID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Controller) gateTokenVerify(context *gin.Context) {
|
||||||
|
tokenVerifyReq := new(TokenVerifyReq)
|
||||||
|
err := context.ShouldBindJSON(tokenVerifyReq)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.LOG.Debug("gate token verify, req: %v", tokenVerifyReq)
|
||||||
|
accountId, err := strconv.ParseUint(tokenVerifyReq.AccountId, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
account, err := c.dao.QueryAccountByField("accountID", accountId)
|
||||||
|
if err != nil || account == nil {
|
||||||
|
context.JSON(http.StatusOK, &TokenVerifyRsp{
|
||||||
|
Valid: false,
|
||||||
|
Forbid: false,
|
||||||
|
ForbidEndTime: 0,
|
||||||
|
PlayerID: 0,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.JSON(http.StatusOK, &TokenVerifyRsp{
|
||||||
|
Valid: true,
|
||||||
|
Forbid: account.Forbid,
|
||||||
|
ForbidEndTime: uint32(account.ForbidEndTime),
|
||||||
|
PlayerID: uint32(account.PlayerID),
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -3,38 +3,20 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"hk4e/dispatch/model"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
appConfig "hk4e/common/config"
|
|
||||||
"hk4e/dispatch/api"
|
"hk4e/dispatch/api"
|
||||||
db "hk4e/dispatch/model"
|
|
||||||
"hk4e/pkg/endec"
|
"hk4e/pkg/endec"
|
||||||
"hk4e/pkg/httpclient"
|
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/random"
|
"hk4e/pkg/random"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SdkUserLoginReq struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SdkUserLoginRsp struct {
|
|
||||||
Code int32 `json:"code"`
|
|
||||||
Msg string `json:"msg"`
|
|
||||||
AccessToken string `json:"access_token"`
|
|
||||||
RefreshToken string `json:"refresh_token"`
|
|
||||||
Data struct {
|
|
||||||
Uid int32 `json:"uid"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
} `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Controller) apiLogin(context *gin.Context) {
|
func (c *Controller) apiLogin(context *gin.Context) {
|
||||||
requestData := new(api.LoginAccountRequestJson)
|
requestData := new(api.LoginAccountRequestJson)
|
||||||
err := context.ShouldBindJSON(requestData)
|
err := context.ShouldBindJSON(requestData)
|
||||||
@@ -109,41 +91,7 @@ func (c *Controller) apiLogin(context *gin.Context) {
|
|||||||
context.JSON(http.StatusOK, responseData)
|
context.JSON(http.StatusOK, responseData)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// SDK账号登陆
|
// TODO SDK账号登陆
|
||||||
sdkUserLoginRsp, err := httpclient.Post[SdkUserLoginRsp](appConfig.CONF.Hk4e.LoginSdkUrl, &SdkUserLoginReq{
|
|
||||||
Username: username,
|
|
||||||
Password: password,
|
|
||||||
}, "")
|
|
||||||
// TODO 测试账号
|
|
||||||
{
|
|
||||||
sdkUserLoginRsp = &SdkUserLoginRsp{
|
|
||||||
Code: 0,
|
|
||||||
Msg: "",
|
|
||||||
AccessToken: "",
|
|
||||||
RefreshToken: "",
|
|
||||||
Data: struct {
|
|
||||||
Uid int32 `json:"uid"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
}{
|
|
||||||
Uid: 267042405,
|
|
||||||
Username: "FlourishingWorld",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
responseData.Retcode = -201
|
|
||||||
responseData.Message = "服务器内部错误:-1"
|
|
||||||
context.JSON(http.StatusOK, responseData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if sdkUserLoginRsp.Code != 0 {
|
|
||||||
responseData.Retcode = -201
|
|
||||||
responseData.Message = sdkUserLoginRsp.Msg
|
|
||||||
context.JSON(http.StatusOK, responseData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 登录成功
|
|
||||||
account, err := c.dao.QueryAccountByField("username", username)
|
account, err := c.dao.QueryAccountByField("username", username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LOG.Error("query account from db error: %v", err)
|
logger.LOG.Error("query account from db error: %v", err)
|
||||||
@@ -151,6 +99,13 @@ func (c *Controller) apiLogin(context *gin.Context) {
|
|||||||
}
|
}
|
||||||
if account == nil {
|
if account == nil {
|
||||||
// 注册一个原神account
|
// 注册一个原神account
|
||||||
|
accountId, err := c.dao.GetNextAccountId()
|
||||||
|
if err != nil {
|
||||||
|
responseData.Retcode = -201
|
||||||
|
responseData.Message = "服务器内部错误:-1"
|
||||||
|
context.JSON(http.StatusOK, responseData)
|
||||||
|
return
|
||||||
|
}
|
||||||
playerID, err := c.dao.GetNextYuanShenUid()
|
playerID, err := c.dao.GetNextYuanShenUid()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
responseData.Retcode = -201
|
responseData.Retcode = -201
|
||||||
@@ -158,12 +113,15 @@ func (c *Controller) apiLogin(context *gin.Context) {
|
|||||||
context.JSON(http.StatusOK, responseData)
|
context.JSON(http.StatusOK, responseData)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
regAccount := &db.Account{
|
regAccount := &model.Account{
|
||||||
Uid: uint64(sdkUserLoginRsp.Data.Uid),
|
AccountID: accountId,
|
||||||
Username: username,
|
Username: username,
|
||||||
PlayerID: playerID,
|
Password: endec.Md5Str(password),
|
||||||
Token: base64.StdEncoding.EncodeToString(random.GetRandomByte(24)),
|
PlayerID: playerID,
|
||||||
ComboToken: "",
|
Token: "",
|
||||||
|
ComboToken: "",
|
||||||
|
Forbid: false,
|
||||||
|
ForbidEndTime: 0,
|
||||||
}
|
}
|
||||||
_, err = c.dao.InsertAccount(regAccount)
|
_, err = c.dao.InsertAccount(regAccount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -172,25 +130,27 @@ func (c *Controller) apiLogin(context *gin.Context) {
|
|||||||
context.JSON(http.StatusOK, responseData)
|
context.JSON(http.StatusOK, responseData)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
responseData.Message = "OK"
|
account = regAccount
|
||||||
responseData.Data.Account.Uid = strconv.FormatInt(int64(regAccount.Uid), 10)
|
|
||||||
responseData.Data.Account.Token = regAccount.Token
|
|
||||||
responseData.Data.Account.Email = regAccount.Username
|
|
||||||
} else {
|
|
||||||
// 生产新的token
|
|
||||||
account.Token = base64.StdEncoding.EncodeToString(random.GetRandomByte(24))
|
|
||||||
_, err := c.dao.UpdateAccountFieldByFieldName("uid", account.Uid, "token", account.Token)
|
|
||||||
if err != nil {
|
|
||||||
responseData.Retcode = -201
|
|
||||||
responseData.Message = "服务器内部错误:-4"
|
|
||||||
context.JSON(http.StatusOK, responseData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
responseData.Message = "OK"
|
|
||||||
responseData.Data.Account.Uid = strconv.FormatInt(int64(account.Uid), 10)
|
|
||||||
responseData.Data.Account.Token = account.Token
|
|
||||||
responseData.Data.Account.Email = account.Username
|
|
||||||
}
|
}
|
||||||
|
if endec.Md5Str(password) != account.Password {
|
||||||
|
responseData.Retcode = -201
|
||||||
|
responseData.Message = "用户名或密码错误"
|
||||||
|
context.JSON(http.StatusOK, responseData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 生产新的token
|
||||||
|
account.Token = base64.StdEncoding.EncodeToString(random.GetRandomByte(24))
|
||||||
|
_, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "token", account.Token)
|
||||||
|
if err != nil {
|
||||||
|
responseData.Retcode = -201
|
||||||
|
responseData.Message = "服务器内部错误:-4"
|
||||||
|
context.JSON(http.StatusOK, responseData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
responseData.Message = "OK"
|
||||||
|
responseData.Data.Account.Uid = strconv.FormatInt(int64(account.AccountID), 10)
|
||||||
|
responseData.Data.Account.Token = account.Token
|
||||||
|
responseData.Data.Account.Email = account.Username
|
||||||
context.JSON(http.StatusOK, responseData)
|
context.JSON(http.StatusOK, responseData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +166,7 @@ func (c *Controller) apiVerify(context *gin.Context) {
|
|||||||
logger.LOG.Error("parse uid error: %v", err)
|
logger.LOG.Error("parse uid error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
account, err := c.dao.QueryAccountByField("uid", uid)
|
account, err := c.dao.QueryAccountByField("accountID", uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LOG.Error("query account from db error: %v", err)
|
logger.LOG.Error("query account from db error: %v", err)
|
||||||
return
|
return
|
||||||
@@ -249,7 +209,7 @@ func (c *Controller) v2Login(context *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
responseData := api.NewComboTokenRes()
|
responseData := api.NewComboTokenRes()
|
||||||
account, err := c.dao.QueryAccountByField("uid", uid)
|
account, err := c.dao.QueryAccountByField("accountID", uid)
|
||||||
if account == nil || account.Token != loginData.Token {
|
if account == nil || account.Token != loginData.Token {
|
||||||
responseData.Retcode = -201
|
responseData.Retcode = -201
|
||||||
responseData.Message = "token错误"
|
responseData.Message = "token错误"
|
||||||
@@ -258,7 +218,7 @@ func (c *Controller) v2Login(context *gin.Context) {
|
|||||||
}
|
}
|
||||||
// 生成新的comboToken
|
// 生成新的comboToken
|
||||||
account.ComboToken = random.GetRandomByteHexStr(20)
|
account.ComboToken = random.GetRandomByteHexStr(20)
|
||||||
_, err = c.dao.UpdateAccountFieldByFieldName("uid", account.Uid, "comboToken", account.ComboToken)
|
_, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "comboToken", account.ComboToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
responseData.Retcode = -201
|
responseData.Retcode = -201
|
||||||
responseData.Message = "服务器内部错误:-1"
|
responseData.Message = "服务器内部错误:-1"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package dao
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"hk4e/dispatch/model"
|
||||||
|
|
||||||
dbEntity "hk4e/dispatch/model"
|
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -12,14 +12,52 @@ import (
|
|||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *Dao) GetNextYuanShenUid() (uint64, error) {
|
func (d *Dao) GetNextAccountId() (uint64, error) {
|
||||||
db := d.db.Collection("player_id_counter")
|
db := d.db.Collection("account_id_counter")
|
||||||
find := db.FindOne(context.TODO(), bson.D{{"_id", "default"}})
|
find := db.FindOne(context.TODO(), bson.D{{"_id", "default"}})
|
||||||
item := new(dbEntity.PlayerIDCounter)
|
item := new(model.AccountIDCounter)
|
||||||
err := find.Decode(item)
|
err := find.Decode(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == mongo.ErrNoDocuments {
|
if err == mongo.ErrNoDocuments {
|
||||||
item := &dbEntity.PlayerIDCounter{
|
item := &model.AccountIDCounter{
|
||||||
|
ID: "default",
|
||||||
|
AccountID: 1,
|
||||||
|
}
|
||||||
|
_, err := db.InsertOne(context.TODO(), item)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.New("insert new AccountID error")
|
||||||
|
}
|
||||||
|
return item.AccountID, nil
|
||||||
|
} else {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.AccountID++
|
||||||
|
_, err = db.UpdateOne(
|
||||||
|
context.TODO(),
|
||||||
|
bson.D{
|
||||||
|
{"_id", "default"},
|
||||||
|
},
|
||||||
|
bson.D{
|
||||||
|
{"$set", bson.D{
|
||||||
|
{"AccountID", item.AccountID},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return item.AccountID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dao) GetNextYuanShenUid() (uint64, error) {
|
||||||
|
db := d.db.Collection("player_id_counter")
|
||||||
|
find := db.FindOne(context.TODO(), bson.D{{"_id", "default"}})
|
||||||
|
item := new(model.PlayerIDCounter)
|
||||||
|
err := find.Decode(item)
|
||||||
|
if err != nil {
|
||||||
|
if err == mongo.ErrNoDocuments {
|
||||||
|
item := &model.PlayerIDCounter{
|
||||||
ID: "default",
|
ID: "default",
|
||||||
PlayerID: 100000001,
|
PlayerID: 100000001,
|
||||||
}
|
}
|
||||||
@@ -50,7 +88,7 @@ func (d *Dao) GetNextYuanShenUid() (uint64, error) {
|
|||||||
return item.PlayerID, nil
|
return item.PlayerID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dao) InsertAccount(account *dbEntity.Account) (primitive.ObjectID, error) {
|
func (d *Dao) InsertAccount(account *model.Account) (primitive.ObjectID, error) {
|
||||||
db := d.db.Collection("account")
|
db := d.db.Collection("account")
|
||||||
id, err := db.InsertOne(context.TODO(), account)
|
id, err := db.InsertOne(context.TODO(), account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -100,7 +138,7 @@ func (d *Dao) UpdateAccountFieldByFieldName(fieldName string, fieldValue any, fi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dao) QueryAccountByField(fieldName string, fieldValue any) (*dbEntity.Account, error) {
|
func (d *Dao) QueryAccountByField(fieldName string, fieldValue any) (*model.Account, error) {
|
||||||
db := d.db.Collection("account")
|
db := d.db.Collection("account")
|
||||||
find, err := db.Find(
|
find, err := db.Find(
|
||||||
context.TODO(),
|
context.TODO(),
|
||||||
@@ -111,9 +149,9 @@ func (d *Dao) QueryAccountByField(fieldName string, fieldValue any) (*dbEntity.A
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := make([]*dbEntity.Account, 0)
|
result := make([]*model.Account, 0)
|
||||||
for find.Next(context.TODO()) {
|
for find.Next(context.TODO()) {
|
||||||
item := new(dbEntity.Account)
|
item := new(model.Account)
|
||||||
err := find.Decode(item)
|
err := find.Decode(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func NewDao() (r *Dao) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
r.client = client
|
r.client = client
|
||||||
r.db = client.Database("gate_hk4e")
|
r.db = client.Database("dispatch_hk4e")
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import "go.mongodb.org/mongo-driver/bson/primitive"
|
|||||||
|
|
||||||
type Account struct {
|
type Account struct {
|
||||||
ID primitive.ObjectID `bson:"_id,omitempty"`
|
ID primitive.ObjectID `bson:"_id,omitempty"`
|
||||||
Uid uint64 `bson:"uid"`
|
AccountID uint64 `bson:"accountID"`
|
||||||
Username string `bson:"username"`
|
Username string `bson:"username"`
|
||||||
|
Password string `bson:"password"`
|
||||||
PlayerID uint64 `bson:"playerID"`
|
PlayerID uint64 `bson:"playerID"`
|
||||||
Token string `bson:"token"`
|
Token string `bson:"token"`
|
||||||
ComboToken string `bson:"comboToken"`
|
ComboToken string `bson:"comboToken"`
|
||||||
|
|||||||
6
dispatch/model/account_id_counter.go
Normal file
6
dispatch/model/account_id_counter.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type AccountIDCounter struct {
|
||||||
|
ID string `bson:"_id"`
|
||||||
|
AccountID uint64 `bson:"AccountID"`
|
||||||
|
}
|
||||||
@@ -11,12 +11,12 @@ type Service struct {
|
|||||||
// 用户密码改变
|
// 用户密码改变
|
||||||
func (f *Service) UserPasswordChange(uid uint32) bool {
|
func (f *Service) UserPasswordChange(uid uint32) bool {
|
||||||
// dispatch登录态失效
|
// dispatch登录态失效
|
||||||
_, err := f.dao.UpdateAccountFieldByFieldName("uid", uid, "token", "")
|
_, err := f.dao.UpdateAccountFieldByFieldName("accountID", uid, "token", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 游戏内登录态失效
|
// 游戏内登录态失效
|
||||||
account, err := f.dao.QueryAccountByField("uid", uid)
|
account, err := f.dao.QueryAccountByField("accountID", uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -41,16 +41,16 @@ func (f *Service) ForbidUser(info *ForbidUserInfo) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 写入账号封禁信息
|
// 写入账号封禁信息
|
||||||
_, err := f.dao.UpdateAccountFieldByFieldName("uid", info.UserId, "forbid", true)
|
_, err := f.dao.UpdateAccountFieldByFieldName("accountID", info.UserId, "forbid", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
_, err = f.dao.UpdateAccountFieldByFieldName("uid", info.UserId, "forbidEndTime", info.ForbidEndTime)
|
_, err = f.dao.UpdateAccountFieldByFieldName("accountID", info.UserId, "forbidEndTime", info.ForbidEndTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 游戏强制下线
|
// 游戏强制下线
|
||||||
account, err := f.dao.QueryAccountByField("uid", info.UserId)
|
account, err := f.dao.QueryAccountByField("accountID", info.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ func (f *Service) ForbidUser(info *ForbidUserInfo) bool {
|
|||||||
// 解封
|
// 解封
|
||||||
func (s *Service) UnForbidUser(uid uint32) bool {
|
func (s *Service) UnForbidUser(uid uint32) bool {
|
||||||
// 解除账号封禁
|
// 解除账号封禁
|
||||||
_, err := s.dao.UpdateAccountFieldByFieldName("uid", uid, "forbid", false)
|
_, err := s.dao.UpdateAccountFieldByFieldName("accountID", uid, "forbid", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"hk4e/dispatch/controller"
|
||||||
|
"hk4e/pkg/httpclient"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -15,27 +17,29 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerTokenReq) (rsp *proto.GetPlayerTokenRsp) {
|
func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerTokenReq) (rsp *proto.GetPlayerTokenRsp) {
|
||||||
_ = req.AccountUid
|
// TODO 请求sdk验证token
|
||||||
_ = req.AccountToken
|
tokenVerifyRsp, err := httpclient.Post[controller.TokenVerifyRsp]("http://127.0.0.1:8080/gate/token/verify", &controller.TokenVerifyReq{
|
||||||
tokenValid := true
|
AccountId: req.AccountUid,
|
||||||
accountForbid := false
|
AccountToken: req.AccountToken,
|
||||||
accountForbidEndTime := uint32(0)
|
}, "")
|
||||||
accountPlayerID := uint32(100000001)
|
if err != nil {
|
||||||
if !tokenValid {
|
logger.LOG.Error("verify token error: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !tokenVerifyRsp.Valid {
|
||||||
logger.LOG.Error("token error")
|
logger.LOG.Error("token error")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// TODO 请求sdk验证token
|
|
||||||
// comboToken验证成功
|
// comboToken验证成功
|
||||||
if accountForbid {
|
if tokenVerifyRsp.Forbid {
|
||||||
// 封号通知
|
// 封号通知
|
||||||
rsp = new(proto.GetPlayerTokenRsp)
|
rsp = new(proto.GetPlayerTokenRsp)
|
||||||
rsp.Uid = accountPlayerID
|
rsp.Uid = tokenVerifyRsp.PlayerID
|
||||||
rsp.IsProficientPlayer = true
|
rsp.IsProficientPlayer = true
|
||||||
rsp.Retcode = 21
|
rsp.Retcode = 21
|
||||||
rsp.Msg = "FORBID_CHEATING_PLUGINS"
|
rsp.Msg = "FORBID_CHEATING_PLUGINS"
|
||||||
//rsp.BlackUidEndTime = 2051193600 // 2035-01-01 00:00:00
|
//rsp.BlackUidEndTime = 2051193600 // 2035-01-01 00:00:00
|
||||||
rsp.BlackUidEndTime = accountForbidEndTime
|
rsp.BlackUidEndTime = tokenVerifyRsp.ForbidEndTime
|
||||||
rsp.RegPlatform = 3
|
rsp.RegPlatform = 3
|
||||||
rsp.CountryCode = "US"
|
rsp.CountryCode = "US"
|
||||||
addr, exist := f.getAddrByConvId(convId)
|
addr, exist := f.getAddrByConvId(convId)
|
||||||
@@ -47,7 +51,7 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
|
|||||||
rsp.ClientIpStr = split[0]
|
rsp.ClientIpStr = split[0]
|
||||||
return rsp
|
return rsp
|
||||||
}
|
}
|
||||||
oldConvId, oldExist := f.getConvIdByUserId(accountPlayerID)
|
oldConvId, oldExist := f.getConvIdByUserId(tokenVerifyRsp.PlayerID)
|
||||||
if oldExist {
|
if oldExist {
|
||||||
// 顶号
|
// 顶号
|
||||||
f.kcpEventInput <- &net.KcpEvent{
|
f.kcpEventInput <- &net.KcpEvent{
|
||||||
@@ -56,14 +60,15 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
|
|||||||
EventMessage: uint32(kcp.EnetServerRelogin),
|
EventMessage: uint32(kcp.EnetServerRelogin),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.setUserIdByConvId(convId, accountPlayerID)
|
// 关联玩家uid和连接信息
|
||||||
f.setConvIdByUserId(accountPlayerID, convId)
|
f.setUserIdByConvId(convId, tokenVerifyRsp.PlayerID)
|
||||||
|
f.setConvIdByUserId(tokenVerifyRsp.PlayerID, convId)
|
||||||
f.setConnState(convId, ConnWaitLogin)
|
f.setConnState(convId, ConnWaitLogin)
|
||||||
// 返回响应
|
// 返回响应
|
||||||
rsp = new(proto.GetPlayerTokenRsp)
|
rsp = new(proto.GetPlayerTokenRsp)
|
||||||
rsp.Uid = accountPlayerID
|
rsp.Uid = tokenVerifyRsp.PlayerID
|
||||||
// TODO 不同的token
|
// TODO 不同的token
|
||||||
rsp.Token = req.AccountToken
|
rsp.Token = "xxx"
|
||||||
rsp.AccountType = 1
|
rsp.AccountType = 1
|
||||||
// TODO 要确定一下新注册的号这个值该返回什么
|
// TODO 要确定一下新注册的号这个值该返回什么
|
||||||
rsp.IsProficientPlayer = true
|
rsp.IsProficientPlayer = true
|
||||||
@@ -149,20 +154,16 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *ForwardManager) playerLogin(convId uint64, req *proto.PlayerLoginReq) (rsp *proto.PlayerLoginRsp) {
|
func (f *ForwardManager) playerLogin(convId uint64, req *proto.PlayerLoginReq) (rsp *proto.PlayerLoginRsp) {
|
||||||
userId, exist := f.getUserIdByConvId(convId)
|
tokenValid := false
|
||||||
if !exist {
|
// TODO 不同的token
|
||||||
logger.LOG.Error("can not find userId by convId")
|
if req.Token == "xxx" {
|
||||||
return nil
|
tokenValid = true
|
||||||
}
|
}
|
||||||
_ = userId
|
|
||||||
_ = req.Token
|
|
||||||
tokenValid := true
|
|
||||||
if !tokenValid {
|
if !tokenValid {
|
||||||
logger.LOG.Error("token error")
|
logger.LOG.Error("token error")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// TODO 请求sdk验证token
|
// token验证成功
|
||||||
// comboToken验证成功
|
|
||||||
f.setConnState(convId, ConnAlive)
|
f.setConnState(convId, ConnAlive)
|
||||||
// 返回响应
|
// 返回响应
|
||||||
rsp = new(proto.PlayerLoginRsp)
|
rsp = new(proto.PlayerLoginRsp)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (p *ProtoEnDecode) protoDecode(kcpMsg *KcpMsg) (protoMsgList []*ProtoMsg) {
|
|||||||
}
|
}
|
||||||
// payload msg
|
// payload msg
|
||||||
protoMessageList := make([]*ProtoMessage, 0)
|
protoMessageList := make([]*ProtoMessage, 0)
|
||||||
p.protoDecodePayloadCore(kcpMsg.CmdId, kcpMsg.ProtoData, &protoMessageList)
|
p.protoDecodePayloadLoop(kcpMsg.CmdId, kcpMsg.ProtoData, &protoMessageList)
|
||||||
if len(protoMessageList) == 0 {
|
if len(protoMessageList) == 0 {
|
||||||
logger.LOG.Error("decode proto object is nil")
|
logger.LOG.Error("decode proto object is nil")
|
||||||
return protoMsgList
|
return protoMsgList
|
||||||
@@ -61,25 +61,26 @@ func (p *ProtoEnDecode) protoDecode(kcpMsg *KcpMsg) (protoMsgList []*ProtoMsg) {
|
|||||||
msg.CmdId = protoMessage.cmdId
|
msg.CmdId = protoMessage.cmdId
|
||||||
msg.HeadMessage = protoMsg.HeadMessage
|
msg.HeadMessage = protoMsg.HeadMessage
|
||||||
msg.PayloadMessage = protoMessage.message
|
msg.PayloadMessage = protoMessage.message
|
||||||
logger.LOG.Debug("[recv] union proto msg, convId: %v, cmdId: %v", msg.ConvId, msg.CmdId)
|
|
||||||
if protoMessage.cmdId == cmd.UnionCmdNotify {
|
if protoMessage.cmdId == cmd.UnionCmdNotify {
|
||||||
// 聚合消息自身不再往后发送
|
// 聚合消息自身不再往后发送
|
||||||
|
logger.LOG.Debug("[recv union], cmdId: %v, convId: %v, headMsg: %v", msg.CmdId, msg.ConvId, msg.HeadMessage)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
logger.LOG.Debug("[recv] proto msg, convId: %v, cmdId: %v, headMsg: %v", protoMsg.ConvId, protoMsg.CmdId, protoMsg.HeadMessage)
|
|
||||||
protoMsgList = append(protoMsgList, msg)
|
protoMsgList = append(protoMsgList, msg)
|
||||||
}
|
}
|
||||||
// 聚合消息自身不再往后发送
|
|
||||||
return protoMsgList
|
|
||||||
} else {
|
} else {
|
||||||
protoMsg.PayloadMessage = protoMessageList[0].message
|
protoMsg.PayloadMessage = protoMessageList[0].message
|
||||||
|
protoMsgList = append(protoMsgList, protoMsg)
|
||||||
}
|
}
|
||||||
logger.LOG.Debug("[recv] proto msg, convId: %v, cmdId: %v, headMsg: %v", protoMsg.ConvId, protoMsg.CmdId, protoMsg.HeadMessage)
|
cmdName := ""
|
||||||
protoMsgList = append(protoMsgList, protoMsg)
|
if protoMsg.PayloadMessage != nil {
|
||||||
|
cmdName = string(protoMsg.PayloadMessage.ProtoReflect().Descriptor().FullName())
|
||||||
|
}
|
||||||
|
logger.LOG.Debug("[recv], cmdId: %v, cmdName: %v, convId: %v, headMsg: %v", protoMsg.CmdId, cmdName, protoMsg.ConvId, protoMsg.HeadMessage)
|
||||||
return protoMsgList
|
return protoMsgList
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProtoEnDecode) protoDecodePayloadCore(cmdId uint16, protoData []byte, protoMessageList *[]*ProtoMessage) {
|
func (p *ProtoEnDecode) protoDecodePayloadLoop(cmdId uint16, protoData []byte, protoMessageList *[]*ProtoMessage) {
|
||||||
protoObj := p.decodePayloadToProto(cmdId, protoData)
|
protoObj := p.decodePayloadToProto(cmdId, protoData)
|
||||||
if protoObj == nil {
|
if protoObj == nil {
|
||||||
logger.LOG.Error("decode proto object is nil")
|
logger.LOG.Error("decode proto object is nil")
|
||||||
@@ -93,7 +94,7 @@ func (p *ProtoEnDecode) protoDecodePayloadCore(cmdId uint16, protoData []byte, p
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, unionCmd := range unionCmdNotify.GetCmdList() {
|
for _, unionCmd := range unionCmdNotify.GetCmdList() {
|
||||||
p.protoDecodePayloadCore(uint16(unionCmd.MessageId), unionCmd.Body, protoMessageList)
|
p.protoDecodePayloadLoop(uint16(unionCmd.MessageId), unionCmd.Body, protoMessageList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*protoMessageList = append(*protoMessageList, &ProtoMessage{
|
*protoMessageList = append(*protoMessageList, &ProtoMessage{
|
||||||
@@ -103,7 +104,11 @@ func (p *ProtoEnDecode) protoDecodePayloadCore(cmdId uint16, protoData []byte, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProtoEnDecode) protoEncode(protoMsg *ProtoMsg) (kcpMsg *KcpMsg) {
|
func (p *ProtoEnDecode) protoEncode(protoMsg *ProtoMsg) (kcpMsg *KcpMsg) {
|
||||||
logger.LOG.Debug("[send] proto msg, convId: %v, cmdId: %v, headMsg: %v", protoMsg.ConvId, protoMsg.CmdId, protoMsg.HeadMessage)
|
cmdName := ""
|
||||||
|
if protoMsg.PayloadMessage != nil {
|
||||||
|
cmdName = string(protoMsg.PayloadMessage.ProtoReflect().Descriptor().FullName())
|
||||||
|
}
|
||||||
|
logger.LOG.Debug("[send], cmdId: %v, cmdName: %v, convId: %v, headMsg: %v", protoMsg.CmdId, cmdName, protoMsg.ConvId, protoMsg.HeadMessage)
|
||||||
kcpMsg = new(KcpMsg)
|
kcpMsg = new(KcpMsg)
|
||||||
kcpMsg.ConvId = protoMsg.ConvId
|
kcpMsg.ConvId = protoMsg.ConvId
|
||||||
kcpMsg.CmdId = protoMsg.CmdId
|
kcpMsg.CmdId = protoMsg.CmdId
|
||||||
|
|||||||
@@ -37,9 +37,6 @@ func (r *RouteManager) doRoute(cmdId uint16, userId uint32, clientSeq uint32, pa
|
|||||||
}
|
}
|
||||||
player := r.gameManager.userManager.GetOnlineUser(userId)
|
player := r.gameManager.userManager.GetOnlineUser(userId)
|
||||||
if player == nil {
|
if player == nil {
|
||||||
// 当gs重启后玩家并未退出gate 会持续触发nil
|
|
||||||
r.gameManager.ReconnectPlayer(userId)
|
|
||||||
|
|
||||||
logger.LOG.Error("player is nil, uid: %v", userId)
|
logger.LOG.Error("player is nil, uid: %v", userId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
1
third_party/README.md
vendored
1
third_party/README.md
vendored
@@ -1,2 +1,3 @@
|
|||||||
# third_party
|
# third_party
|
||||||
|
|
||||||
本文件夹为第三方依赖,任何内容都不可修改
|
本文件夹为第三方依赖,任何内容都不可修改
|
||||||
6
third_party/natsrpc/natsrpc.proto
vendored
6
third_party/natsrpc/natsrpc.proto
vendored
@@ -6,8 +6,8 @@ option go_package = "github.com/byebyebruce/natsrpc;natsrpc";
|
|||||||
import "google/protobuf/descriptor.proto";
|
import "google/protobuf/descriptor.proto";
|
||||||
|
|
||||||
extend google.protobuf.ServiceOptions {
|
extend google.protobuf.ServiceOptions {
|
||||||
bool serviceAsync = 43230; // service异步handler
|
bool serviceAsync = 43230; // service异步handler
|
||||||
bool clientAsync = 43231; // client异步请求
|
bool clientAsync = 43231; // client异步请求
|
||||||
}
|
}
|
||||||
|
|
||||||
extend google.protobuf.MethodOptions {
|
extend google.protobuf.MethodOptions {
|
||||||
@@ -20,7 +20,7 @@ message Empty {}
|
|||||||
// Request 请求
|
// Request 请求
|
||||||
message Request {
|
message Request {
|
||||||
bytes payload = 1; // 包体
|
bytes payload = 1; // 包体
|
||||||
map<string,string> header = 2; // 包头
|
map<string, string> header = 2; // 包头
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reply 返回
|
// Reply 返回
|
||||||
|
|||||||
Reference in New Issue
Block a user