From 16eed66f4f8355aa9f5128118430e2c740eb075e Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Tue, 16 Dec 2025 14:36:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E5=8F=B0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdk/login/model/base/base.go | 1 + sdk/login/model/test/test.go | 4 +- sdk/login/model/tuyou/tuyou.go | 4 +- util/login.go | 131 ++++++++++++++++++++++++--------- 4 files changed, 101 insertions(+), 39 deletions(-) diff --git a/sdk/login/model/base/base.go b/sdk/login/model/base/base.go index b044b4c..bff9be3 100644 --- a/sdk/login/model/base/base.go +++ b/sdk/login/model/base/base.go @@ -12,6 +12,7 @@ type Param struct { Token string `json:"token" binding:"required"` AppId int `json:"app_id" binding:"required"` AreaCode int `json:"area_code" binding:"required"` + Version string `json:"version"` } type LoginResponse struct { diff --git a/sdk/login/model/test/test.go b/sdk/login/model/test/test.go index a8204d2..6635c3e 100644 --- a/sdk/login/model/test/test.go +++ b/sdk/login/model/test/test.go @@ -17,7 +17,7 @@ func Login(c *gin.Context) { p.Token = c.Query("token") p.AppId = util.Int(c.Query("appId")) p.AreaCode = util.Int(c.Query("areaCode")) - + p.Version = c.Query("version") if p.Uid == "" || p.Token == "" { c.JSON(400, gin.H{"error": "missing uid or token"}) return @@ -26,7 +26,7 @@ func Login(c *gin.Context) { c.JSON(401, gin.H{"error": "invalid token"}) return } - util.LoginResponse(c, p.AppId, p.AreaCode) + util.LoginResponse(c, p.AppId, p.AreaCode, p.Version) } func (t *TestModel) VerifyToken(Uid string, Token string) error { diff --git a/sdk/login/model/tuyou/tuyou.go b/sdk/login/model/tuyou/tuyou.go index 2ee69dc..f8d7212 100644 --- a/sdk/login/model/tuyou/tuyou.go +++ b/sdk/login/model/tuyou/tuyou.go @@ -42,7 +42,7 @@ func Login(c *gin.Context) { p.Token = c.Query("token") p.AppId = util.Int(c.Query("appId")) p.AreaCode = util.Int(c.Query("areaCode")) - + p.Version = c.Query("version") if p.Uid == "" || p.Token == "" { c.JSON(400, gin.H{"error": "missing uid or token"}) return @@ -58,7 +58,7 @@ func Login(c *gin.Context) { c.JSON(401, gin.H{"error": "invalid token"}) return } - util.LoginResponse(c, p.AppId, p.AreaCode) + util.LoginResponse(c, p.AppId, p.AreaCode, p.Version) } func (t *TuyouModel) VerifyToken(AppId int, Uid string, Token string) error { diff --git a/util/login.go b/util/login.go index 4e7f5b3..558cf62 100644 --- a/util/login.go +++ b/util/login.go @@ -1,6 +1,10 @@ package util -import "github.com/gin-gonic/gin" +import ( + "fmt" + + "github.com/gin-gonic/gin" +) type ServerConfig struct { ServerId int `db:"ServerId"` @@ -8,57 +12,86 @@ type ServerConfig struct { Port int `db:"Port"` MaxOnline int `db:"MaxOnline"` Online int `db:"Online"` + Version string `db:"version"` + Status int `db:"Status"` } -func LoginResponse(c *gin.Context, AppId, AreaCode int) { +func LoginResponse(c *gin.Context, AppId, AreaCode int, Version string) { Uid := c.GetString("Uid") Token := c.GetString("Token") - Port, Host, ServerId := GetUserInfo(AppId, AreaCode, Uid, Token) + Port, Host, ServerId := GetUserInfo(AppId, AreaCode, Uid, Token, Version) LoginSuccess(c, "login success", Port, Host, ServerId) } -func GetUserInfo(AppId, AreaCode int, Uid, Token string) (int, string, int) { +func GetUserInfo(AppId, AreaCode int, Uid, Token, Version string) (int, string, int) { Db := MPool.GetGameDB() defer Db.Close() var ServerId int var Host string var Port int - err := Db.QueryRow("SELECT ServerId FROM user WHERE Uid = ?", Uid).Scan(&ServerId) - if err != nil { - ServerId = 0 - } + ServerId = 0 ServerList := GetServerInfo(AppId, AreaCode) if len(ServerList) == 0 { return 0, "", 0 } - if ServerId == 0 { + + // 先尝试找版本号完全匹配且未满的服务器 + for _, server := range ServerList { + if server.Status != 1 { + continue + } + if server.Online < server.MaxOnline && server.Version == Version { + ServerId = server.ServerId + Host = server.Host + Port = server.Port + break + } + } + + // // 如果没找到匹配版本,选择版本号最接近且在线人数最少的服务器 + // if ServerId == 0 { + // BestVersion := "" + // minDistance := -1 + // for _, server := range ServerList { + // if server.Status != 1 { + // continue + // } + // if server.Online < server.MaxOnline { + // distance := VersionDistance(Version, server.Version) + // if minDistance == -1 || distance < minDistance { + // minDistance = distance + // BestVersion = server.Version + // } + // } + // } + + // var bestServer *ServerConfig + // minOnline := -1 + + // for i := range ServerList { + // server := &ServerList[i] + // if server.Status != 1 || server.Online >= server.MaxOnline || server.Version != BestVersion { + // continue + // } + + // // 如果还没有候选服务器,或者当前服务器在线人数更少 + // if bestServer == nil || server.Online < minOnline { + // bestServer = server + // minOnline = server.Online + // } + // } + + // if bestServer != nil { + // ServerId = bestServer.ServerId + // Host = bestServer.Host + // Port = bestServer.Port + // } + // } + + if ServerId == 0 && Version == "" { ServerId = ServerList[0].ServerId Host = ServerList[0].Host Port = ServerList[0].Port - for _, server := range ServerList { - if server.Online < server.MaxOnline { - ServerId = server.ServerId - Host = server.Host - Port = server.Port - break - } - } - if ServerId == 0 { - return 0, "", 0 - } - _, err := Db.Exec("insert into user (Uid, AppId, ServerId, AuthCode, CreateTime, UpdateTime) values (?, ?, ?, ?, ?, ?)", Uid, AppId, ServerId, Token, Now(), Now()) - if err != nil { - return 0, "", 0 - } - } else { - for _, server := range ServerList { - if server.ServerId == ServerId { - Host = server.Host - Port = server.Port - break - } - } - Db.Exec("update user set AuthCode = ?, UpdateTime = ? where Uid = ?", Token, Now(), Uid) } return Port, Host, ServerId } @@ -66,7 +99,7 @@ func GetUserInfo(AppId, AreaCode int, Uid, Token string) (int, string, int) { func GetServerInfo(AppId, AreaCode int) []ServerConfig { Db := MPool.GetGameDB() defer Db.Close() - rows, err := Db.Query("SELECT ServerId, Host, Port, MaxOnline, Online FROM server WHERE AppId = ? AND AreaCode = ? AND Status = 1 ORDER BY ServerId", AppId, AreaCode) + rows, err := Db.Query("SELECT ServerId, Status, Host, Port, MaxOnline, Online, version FROM server WHERE AppId = ? AND AreaCode = ? AND Status = 1 ORDER BY ServerId", AppId, AreaCode) if err != nil { return nil } @@ -74,10 +107,38 @@ func GetServerInfo(AppId, AreaCode int) []ServerConfig { var servers []ServerConfig for rows.Next() { var server ServerConfig - if err := rows.Scan(&server.ServerId, &server.Host, &server.Port, &server.MaxOnline, &server.Online); err != nil { + if err := rows.Scan(&server.ServerId, &server.Status, &server.Host, &server.Port, &server.MaxOnline, &server.Online, &server.Version); err != nil { continue } servers = append(servers, server) } return servers } + +// VersionDistance 计算两个版本号之间的跨度 +// 版本号格式为 major.minor.patch (例如: 1.0.0) +// 返回值越大表示版本差异越大 +func VersionDistance(v1, v2 string) int { + parse := func(version string) (int, int, int) { + var major, minor, patch int + fmt.Sscanf(version, "%d.%d.%d", &major, &minor, &patch) + return major, minor, patch + } + + major1, minor1, patch1 := parse(v1) + major2, minor2, patch2 := parse(v2) + + majorDiff := abs(major1 - major2) + minorDiff := abs(minor1 - minor2) + patchDiff := abs(patch1 - patch2) + + // 主版本号差异权重最高,次版本号次之,补丁版本号最低 + return majorDiff*10000 + minorDiff*100 + patchDiff +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +}