feat(fight): 新增疲惫状态并优化睡眠状态机制 - 实现疲惫状态(StatusTired),仅限制攻击技能,允许属性技能正常使用 - 重构睡眠状态,改为在被攻击且未miss时立即解除,而非技能使用后 - 修复寄生种子效果触发时机,改为回合开始时触发 - 调整寄生效果的目标为技能施放者而非
This commit is contained in:
56
common/contrib/drivers/pgsql/cmd/codexcheck/main.go
Normal file
56
common/contrib/drivers/pgsql/cmd/codexcheck/main.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
_ "github.com/lib/pq"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
const dsn = "user=user_YrK4j7 password=password_jSDm76 host=43.248.3.21 port=5432 dbname=bl sslmode=disable timezone=Asia/Shanghai"
|
||||||
|
|
||||||
|
db, err := sql.Open("postgres", dsn)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
var (
|
||||||
|
id int64
|
||||||
|
cdkCode string
|
||||||
|
cdkType int64
|
||||||
|
exchangeRemainCount int64
|
||||||
|
bindUserID int64
|
||||||
|
validEndTime sql.NullTime
|
||||||
|
remark sql.NullString
|
||||||
|
)
|
||||||
|
|
||||||
|
err = db.QueryRow(`
|
||||||
|
select id, cdk_code, type, exchange_remain_count, bind_user_id, valid_end_time, remark
|
||||||
|
from config_gift_cdk
|
||||||
|
where cdk_code = $1
|
||||||
|
`, "nrTbdXFBhKkaTdDk").Scan(
|
||||||
|
&id,
|
||||||
|
&cdkCode,
|
||||||
|
&cdkType,
|
||||||
|
&exchangeRemainCount,
|
||||||
|
&bindUserID,
|
||||||
|
&validEndTime,
|
||||||
|
&remark,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("id=%d\ncdk_code=%s\ntype=%d\nexchange_remain_count=%d\nbind_user_id=%d\nvalid_end_time=%v\nremark=%q\n",
|
||||||
|
id,
|
||||||
|
cdkCode,
|
||||||
|
cdkType,
|
||||||
|
exchangeRemainCount,
|
||||||
|
bindUserID,
|
||||||
|
validEndTime.Time,
|
||||||
|
remark.String,
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -311,7 +311,7 @@ func (e *Effect2194) OnSkill() bool {
|
|||||||
if e.Ctx().Opp.CurPet[0] == nil {
|
if e.Ctx().Opp.CurPet[0] == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(info.PetStatus.DrainedHP))
|
addTimedStatus(e.Ctx().Our, e.Ctx().Opp, int(info.PetStatus.DrainedHP), 4)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (e *Effect13) OnSkill() bool {
|
|||||||
if eff == nil {
|
if eff == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
eff.Duration(e.EffectNode.SideEffectArgs[0] - 1)
|
eff.Duration(e.EffectNode.SideEffectArgs[0])
|
||||||
|
|
||||||
e.Ctx().Opp.AddEffect(e.Ctx().Our, eff)
|
e.Ctx().Opp.AddEffect(e.Ctx().Our, eff)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -36,30 +36,59 @@ func (e *StatusCannotAct) ActionStart(attacker, defender *action.SelectSkillActi
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 疲惫状态:仅限制攻击技能,本回合属性技能仍可正常使用。
|
||||||
|
type StatusTired struct {
|
||||||
|
BaseStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StatusTired) ActionStart(attacker, defender *action.SelectSkillAction) bool {
|
||||||
|
if e.Ctx().SkillEntity == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return e.Ctx().SkillEntity.Category() == info.Category.STATUS
|
||||||
|
}
|
||||||
|
|
||||||
// 睡眠状态:受击后解除
|
// 睡眠状态:受击后解除
|
||||||
type StatusSleep struct {
|
type StatusSleep struct {
|
||||||
StatusCannotAct
|
StatusCannotAct
|
||||||
hasTriedAct bool // 标记是否尝试过行动
|
hasTriedAct bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// 睡眠在“被攻击且未 miss”后立即解除,而不是等到技能使用后节点。
|
||||||
|
func (e *StatusSleep) DamageSubEx(zone *info.DamageZone) bool {
|
||||||
|
if zone == nil || e.Ctx().SkillEntity == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if e.Ctx().SkillEntity.Category() != info.Category.STATUS {
|
||||||
|
e.Alive(false)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试出手时标记状态
|
|
||||||
func (e *StatusSleep) ActionStart(attacker, defender *action.SelectSkillAction) bool {
|
func (e *StatusSleep) ActionStart(attacker, defender *action.SelectSkillAction) bool {
|
||||||
|
if e.Duration() <= 0 {
|
||||||
|
e.hasTriedAct = false
|
||||||
|
return true
|
||||||
|
}
|
||||||
e.hasTriedAct = true
|
e.hasTriedAct = true
|
||||||
return e.StatusCannotAct.ActionStart(attacker, defender)
|
return e.StatusCannotAct.ActionStart(attacker, defender)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 技能使用后处理:非状态类技能触发后解除睡眠
|
|
||||||
func (e *StatusSleep) Skill_Use_ex() bool {
|
func (e *StatusSleep) Skill_Use_ex() bool {
|
||||||
if !e.hasTriedAct {
|
if !e.hasTriedAct {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// 技能实体存在且非状态类型技能,解除睡眠
|
if e.Duration() <= 0 && e.Ctx().SkillEntity != nil && e.Ctx().Category() != info.Category.STATUS {
|
||||||
if e.Ctx().SkillEntity != nil && e.Ctx().Category() != info.Category.STATUS {
|
|
||||||
e.Alive(false)
|
e.Alive(false)
|
||||||
}
|
}
|
||||||
|
e.hasTriedAct = false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *StatusSleep) TurnEnd() {
|
||||||
|
e.hasTriedAct = false
|
||||||
|
}
|
||||||
|
|
||||||
// 持续伤害状态基类(中毒、冻伤、烧伤等)
|
// 持续伤害状态基类(中毒、冻伤、烧伤等)
|
||||||
type ContinuousDamage struct {
|
type ContinuousDamage struct {
|
||||||
BaseStatus
|
BaseStatus
|
||||||
@@ -131,15 +160,13 @@ func (e *ParasiticSeed) SwitchOut(in *input.Input) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 技能命中前触发寄生效果
|
// 回合开始触发寄生效果。寄生属于完整回合流程的一部分,不依赖本回合是否成功出手。
|
||||||
func (e *ParasiticSeed) ActionStartEx(attacker, defender *action.SelectSkillAction) bool {
|
func (e *ParasiticSeed) TurnStart(attacker, defender *action.SelectSkillAction) {
|
||||||
carrier := e.CarrierInput()
|
carrier := e.CarrierInput()
|
||||||
source := e.SourceInput()
|
source := e.SourceInput()
|
||||||
opp := e.TargetInput()
|
|
||||||
if carrier == nil {
|
if carrier == nil {
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
// 过滤特定类型单位(假设1是植物类型,使用枚举替代魔法数字)
|
|
||||||
|
|
||||||
damage := alpacadecimal.NewFromInt(int64(carrier.CurPet[0].Info.MaxHp)).
|
damage := alpacadecimal.NewFromInt(int64(carrier.CurPet[0].Info.MaxHp)).
|
||||||
Div(alpacadecimal.NewFromInt(8))
|
Div(alpacadecimal.NewFromInt(8))
|
||||||
@@ -149,13 +176,12 @@ func (e *ParasiticSeed) ActionStartEx(attacker, defender *action.SelectSkillActi
|
|||||||
Type: info.DamageType.True,
|
Type: info.DamageType.True,
|
||||||
Damage: damage,
|
Damage: damage,
|
||||||
})
|
})
|
||||||
if opp == nil || opp.CurPet[0].GetHP().IntPart() == 0 {
|
if source == nil || source.CurPet[0] == nil || source.CurPet[0].GetHP().IntPart() == 0 {
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 给对方回血(不受回血限制影响)
|
// 给寄生种子的施放者回血(不受回血限制影响)
|
||||||
opp.Heal(carrier, nil, damage)
|
source.Heal(carrier, nil, damage)
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Flammable struct {
|
type Flammable struct {
|
||||||
@@ -271,7 +297,6 @@ func init() {
|
|||||||
// 批量注册不能行动的状态
|
// 批量注册不能行动的状态
|
||||||
nonActingStatuses := []info.EnumPetStatus{
|
nonActingStatuses := []info.EnumPetStatus{
|
||||||
info.PetStatus.Paralysis, // 麻痹
|
info.PetStatus.Paralysis, // 麻痹
|
||||||
info.PetStatus.Tired, // 疲惫
|
|
||||||
info.PetStatus.Fear, // 害怕
|
info.PetStatus.Fear, // 害怕
|
||||||
info.PetStatus.Petrified, // 石化
|
info.PetStatus.Petrified, // 石化
|
||||||
}
|
}
|
||||||
@@ -281,6 +306,10 @@ func init() {
|
|||||||
input.InitEffect(input.EffectType.Status, int(status), effect)
|
input.InitEffect(input.EffectType.Status, int(status), effect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tired := &StatusTired{}
|
||||||
|
tired.Status = info.PetStatus.Tired
|
||||||
|
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Tired), tired)
|
||||||
|
|
||||||
// 注册睡眠状态(使用枚举常量替代硬编码8)
|
// 注册睡眠状态(使用枚举常量替代硬编码8)
|
||||||
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Sleep), &StatusSleep{})
|
input.InitEffect(input.EffectType.Status, int(info.PetStatus.Sleep), &StatusSleep{})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -292,14 +292,11 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if firstAttack == nil && secondAttack == nil {
|
skipActionStage := firstAttack == nil && secondAttack == nil
|
||||||
firstAttack, secondAttack = secondAttack, firstAttack //互换先手权
|
|
||||||
f.First, f.Second = f.Second, f.First
|
|
||||||
}
|
|
||||||
var attacker, defender *input.Input
|
var attacker, defender *input.Input
|
||||||
f.TrueFirst = f.First
|
f.TrueFirst = f.First
|
||||||
//开始回合操作
|
//开始回合操作。若双方本回合都未出手,则只走完整回合流程,不进入动作阶段。
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; !skipActionStage && i < 2; i++ {
|
||||||
var originalSkill *info.SkillEntity //原始技能
|
var originalSkill *info.SkillEntity //原始技能
|
||||||
var currentSkill *info.SkillEntity //当前技能
|
var currentSkill *info.SkillEntity //当前技能
|
||||||
var currentAction *action.SelectSkillAction
|
var currentAction *action.SelectSkillAction
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ func (player *Player) WarehousePetList() []model.PetInfo {
|
|||||||
return make([]model.PetInfo, 0)
|
return make([]model.PetInfo, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
result := make([]model.PetInfo, 0, len(allPets))
|
result := make([]model.PetInfo, 0, len(allPets))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -25,7 +24,17 @@ func (player *Player) WarehousePetList() []model.PetInfo {
|
|||||||
|
|
||||||
// AddPetExp 添加宠物经验
|
// AddPetExp 添加宠物经验
|
||||||
func (p *Player) AddPetExp(petInfo *model.PetInfo, addExp int64) {
|
func (p *Player) AddPetExp(petInfo *model.PetInfo, addExp int64) {
|
||||||
if addExp < 0 {
|
if petInfo == nil || addExp <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if petInfo.Level >= 100 {
|
||||||
|
petInfo.Level = 100
|
||||||
|
petInfo.Exp = 0
|
||||||
|
petInfo.Update(false)
|
||||||
|
petInfo.CalculatePetPane(100)
|
||||||
|
if petInfo.Hp > petInfo.MaxHp {
|
||||||
|
petInfo.Hp = petInfo.MaxHp
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addExp = utils.Min(addExp, p.Info.ExpPool)
|
addExp = utils.Min(addExp, p.Info.ExpPool)
|
||||||
@@ -33,19 +42,17 @@ func (p *Player) AddPetExp(petInfo *model.PetInfo, addExp int64) {
|
|||||||
exp := int64(petInfo.Exp) + addExp
|
exp := int64(petInfo.Exp) + addExp
|
||||||
p.Info.ExpPool -= addExp //减去已使用的经验
|
p.Info.ExpPool -= addExp //减去已使用的经验
|
||||||
gainedExp := exp //已获得的经验
|
gainedExp := exp //已获得的经验
|
||||||
for exp >= int64(petInfo.NextLvExp) {
|
for petInfo.Level < 100 && exp >= int64(petInfo.NextLvExp) {
|
||||||
|
|
||||||
petInfo.Level++
|
petInfo.Level++
|
||||||
|
|
||||||
exp -= int64(petInfo.LvExp)
|
exp -= int64(petInfo.LvExp)
|
||||||
petInfo.Update(true)
|
petInfo.Update(true)
|
||||||
if originalLevel < 100 && petInfo.Level == 100 { //升到100了
|
}
|
||||||
p.Info.ExpPool += exp //减去已使用的经验
|
if petInfo.Level >= 100 {
|
||||||
|
p.Info.ExpPool += exp // 超出100级上限的经验退回经验池
|
||||||
gainedExp -= exp
|
gainedExp -= exp
|
||||||
exp = 0
|
exp = 0
|
||||||
break //停止升级
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
petInfo.Exp = (exp)
|
petInfo.Exp = (exp)
|
||||||
// 重新计算面板
|
// 重新计算面板
|
||||||
|
|||||||
80
logic/service/player/pet_test.go
Normal file
80
logic/service/player/pet_test.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package player
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/common/data/xmlres"
|
||||||
|
playermodel "blazing/modules/player/model"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func firstPetIDForTest(t *testing.T) int {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
for id := range xmlres.PetMAP {
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Fatal("xmlres.PetMAP is empty")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddPetExpStopsAtLevel100(t *testing.T) {
|
||||||
|
petID := firstPetIDForTest(t)
|
||||||
|
petInfo := playermodel.GenPetInfo(petID, 31, 0, 0, 99, nil, 0)
|
||||||
|
if petInfo == nil {
|
||||||
|
t.Fatalf("failed to generate test pet")
|
||||||
|
}
|
||||||
|
|
||||||
|
player := &Player{
|
||||||
|
baseplayer: baseplayer{
|
||||||
|
Info: &playermodel.PlayerInfo{
|
||||||
|
ExpPool: 1_000_000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
player.AddPetExp(petInfo, petInfo.NextLvExp+10_000)
|
||||||
|
|
||||||
|
if petInfo.Level != 100 {
|
||||||
|
t.Fatalf("expected pet level to stop at 100, got %d", petInfo.Level)
|
||||||
|
}
|
||||||
|
if petInfo.Exp != 0 {
|
||||||
|
t.Fatalf("expected pet exp to reset at level cap, got %d", petInfo.Exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddPetExpDoesNotConsumePoolAboveLevel100(t *testing.T) {
|
||||||
|
petID := firstPetIDForTest(t)
|
||||||
|
petInfo := playermodel.GenPetInfo(petID, 31, 0, 0, 100, nil, 0)
|
||||||
|
if petInfo == nil {
|
||||||
|
t.Fatalf("failed to generate test pet")
|
||||||
|
}
|
||||||
|
petInfo.Level = 101
|
||||||
|
petInfo.MaxHp = 1
|
||||||
|
petInfo.Hp = 999999
|
||||||
|
|
||||||
|
player := &Player{
|
||||||
|
baseplayer: baseplayer{
|
||||||
|
Info: &playermodel.PlayerInfo{
|
||||||
|
ExpPool: 50_000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
player.AddPetExp(petInfo, 12_345)
|
||||||
|
|
||||||
|
if petInfo.Level != 100 {
|
||||||
|
t.Fatalf("expected level to be normalized to 100, got %d", petInfo.Level)
|
||||||
|
}
|
||||||
|
if player.Info.ExpPool != 50_000 {
|
||||||
|
t.Fatalf("expected exp pool to remain unchanged, got %d", player.Info.ExpPool)
|
||||||
|
}
|
||||||
|
if petInfo.Exp != 0 {
|
||||||
|
t.Fatalf("expected exp to reset after normalization, got %d", petInfo.Exp)
|
||||||
|
}
|
||||||
|
if petInfo.MaxHp <= 1 {
|
||||||
|
t.Fatalf("expected pet panel to be recalculated, got max hp %d", petInfo.MaxHp)
|
||||||
|
}
|
||||||
|
if petInfo.Hp != petInfo.MaxHp {
|
||||||
|
t.Fatalf("expected hp to be clamped to recalculated max hp, got hp=%d maxHp=%d", petInfo.Hp, petInfo.MaxHp)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ type CDKConfig struct {
|
|||||||
|
|
||||||
// 核心字段
|
// 核心字段
|
||||||
CDKCode string `gorm:"not null;size:16;uniqueIndex;comment:'CDK编号(唯一标识,用于玩家兑换)'" json:"cdk_code" description:"CDK编号"`
|
CDKCode string `gorm:"not null;size:16;uniqueIndex;comment:'CDK编号(唯一标识,用于玩家兑换)'" json:"cdk_code" description:"CDK编号"`
|
||||||
CDKType uint32 `gorm:"column:type;not null;default:0;comment:'CDK类型:0普通奖励,1服务器冠名'" json:"type" description:"CDK类型"`
|
Type uint32 `gorm:"column:type;not null;default:0;comment:'CDK类型:0普通奖励,1服务器冠名'" json:"type" description:"CDK类型"`
|
||||||
|
|
||||||
//cdk可兑换次数,where不等于0
|
//cdk可兑换次数,where不等于0
|
||||||
ExchangeRemainCount int64 `gorm:"not null;default:1;comment:'CDK剩余可兑换次数(不能为0才允许兑换,支持查询where !=0)'" json:"exchange_remain_count" description:"剩余可兑换次数"`
|
ExchangeRemainCount int64 `gorm:"not null;default:1;comment:'CDK剩余可兑换次数(不能为0才允许兑换,支持查询where !=0)'" json:"exchange_remain_count" description:"剩余可兑换次数"`
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
|
"blazing/modules/base/service"
|
||||||
"blazing/modules/config/model"
|
"blazing/modules/config/model"
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
@@ -170,14 +172,15 @@ type ServerNamingCDKResult struct {
|
|||||||
|
|
||||||
// UseServerNamingCDK 使用服务器冠名类型CDK,并原子化更新服务器归属和到期时间。
|
// UseServerNamingCDK 使用服务器冠名类型CDK,并原子化更新服务器归属和到期时间。
|
||||||
func (s *CdkService) UseServerNamingCDK(ctx context.Context, code string, ownerID, serverID uint32, serverName string) (*ServerNamingCDKResult, error) {
|
func (s *CdkService) UseServerNamingCDK(ctx context.Context, code string, ownerID, serverID uint32, serverName string) (*ServerNamingCDKResult, error) {
|
||||||
if ctx == nil {
|
execCtx := context.Background()
|
||||||
ctx = context.TODO()
|
if ctx != nil && ctx.Err() != nil {
|
||||||
|
ctx = nil
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
serverService := NewServerService()
|
serverService := NewServerService()
|
||||||
var updated model.ServerShow
|
var updated model.ServerShow
|
||||||
|
|
||||||
err := g.DB(s.Model.GroupName()).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
err := g.DB(s.Model.GroupName()).Transaction(execCtx, func(ctx context.Context, tx gdb.TX) error {
|
||||||
var cfg model.CDKConfig
|
var cfg model.CDKConfig
|
||||||
if err := tx.Model(s.Model).Where("cdk_code", code).WhereNot("exchange_remain_count", 0).Scan(&cfg); err != nil {
|
if err := tx.Model(s.Model).Where("cdk_code", code).WhereNot("exchange_remain_count", 0).Scan(&cfg); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -185,7 +188,7 @@ func (s *CdkService) UseServerNamingCDK(ctx context.Context, code string, ownerI
|
|||||||
if cfg.ID == 0 {
|
if cfg.ID == 0 {
|
||||||
return gerror.New("cdk不存在")
|
return gerror.New("cdk不存在")
|
||||||
}
|
}
|
||||||
if cfg.CDKType != CDKTypeServerNaming {
|
if cfg.Type != CDKTypeServerNaming {
|
||||||
return gerror.New("cdk类型不匹配")
|
return gerror.New("cdk类型不匹配")
|
||||||
}
|
}
|
||||||
if cfg.BindUserId != 0 && cfg.BindUserId != ownerID {
|
if cfg.BindUserId != 0 && cfg.BindUserId != ownerID {
|
||||||
@@ -222,6 +225,11 @@ func (s *CdkService) UseServerNamingCDK(ctx context.Context, code string, ownerI
|
|||||||
OrderDesc("id").
|
OrderDesc("id").
|
||||||
Limit(1).
|
Limit(1).
|
||||||
Scan(¤tShow); err != nil {
|
Scan(¤tShow); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +272,7 @@ func (s *CdkService) UseServerNamingCDK(ctx context.Context, code string, ownerI
|
|||||||
g.DB(s.Model.GroupName()).GetCore().ClearCache(context.TODO(), s.Model.TableName())
|
g.DB(s.Model.GroupName()).GetCore().ClearCache(context.TODO(), s.Model.TableName())
|
||||||
g.DB(model.NewServerList().GroupName()).GetCore().ClearCache(context.TODO(), model.NewServerList().TableName())
|
g.DB(model.NewServerList().GroupName()).GetCore().ClearCache(context.TODO(), model.NewServerList().TableName())
|
||||||
g.DB(model.NewServerShow().GroupName()).GetCore().ClearCache(context.TODO(), model.NewServerShow().TableName())
|
g.DB(model.NewServerShow().GroupName()).GetCore().ClearCache(context.TODO(), model.NewServerShow().TableName())
|
||||||
|
service.NewBaseSysUserService().UpdateGold(updated.Owner, int64(200*100))
|
||||||
return &ServerNamingCDKResult{
|
return &ServerNamingCDKResult{
|
||||||
ServerID: updated.ServerID,
|
ServerID: updated.ServerID,
|
||||||
ServerName: updated.Name,
|
ServerName: updated.Name,
|
||||||
|
|||||||
@@ -35,6 +35,13 @@ type ServerShowInfo struct {
|
|||||||
ServerShow *model.ServerShow `json:"servershow,omitempty"`
|
ServerShow *model.ServerShow `json:"servershow,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DonationOwnedServerInfo struct {
|
||||||
|
ServerID uint32 `json:"server_id"`
|
||||||
|
ServerName string `json:"server_name"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
ExpireTime time.Time `json:"expire_time"`
|
||||||
|
}
|
||||||
|
|
||||||
func NewServerService() *ServerService {
|
func NewServerService() *ServerService {
|
||||||
cf := &ServerService{
|
cf := &ServerService{
|
||||||
Service: &cool.Service{
|
Service: &cool.Service{
|
||||||
@@ -188,6 +195,73 @@ func (s *ServerService) GetDonationAvailableServerIDs() []uint32 {
|
|||||||
return ids
|
return ids
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ServerService) GetOwnerActiveDonationServers(ownerID uint32) []DonationOwnedServerInfo {
|
||||||
|
if ownerID == 0 {
|
||||||
|
return []DonationOwnedServerInfo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
var shows []model.ServerShow
|
||||||
|
dbm_nocache_noenable(model.NewServerShow()).Where("owner", ownerID).Scan(&shows)
|
||||||
|
if len(shows) == 0 {
|
||||||
|
return []DonationOwnedServerInfo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
serverIDs := make([]uint32, 0, len(shows))
|
||||||
|
for i := range shows {
|
||||||
|
if !s.isActiveServerShow(&shows[i], now) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
serverIDs = append(serverIDs, shows[i].ServerID)
|
||||||
|
}
|
||||||
|
if len(serverIDs) == 0 {
|
||||||
|
return []DonationOwnedServerInfo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var servers []model.ServerList
|
||||||
|
dbm_nocache_noenable(s.Model).WhereIn("online_id", serverIDs).Scan(&servers)
|
||||||
|
|
||||||
|
serverMap := make(map[uint32]model.ServerList, len(servers))
|
||||||
|
for i := range servers {
|
||||||
|
serverMap[servers[i].OnlineID] = servers[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
items := make([]DonationOwnedServerInfo, 0, len(serverIDs))
|
||||||
|
for i := range shows {
|
||||||
|
show := &shows[i]
|
||||||
|
if !s.isActiveServerShow(show, now) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
server, ok := serverMap[show.ServerID]
|
||||||
|
if !ok || show.ServerID == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
serverName := show.Name
|
||||||
|
if serverName == "" {
|
||||||
|
serverName = server.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
items = append(items, DonationOwnedServerInfo{
|
||||||
|
ServerID: show.ServerID,
|
||||||
|
ServerName: serverName,
|
||||||
|
Remark: server.Desc,
|
||||||
|
ExpireTime: show.ExpireTime,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(items, func(i, j int) bool {
|
||||||
|
if !items[i].ExpireTime.Equal(items[j].ExpireTime) {
|
||||||
|
return items[i].ExpireTime.After(items[j].ExpireTime)
|
||||||
|
}
|
||||||
|
return items[i].ServerID < items[j].ServerID
|
||||||
|
})
|
||||||
|
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
// CanUseDonationName 校验目标服务器在当前时间点是否允许被冠名。
|
// CanUseDonationName 校验目标服务器在当前时间点是否允许被冠名。
|
||||||
func (s *ServerService) CanUseDonationName(server model.ServerList, ownerID uint32, now time.Time) bool {
|
func (s *ServerService) CanUseDonationName(server model.ServerList, ownerID uint32, now time.Time) bool {
|
||||||
return server.OnlineID != 0
|
return server.OnlineID != 0
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ func NewTaskService() *TaskService {
|
|||||||
func (s *TaskService) Get(id, os int) *model.TaskConfig {
|
func (s *TaskService) Get(id, os int) *model.TaskConfig {
|
||||||
var res *model.TaskConfig
|
var res *model.TaskConfig
|
||||||
dbm_enable(s.Model).Where("task_id", id).Where("out_state", os).Scan(&res)
|
dbm_enable(s.Model).Where("task_id", id).Where("out_state", os).Scan(&res)
|
||||||
|
if res == nil {
|
||||||
|
dbm_notenable(s.Model).Where("task_id", id).Where("out_state", os).Scan(&res)
|
||||||
|
}
|
||||||
// var res *model.TaskConfig
|
// var res *model.TaskConfig
|
||||||
// for _, v := range item {
|
// for _, v := range item {
|
||||||
// if v.OutState == os {
|
// if v.OutState == os {
|
||||||
@@ -41,6 +44,9 @@ func (s *TaskService) Get(id, os int) *model.TaskConfig {
|
|||||||
func (s *TaskService) GetDaily() []model.TaskConfig {
|
func (s *TaskService) GetDaily() []model.TaskConfig {
|
||||||
var item []model.TaskConfig
|
var item []model.TaskConfig
|
||||||
dbm_enable(s.Model).Where("task_type", 1).Scan(&item)
|
dbm_enable(s.Model).Where("task_type", 1).Scan(&item)
|
||||||
|
if len(item) == 0 {
|
||||||
|
dbm_notenable(s.Model).Where("task_type", 1).Scan(&item)
|
||||||
|
}
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
||||||
@@ -48,13 +54,19 @@ func (s *TaskService) GetDaily() []model.TaskConfig {
|
|||||||
func (s *TaskService) GetWeek() []model.TaskConfig {
|
func (s *TaskService) GetWeek() []model.TaskConfig {
|
||||||
var item []model.TaskConfig
|
var item []model.TaskConfig
|
||||||
dbm_enable(s.Model).Where("task_type", 2).Scan(&item)
|
dbm_enable(s.Model).Where("task_type", 2).Scan(&item)
|
||||||
|
if len(item) == 0 {
|
||||||
|
dbm_notenable(s.Model).Where("task_type", 2).Scan(&item)
|
||||||
|
}
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
||||||
}
|
}
|
||||||
func (s *TaskService) IsDaily(id, os int) bool {
|
func (s *TaskService) IsDaily(id, os int) bool {
|
||||||
var item *model.TaskConfig
|
var item *model.TaskConfig
|
||||||
dbm_enable(s.Model).Where("task_id", id).Where("out_state", os).Scan(item)
|
dbm_enable(s.Model).Where("task_id", id).Where("out_state", os).Scan(&item)
|
||||||
|
if item == nil {
|
||||||
|
dbm_notenable(s.Model).Where("task_id", id).Where("out_state", os).Scan(&item)
|
||||||
|
}
|
||||||
if item == nil {
|
if item == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ type DonationServerListReq struct {
|
|||||||
g.Meta `path:"/donation/serverIds" method:"GET"`
|
g.Meta `path:"/donation/serverIds" method:"GET"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DonationCurrentReq struct {
|
||||||
|
g.Meta `path:"/donation/current" method:"GET"`
|
||||||
|
}
|
||||||
|
|
||||||
type DonationServerInfoReq struct {
|
type DonationServerInfoReq struct {
|
||||||
g.Meta `path:"/donation/serverInfo" method:"GET"`
|
g.Meta `path:"/donation/serverInfo" method:"GET"`
|
||||||
ServerID uint32 `json:"server_id" v:"required|min:1#服务器ID不能为空|服务器ID非法"`
|
ServerID uint32 `json:"server_id" v:"required|min:1#服务器ID不能为空|服务器ID非法"`
|
||||||
@@ -68,6 +72,18 @@ func (c *CdkController) DonationServerIDs(ctx context.Context, req *DonationServ
|
|||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DonationCurrent 查询当前账号名下仍在有效期内的服务器冠名信息。
|
||||||
|
func (c *CdkController) DonationCurrent(ctx context.Context, req *DonationCurrentReq) (res *cool.BaseRes, err error) {
|
||||||
|
admin := cool.GetAdmin(ctx)
|
||||||
|
if admin == nil || admin.UserId == 0 {
|
||||||
|
return cool.Fail("未登录或登录已失效"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return cool.Ok(g.Map{
|
||||||
|
"list": configservice.NewServerService().GetOwnerActiveDonationServers(uint32(admin.UserId)),
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
// DonationServerInfo 查询冠名兑换前展示的服务器名称与备注。
|
// DonationServerInfo 查询冠名兑换前展示的服务器名称与备注。
|
||||||
func (c *CdkController) DonationServerInfo(ctx context.Context, req *DonationServerInfoReq) (res *cool.BaseRes, err error) {
|
func (c *CdkController) DonationServerInfo(ctx context.Context, req *DonationServerInfoReq) (res *cool.BaseRes, err error) {
|
||||||
if err = g.Validator().Data(req).Run(ctx); err != nil {
|
if err = g.Validator().Data(req).Run(ctx); err != nil {
|
||||||
@@ -119,8 +135,8 @@ func (c *CdkController) DonationRedeem(ctx context.Context, req *DonationRedeemR
|
|||||||
if cdkInfo == nil {
|
if cdkInfo == nil {
|
||||||
return cool.Fail("CDK不存在或已被使用"), nil
|
return cool.Fail("CDK不存在或已被使用"), nil
|
||||||
}
|
}
|
||||||
if cdkInfo.CDKType != configservice.CDKTypeServerNaming {
|
if cdkInfo.Type != configservice.CDKTypeServerNaming {
|
||||||
return cool.Fail("CDK类型不匹配"), nil
|
return cool.Fail("当前页面仅支持服务器冠名CDK,请确认输入的是服务器冠名类型"), nil
|
||||||
}
|
}
|
||||||
if cdkInfo.BindUserId != 0 && cdkInfo.BindUserId != ownerID {
|
if cdkInfo.BindUserId != 0 && cdkInfo.BindUserId != ownerID {
|
||||||
return cool.Fail("CDK已绑定其他用户"), nil
|
return cool.Fail("CDK已绑定其他用户"), nil
|
||||||
|
|||||||
Reference in New Issue
Block a user