mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 14:22:26 +08:00
234 lines
6.9 KiB
Go
234 lines
6.9 KiB
Go
package controller
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"hk4e/dispatch/model"
|
|
"net/http"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"hk4e/dispatch/api"
|
|
"hk4e/pkg/endec"
|
|
"hk4e/pkg/logger"
|
|
"hk4e/pkg/random"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func (c *Controller) apiLogin(context *gin.Context) {
|
|
requestData := new(api.LoginAccountRequestJson)
|
|
err := context.ShouldBindJSON(requestData)
|
|
if err != nil {
|
|
logger.LOG.Error("parse LoginAccountRequestJson error: %v", err)
|
|
return
|
|
}
|
|
|
|
encPwdData, err := base64.StdEncoding.DecodeString(requestData.Password)
|
|
if err != nil {
|
|
logger.LOG.Error("decode password enc data error: %v", err)
|
|
return
|
|
}
|
|
pwdPrivKey, err := endec.RsaParsePrivKey(c.pwdRsaKey)
|
|
if err != nil {
|
|
logger.LOG.Error("parse rsa key error: %v", err)
|
|
return
|
|
}
|
|
pwdDecData, err := endec.RsaDecrypt(encPwdData, pwdPrivKey)
|
|
useAtAtMode := false
|
|
if err != nil {
|
|
logger.LOG.Debug("rsa dec error: %v", err)
|
|
logger.LOG.Debug("password rsa dec fail, fallback to @@ mode")
|
|
useAtAtMode = true
|
|
} else {
|
|
logger.LOG.Debug("password dec: %v", string(pwdDecData))
|
|
useAtAtMode = false
|
|
}
|
|
|
|
responseData := api.NewLoginResult()
|
|
|
|
var username string
|
|
var password string
|
|
if useAtAtMode {
|
|
// 账号格式检查 用户名6-20字符 密码8-20字符 用户名和密码公用account字段 第一次出现的@@视为分割标识 username@@password
|
|
if len(requestData.Account) > 20+20+2 {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "用户名或密码长度超限"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
if !strings.Contains(requestData.Account, "@@") {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "用户名同密码均填写到用户名输入框,填写格式为:用户名@@密码,密码输入框填写任意字符均可"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
atIndex := strings.Index(requestData.Account, "@@")
|
|
username = requestData.Account[:atIndex]
|
|
password = requestData.Account[atIndex+2:]
|
|
} else {
|
|
username = requestData.Account
|
|
password = string(pwdDecData)
|
|
}
|
|
|
|
if len(username) < 6 || len(username) > 20 {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "用户名为6-20位字符"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
if len(password) < 8 || len(password) > 20 {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "密码为8-20位字符"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
ok, err := regexp.MatchString("^[a-zA-Z0-9]{6,20}$", username)
|
|
if err != nil || !ok {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "用户名只能包含大小写字母和数字"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
// TODO SDK账号登陆
|
|
account, err := c.dao.QueryAccountByField("username", username)
|
|
if err != nil {
|
|
logger.LOG.Error("query account from db error: %v", err)
|
|
return
|
|
}
|
|
if account == nil {
|
|
// 注册一个原神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()
|
|
if err != nil {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "服务器内部错误:-2"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
regAccount := &model.Account{
|
|
AccountID: accountId,
|
|
Username: username,
|
|
Password: endec.Md5Str(password),
|
|
PlayerID: playerID,
|
|
Token: "",
|
|
ComboToken: "",
|
|
Forbid: false,
|
|
ForbidEndTime: 0,
|
|
}
|
|
_, err = c.dao.InsertAccount(regAccount)
|
|
if err != nil {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "服务器内部错误:-3"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
account = regAccount
|
|
}
|
|
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)
|
|
}
|
|
|
|
func (c *Controller) apiVerify(context *gin.Context) {
|
|
requestData := new(api.LoginTokenRequest)
|
|
err := context.ShouldBindJSON(requestData)
|
|
if err != nil {
|
|
logger.LOG.Error("parse LoginTokenRequest error: %v", err)
|
|
return
|
|
}
|
|
uid, err := strconv.ParseInt(requestData.Uid, 10, 64)
|
|
if err != nil {
|
|
logger.LOG.Error("parse uid error: %v", err)
|
|
return
|
|
}
|
|
account, err := c.dao.QueryAccountByField("accountID", uid)
|
|
if err != nil {
|
|
logger.LOG.Error("query account from db error: %v", err)
|
|
return
|
|
}
|
|
responseData := api.NewLoginResult()
|
|
if account == nil || account.Token != requestData.Token {
|
|
responseData.Retcode = -111
|
|
responseData.Message = "账号本地缓存信息错误"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
responseData.Message = "OK"
|
|
responseData.Data.Account.Uid = requestData.Uid
|
|
responseData.Data.Account.Token = requestData.Token
|
|
responseData.Data.Account.Email = account.Username
|
|
context.JSON(http.StatusOK, responseData)
|
|
}
|
|
|
|
func (c *Controller) v2Login(context *gin.Context) {
|
|
requestData := new(api.ComboTokenReq)
|
|
err := context.ShouldBindJSON(requestData)
|
|
if err != nil {
|
|
logger.LOG.Error("parse ComboTokenReq error: %v", err)
|
|
return
|
|
}
|
|
data := requestData.Data
|
|
if len(data) == 0 {
|
|
logger.LOG.Error("requestData.Data len == 0")
|
|
return
|
|
}
|
|
loginData := new(api.LoginTokenData)
|
|
err = json.Unmarshal([]byte(data), loginData)
|
|
if err != nil {
|
|
logger.LOG.Error("Unmarshal LoginTokenData error: %v", err)
|
|
return
|
|
}
|
|
uid, err := strconv.ParseInt(loginData.Uid, 10, 64)
|
|
if err != nil {
|
|
logger.LOG.Error("ParseInt uid error: %v", err)
|
|
return
|
|
}
|
|
responseData := api.NewComboTokenRes()
|
|
account, err := c.dao.QueryAccountByField("accountID", uid)
|
|
if account == nil || account.Token != loginData.Token {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "token错误"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
// 生成新的comboToken
|
|
account.ComboToken = random.GetRandomByteHexStr(20)
|
|
_, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "comboToken", account.ComboToken)
|
|
if err != nil {
|
|
responseData.Retcode = -201
|
|
responseData.Message = "服务器内部错误:-1"
|
|
context.JSON(http.StatusOK, responseData)
|
|
return
|
|
}
|
|
responseData.Message = "OK"
|
|
responseData.Data.OpenID = loginData.Uid
|
|
responseData.Data.ComboID = "0"
|
|
responseData.Data.ComboToken = account.ComboToken
|
|
context.JSON(http.StatusOK, responseData)
|
|
}
|