You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

484 lines
15 KiB

package internal
import (
"context"
"crypto/md5"
"errors"
"fmt"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"log"
"os"
"strings"
"time"
"tyj_admin/api/v1/game"
"tyj_admin/internal/consts"
"tyj_admin/internal/dao"
"tyj_admin/internal/model/do"
"tyj_admin/internal/model/entity"
)
type Account struct {
Code string `json:"code" description:"账号"`
ConfigId int32 `json:"configId" description:"密码"`
Used int64 `json:"used" description:"创建时间"`
}
func checkOne(result string, value string) bool {
return strings.Contains(result, value)
}
func getPreValue(id int64, charset string) string {
charsetLen := int64(len(charset))
preValue := ""
for {
preValue = charset[id%charsetLen:id%charsetLen+1] + preValue
if id/charsetLen == 0 {
break
}
id = id / charsetLen
}
return preValue
}
func randomGenerate(ctx context.Context, preName string, id int64, num int) {
g.Try(ctx, func(ctx context.Context) {
timeD := time.Now().Unix()
charset := consts.CHARSET
charsetDef := consts.CHARSETDef
lenfrom := 6
lento := 6
result := ""
index := -1
preValue := getPreValue(id, charsetDef)
datas := []g.List{}
data := g.List{}
for i := num - 1; i >= 0; {
if index == i {
continue
}
index = i
value := generateOne(charset, lenfrom, lento)
value = preValue + value
a := checkOne(result, value)
if a == true {
index = -1
continue
}
i--
result += value + "\r"
data = append(data, g.Map{
dao.GameCdKey.Columns().Code: value,
dao.GameCdKey.Columns().ConfigId: id,
})
if len(data) > 10000 {
datas = append(datas, data)
data = g.List{}
}
}
if len(data) > 0 {
datas = append(datas, data)
}
log.Println("randomGenerate: s: ", time.Now().Unix()-timeD)
if err := os.WriteFile(fmt.Sprintf("./download/%s", cdKeyFilename(preName, id)), []byte(result), 0666); err != nil {
log.Fatal(err)
} else {
updateGiftExchangeConfig(ctx, id, "", 1)
}
for _, v := range datas {
if len(v) > 0 {
_, _ = dao.GameCdKey.Ctx(ctx).Data(v).Insert()
}
}
})
}
func GetGiftExchangeConfig(ctx context.Context, req *game.GetGiftExchangeListReq) (res *game.GetGiftExchangeListRes, err error) {
res = new(game.GetGiftExchangeListRes)
model := dao.GameGiftExchange.Ctx(ctx)
if req.Name != "" {
model = model.Where("name like ?", "%"+req.Name+"%")
}
if req.Pass != "" {
model = model.Where("password like ?", "%"+req.Pass+"%")
}
if req.Channel != "" {
model = model.Where("channel like ?", "%"+req.Channel+"%")
}
if req.KeyType != 0 {
model = model.Where("type=?", req.KeyType)
}
if req.States != 0 {
switch req.States {
case 1:
model = model.Where("start_time>?", time.Now().Format(consts.TIME_FORMAT))
break
case 2:
model = model.Where("start_time<?", time.Now().Format(consts.TIME_FORMAT))
model = model.Where("stop_time>?", time.Now().Format(consts.TIME_FORMAT))
break
case 3:
model = model.Where("stop_time<?", time.Now().Format(consts.TIME_FORMAT))
break
}
} else {
if req.StartTime != "" {
model = model.Where("start_time>=?", req.StartTime)
}
if req.StopTime != "" {
model = model.Where("stop_time<=?", req.StopTime)
}
}
res.Total, err = model.Count()
err = model.Page(req.PageNum, req.PageSize).OrderDesc("id").Scan(&res.List)
log.Println("GetGiftExchangeConfig: ", gjson.MustEncodeString(res))
return
}
func GetGiftExchange(ctx context.Context, req *game.GetGiftExchangeReq) (res *game.GetGiftExchangeRes, err error) {
res = new(game.GetGiftExchangeRes)
var path = gfile.Join(gfile.RealPath("download"), req.File)
log.Println("GetGiftExchange: ", req.File, path, gfile.Exists(path))
if gfile.Exists(path) {
res.State = 1
}
return
}
func UpdateGiftExchangeConfig(ctx context.Context, req *game.UpdateGiftExchangeReq) (res *game.UpdateGiftExchangeRes, err error) {
data := do.GameGiftExchange{Channel: req.Channel}
if req.StartTime != "" {
data.StartTime = req.StartTime
}
if req.StopTime != "" {
data.StopTime = req.StopTime
}
if req.Times != 0 {
data.Times = req.Times
}
if len(req.Awards) > 0 {
data.Rewards = req.Awards
}
if req.StartTime == "" && req.StopTime == "" && req.Times == 0 {
data.StartTime = time.Now().Format(consts.TIME_FORMAT)
data.StopTime = time.Now().Format(consts.TIME_FORMAT)
}
dao.GameGiftExchange.Ctx(ctx).WherePri(req.Id).Update(data)
return
}
func RandomGenerateCode(ctx context.Context, req *game.RandomGenerateCodeReq) (res *game.RandomGenerateCodeRes, err error) {
res = new(game.RandomGenerateCodeRes)
if req.KeyType == consts.CDKEY_TYPE_PASS {
gift := []entity.GameGiftExchange{}
dao.GameGiftExchange.Ctx(ctx).Where("password=?", req.Pass).Scan(&gift)
if len(gift) > 0 {
return res, errors.New("有相同口令")
}
}
id, err := insertGiftExchangeConfig(ctx, req)
if err != nil {
log.Println("RandomGenerateCode: insertGiftExchangeConfig: ", err)
return
}
if req.KeyType == consts.CDKEY_TYPE_NUM {
preName := fmt.Sprintf("code%d_", time.Now().Unix())
res.Filename = cdKeyFilename(preName, id)
updateGiftExchangeConfig(ctx, id, res.Filename, 0)
go randomGenerate(ctx, preName, id, req.Num)
}
log.Printf("RandomGenerateCode: FieldName: %s", res.Filename)
return
}
func updateGiftExchangeConfig(ctx context.Context, id int64, filename string, fileState int) {
data := do.GameGiftExchange{}
if filename != "" {
data.Filename = filename
}
if fileState != 0 {
data.FileState = fileState
}
_, err := dao.GameGiftExchange.Ctx(ctx).WherePri(id).Update(data)
if err != nil {
log.Printf("updateGiftExchangeConfig err: %v", err)
}
}
func insertGiftExchangeConfig(ctx context.Context, req *game.RandomGenerateCodeReq) (id int64, err error) {
if req.Name == "" || req.KeyType == 0 || len(req.Awards) <= 0 || req.Times == 0 {
return 0, errors.New("配置未填!")
}
data := do.GameGiftExchange{Name: req.Name, Channel: req.Channel, Rewards: req.Awards,
Type: req.KeyType, Times: req.Times, StartTime: req.StartTime, StopTime: req.StopTime}
if req.KeyType == consts.CDKEY_TYPE_PASS {
if req.Pass == "" {
return 0, errors.New("口令为空")
}
data.Password = req.Pass
} else {
if req.Num == 0 {
return 0, errors.New("兑换码数量为0")
}
data.Num = req.Num
}
res, err := dao.GameGiftExchange.Ctx(ctx).Insert(data)
if err != nil {
log.Printf("insertGiftExchangeConfig value: %v, err: %v", req, err)
return 0, err
}
id, err = res.LastInsertId()
if err != nil {
log.Printf("insertGiftExchangeConfig value: %v, err: %v", req, err)
return 0, err
}
log.Println("insertGiftExchangeConfig res: ", id)
return id, err
}
// http://192.168.2.100:4111/frontApi/game/exchangeCodeVerification?code=1ipq61NK&account=lq0001&time=10000&server=1&channel=000000000000&token
func GetGenerateCode(ctx context.Context, req *game.GetGenerateCodeReq) (res *game.GetGenerateCodeRes, err error) {
res = new(game.GetGenerateCodeRes)
if req.Code == "" {
log.Printf("[%d-%d]CodeExchange failed, code not exist, req.Code: %s", req.Account, req.Server, req.Code)
res.Code = 292
return res, nil
}
if req.Channel == "" {
log.Printf("[%d-%d]CodeExchange failed, channel not exist, req.channel: %s", req.Account, req.Server, req.Channel)
res.Code = 292
return res, nil
}
token := fmt.Sprintf("%x", md5.Sum([]byte("#colony"+fmt.Sprint(req.Account)+fmt.Sprint(req.Time)+fmt.Sprint(req.Code)+fmt.Sprint(req.Server)+req.Channel+"$")))
if req.Time != 10000 && req.Token != token {
log.Printf("[%d-%d]CodeExchange failed, token error, req.Token: %s, md5: %s", req.Account, req.Server, req.Token, token)
res.Code = 290
return res, nil
}
//units := []entity.GameUnit{}
//err1 := dao.GameUnit.Ctx(ctx).Where("uid=?", req.Account).Scan(&units)
//if err1 != nil {
// log.Printf("[%d-%d]CodeExchange get unit error %s", req.Account, req.Server, err1.Error())
// res.Code = 250
// return res, nil
//}
//if len(units) == 0 {
// log.Printf("[%d-%d]CodeExchange unit is null", req.Account, req.Server)
// res.Code = 294
// return res, nil
//}
//unit := entity.GameUnit{}
//for _, v := range units {
// if v.Server == req.Server {
// unit = v
// }
//}
//if unit.Id == 0 {
// log.Printf("[%d-%d]CodeExchange unit is null", req.Account, req.Server)
// res.Code = 294
// return res, nil
//}
res, err = getPasswordKey(ctx, req, req.Channel)
if res.Code != 1 {
return res, nil
}
detail := []entity.GameCdKey{}
err1 := dao.GameCdKey.Ctx(ctx).Where("code=?", req.Code).Scan(&detail)
if err1 != nil {
log.Printf("[%d-%d]CodeExchange get code error %s", req.Account, req.Server, err1.Error())
res.Code = 250
return res, nil
}
if len(detail) <= 0 {
log.Printf("[%d-%d]CodeExchange code[%s] not exist", req.Account, req.Server, req.Code)
res.Code = 291
return res, nil
}
if detail[0].Used != 0 {
log.Printf("[%d-%d]CodeExchange GetGenerateCode code is used: %d", req.Account, req.Server, detail[0].Used)
res.Code = 299
return res, nil
}
exchange := []entity.GameGiftExchange{}
err3 := dao.GameGiftExchange.Ctx(ctx).WherePri(detail[0].ConfigId).Scan(&exchange)
if err3 != nil {
log.Printf("[%d-%d]CodeExchange get code error %s", req.Account, req.Server, err3.Error())
res.Code = 250
return res, nil
}
if exchange[0].Channel != "" && !strings.Contains(exchange[0].Channel, req.Channel) {
log.Printf("[%d-%d]CodeExchange channel error exchange[0].Channel: %s, req.Channel: %s", req.Account, req.Server, exchange[0].Channel, req.Channel)
res.Code = 293
return res, nil
}
//if exchange[0].StartTime != "" {
begin, _ := time.ParseInLocation(consts.TIME_FORMAT, exchange[0].StartTime, time.Local)
if begin.Unix() > time.Now().Unix() {
log.Printf("[%d-%d]CodeExchange not activated", req.Account, req.Server)
res.Code = 297
return res, nil
}
//}
//if exchange[0].StopTime != "" {
end, _ := time.ParseInLocation(consts.TIME_FORMAT, exchange[0].StopTime, time.Local)
if end.Unix() < time.Now().Unix() {
log.Printf("[%d-%d]CodeExchange code is expired", req.Account, req.Server)
res.Code = 295
return res, nil
}
//}
detail1 := []entity.GameCdKey{}
err2 := dao.GameCdKey.Ctx(ctx).Where("used=?", req.Account).Where("server=?", req.Server).Where("configId=?", detail[0].ConfigId).Scan(&detail1)
if err2 != nil {
log.Printf("[%d-%d]CodeExchange get code error %s", req.Account, req.Server, err2.Error())
res.Code = 250
return res, nil
}
if len(detail1) >= exchange[0].Times {
log.Printf("[%d-%d]CodeExchange The usage limit has been reached used: %d, times: %d", req.Account, req.Server, len(detail1), exchange[0].Times)
res.Code = 296
return res, nil
}
_, err4 := dao.GameCdKey.Ctx(ctx).Where("code=?", req.Code).Update(g.Map{dao.GameCdKey.Columns().Used: req.Account, dao.GameCdKey.Columns().Server: req.Server})
if err4 != nil {
log.Printf("[%d-%d]CodeExchange UpdateOne err: %s", req.Account, req.Server, err4.Error())
res.Code = 250
return res, nil
}
log.Printf("[%d-%d]CodeExchange success: %d", req.Account, req.Server, detail[0].ConfigId)
res.Code = 200
res.Rewards = exchange[0].Rewards
return res, nil
}
func getPasswordKey(ctx context.Context, req *game.GetGenerateCodeReq, channel string) (res *game.GetGenerateCodeRes, err error) {
res = new(game.GetGenerateCodeRes)
exchange := []entity.GameGiftExchange{}
err1 := dao.GameGiftExchange.Ctx(ctx).Where("password=?", req.Code).Scan(&exchange)
if err1 != nil {
log.Printf("[%d-%d]CodeExchange get exchange error %s", req.Account, req.Server, err1.Error())
res.Code = 250
return res, nil
}
if len(exchange) <= 0 {
//log.Printf("[%d-%d]CodeExchange password nil: code: %s err: %s", req.Account, req.Server, req.Code, err1.Error())
res.Code = 1
return res, nil
}
if exchange[0].Channel != "" && !strings.Contains(exchange[0].Channel, channel) {
log.Printf("[%d-%d]CodeExchange channel error exchange[0].Channel: %s, req.Channel: %s", req.Account, req.Server, exchange[0].Channel, channel)
res.Code = 293
return res, nil
}
//if exchange[0].StartTime != "" {
begin, _ := time.ParseInLocation(consts.TIME_FORMAT, exchange[0].StartTime, time.Local)
if begin.Unix() > time.Now().Unix() {
log.Printf("[%d-%d]CodeExchange not activated", req.Account, req.Server)
res.Code = 297
return res, nil
}
//}
//if exchange[0].StopTime != "" {
end, _ := time.ParseInLocation(consts.TIME_FORMAT, exchange[0].StopTime, time.Local)
if end.Unix() < time.Now().Unix() {
log.Printf("[%d-%d]CodeExchange code is expired", req.Account, req.Server)
res.Code = 295
return res, nil
}
//}
model := dao.GameCdPassword.Ctx(ctx)
total, err1 := model.Where("account=?", req.Account).Where("server=?", req.Server).Where("config_id=?", exchange[0].Id).Count()
if err1 != nil {
log.Printf("[%d-%d]CodeExchange get GameCdPassword error %s", req.Account, req.Server, err1.Error())
res.Code = 250
return res, nil
}
if total >= exchange[0].Times {
log.Printf("[%d-%d]CodeExchange The usage limit has been reached used: %d, times: %d", req.Account, req.Server, total, exchange[0].Times)
res.Code = 296
return res, nil
}
_, err1 = model.Insert(do.GameCdPassword{Account: req.Account, Server: req.Server, ConfigId: exchange[0].Id})
if err1 != nil {
log.Printf("[%d-%d]CodeExchange insert GameCdPassword error %s", req.Account, req.Server, err1.Error())
res.Code = 250
return res, nil
}
res.Code = 200
res.Rewards = exchange[0].Rewards
return
}
// http://192.168.2.100:4111/frontApi/game/addGenerateCode?id=1&account=10100001&time=10000&token
func AddGenerateCode(ctx context.Context, req *game.AddGenerateCodeReq) (res *game.AddGenerateCodeRes, err error) {
res = new(game.AddGenerateCodeRes)
token := fmt.Sprintf("%x", md5.Sum([]byte("#colony"+fmt.Sprint(req.Id)+fmt.Sprint(req.Account)+fmt.Sprint(req.Time)+"$")))
if req.Time != 10000 && req.Token != token {
log.Printf("[%d]AddGenerateCode failed, token error, req.Token: %s, md5: %s", req.Account, req.Token, token)
return res, nil
}
exchange := []entity.GameGiftExchange{}
err3 := dao.GameGiftExchange.Ctx(ctx).WherePri(req.Id).Scan(&exchange)
if err3 != nil {
log.Printf("[%d]AddGenerateCode get code error %s", req.Account, err3.Error())
return res, nil
}
if len(exchange) == 0 || exchange[0].Id == 0 {
log.Printf("[%d]AddGenerateCode GameGiftExchange nil ", req.Account)
return res, nil
}
//if exchange[0].StartTime != "" {
begin, _ := time.ParseInLocation(consts.TIME_FORMAT, exchange[0].StartTime, time.Local)
if begin.Unix() > time.Now().Unix() {
log.Printf("[%d]AddGenerateCode not activated", req.Account)
return res, nil
}
//}
//if exchange[0].StopTime != "" {
end, _ := time.ParseInLocation(consts.TIME_FORMAT, exchange[0].StopTime, time.Local)
if end.Unix() < time.Now().Unix() {
log.Printf("[%d]AddGenerateCode code is expired", req.Account)
return res, nil
}
//}
charsetSpecial := consts.CHARSETSpecial
charset := consts.CHARSETDef
code := getPreValue(req.Id, charsetSpecial) + getPreValue(req.Account, charset)
detail := []entity.GameCdKey{}
err1 := dao.GameCdKey.Ctx(ctx).Where("code=?", code).Scan(&detail)
if err1 != nil {
log.Printf("[%d]AddGenerateCode get code error %s", req.Account, err1.Error())
return res, nil
}
if len(detail) > 0 {
log.Printf("[%d]AddGenerateCode code not exist", req.Account)
return res, nil
}
_, _ = dao.GameCdKey.Ctx(ctx).Insert(g.Map{
dao.GameCdKey.Columns().Code: code,
dao.GameCdKey.Columns().ConfigId: req.Id,
})
log.Printf("[%d]AddGenerateCode success: %d", req.Account, req.Id)
res.Code = code
return res, nil
}