This commit is contained in:
@@ -3,6 +3,7 @@ package cool
|
|||||||
import (
|
import (
|
||||||
_ "blazing/contrib/drivers/pgsql"
|
_ "blazing/contrib/drivers/pgsql"
|
||||||
"blazing/cool/cooldb"
|
"blazing/cool/cooldb"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/encoding/gjson"
|
"github.com/gogf/gf/v2/encoding/gjson"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
@@ -10,6 +11,11 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
autoMigrateMu sync.Mutex
|
||||||
|
autoMigrateModels []IModel
|
||||||
|
)
|
||||||
|
|
||||||
// 初始化数据库连接供gorm使用
|
// 初始化数据库连接供gorm使用
|
||||||
func InitDB(group string) (*gorm.DB, error) {
|
func InitDB(group string) (*gorm.DB, error) {
|
||||||
// var ctx context.Context
|
// var ctx context.Context
|
||||||
@@ -54,9 +60,33 @@ func getDBbyModel(model IModel) *gorm.DB {
|
|||||||
|
|
||||||
// 根据entity结构体创建表
|
// 根据entity结构体创建表
|
||||||
func CreateTable(model IModel) error {
|
func CreateTable(model IModel) error {
|
||||||
if Config.AutoMigrate {
|
autoMigrateMu.Lock()
|
||||||
|
autoMigrateModels = append(autoMigrateModels, model)
|
||||||
|
autoMigrateMu.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunAutoMigrate 显式执行已注册模型的建表/迁移。
|
||||||
|
func RunAutoMigrate() error {
|
||||||
|
if !Config.AutoMigrate {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
autoMigrateMu.Lock()
|
||||||
|
models := append([]IModel(nil), autoMigrateModels...)
|
||||||
|
autoMigrateMu.Unlock()
|
||||||
|
|
||||||
|
seen := make(map[string]struct{}, len(models))
|
||||||
|
for _, model := range models {
|
||||||
|
key := model.GroupName() + ":" + model.TableName()
|
||||||
|
if _, ok := seen[key]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[key] = struct{}{}
|
||||||
|
|
||||||
db := getDBbyModel(model)
|
db := getDBbyModel(model)
|
||||||
return db.AutoMigrate(model)
|
if err := db.AutoMigrate(model); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ func startMapBossFight(
|
|||||||
ai *player.AI_player,
|
ai *player.AI_player,
|
||||||
fn func(model.FightOverInfo),
|
fn func(model.FightOverInfo),
|
||||||
) (*fight.FightC, errorcode.ErrorCode) {
|
) (*fight.FightC, errorcode.ErrorCode) {
|
||||||
ourPets := p.GetPetInfo(100)
|
ourPets := p.GetPetInfo(p.CurrentMapPetLevelLimit())
|
||||||
oppPets := ai.GetPetInfo(0)
|
oppPets := ai.GetPetInfo(0)
|
||||||
if mapNode != nil && mapNode.IsGroupBoss != 0 {
|
if mapNode != nil && mapNode.IsGroupBoss != 0 {
|
||||||
if len(ourPets) > 0 && len(oppPets) > 0 {
|
if len(ourPets) > 0 && len(oppPets) > 0 {
|
||||||
@@ -98,8 +98,8 @@ func (Controller) OnPlayerFightNpcMonster(req *FightNpcMonsterInboundInfo, p *pl
|
|||||||
if err = p.CanFight(); err != 0 {
|
if err = p.CanFight(); err != 0 {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if req.Number > 9 {
|
if int(req.Number) >= len(p.Data) {
|
||||||
return nil, errorcode.ErrorCodes.ErrSystemError
|
return nil, errorcode.ErrorCodes.ErrPokemonNotHere
|
||||||
}
|
}
|
||||||
|
|
||||||
refPet := p.Data[req.Number]
|
refPet := p.Data[req.Number]
|
||||||
@@ -114,7 +114,7 @@ func (Controller) OnPlayerFightNpcMonster(req *FightNpcMonsterInboundInfo, p *pl
|
|||||||
p.Fightinfo.Status = fightinfo.BattleMode.FIGHT_WITH_NPC
|
p.Fightinfo.Status = fightinfo.BattleMode.FIGHT_WITH_NPC
|
||||||
p.Fightinfo.Mode = fightinfo.BattleMode.MULTI_MODE
|
p.Fightinfo.Mode = fightinfo.BattleMode.MULTI_MODE
|
||||||
|
|
||||||
_, err = fight.NewFight(p, ai, p.GetPetInfo(100), ai.GetPetInfo(0), func(foi model.FightOverInfo) {
|
_, err = fight.NewFight(p, ai, p.GetPetInfo(p.CurrentMapPetLevelLimit()), ai.GetPetInfo(0), func(foi model.FightOverInfo) {
|
||||||
handleNpcFightRewards(p, foi, monster)
|
handleNpcFightRewards(p, foi, monster)
|
||||||
})
|
})
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
@@ -236,7 +236,7 @@ func shouldGrantBossWinBonus(fightC *fight.FightC, playerID uint32, bossConfig c
|
|||||||
|
|
||||||
func buildNpcMonsterInfo(refPet player.OgrePetInfo, mapID uint32) (*model.PetInfo, *model.PlayerInfo, errorcode.ErrorCode) {
|
func buildNpcMonsterInfo(refPet player.OgrePetInfo, mapID uint32) (*model.PetInfo, *model.PlayerInfo, errorcode.ErrorCode) {
|
||||||
if refPet.ID == 0 {
|
if refPet.ID == 0 {
|
||||||
return nil, nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
return nil, nil, errorcode.ErrorCodes.ErrPokemonNotHere
|
||||||
}
|
}
|
||||||
|
|
||||||
monster := model.GenPetInfo(
|
monster := model.GenPetInfo(
|
||||||
|
|||||||
@@ -17,11 +17,16 @@ const (
|
|||||||
// c: 当前玩家对象
|
// c: 当前玩家对象
|
||||||
// 返回: 分配结果和错误码
|
// 返回: 分配结果和错误码
|
||||||
func (h Controller) PetEVDiy(data *PetEV, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) PetEVDiy(data *PetEV, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
_, currentPet, found := c.FindPet(data.CacthTime)
|
slot, found := c.FindPetBagSlot(data.CacthTime)
|
||||||
if !found {
|
if !found {
|
||||||
return nil, errorcode.ErrorCodes.Err10401
|
return nil, errorcode.ErrorCodes.Err10401
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentPet := slot.PetInfoPtr()
|
||||||
|
if currentPet == nil {
|
||||||
|
return nil, errorcode.ErrorCodes.Err10401
|
||||||
|
}
|
||||||
|
|
||||||
var targetTotal uint32
|
var targetTotal uint32
|
||||||
var currentTotal uint32
|
var currentTotal uint32
|
||||||
for i, evValue := range data.EVs {
|
for i, evValue := range data.EVs {
|
||||||
|
|||||||
45
logic/controller/pet_ev_test.go
Normal file
45
logic/controller/pet_ev_test.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"blazing/logic/service/player"
|
||||||
|
playermodel "blazing/modules/player/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPetEVDiy_AppliesToBackupPet(t *testing.T) {
|
||||||
|
p := player.NewPlayer(nil)
|
||||||
|
p.Info = &playermodel.PlayerInfo{
|
||||||
|
EVPool: 20,
|
||||||
|
PetList: []playermodel.PetInfo{
|
||||||
|
{CatchTime: 1},
|
||||||
|
},
|
||||||
|
BackupPetList: []playermodel.PetInfo{
|
||||||
|
{
|
||||||
|
CatchTime: 2,
|
||||||
|
Level: 100,
|
||||||
|
Ev: [6]uint32{0, 4, 0, 0, 0, 0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
data := &PetEV{
|
||||||
|
CacthTime: 2,
|
||||||
|
EVs: [6]uint32{0, 8, 4, 0, 0, 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := (Controller{}).PetEVDiy(data, p)
|
||||||
|
if err != 0 {
|
||||||
|
t.Fatalf("PetEVDiy returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := p.Info.BackupPetList[0].Ev
|
||||||
|
want := [6]uint32{0, 8, 4, 0, 0, 0}
|
||||||
|
if got != want {
|
||||||
|
t.Fatalf("backup pet EV mismatch, got %v want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gotPool, wantPool := p.Info.EVPool, int64(12); gotPool != wantPool {
|
||||||
|
t.Fatalf("EVPool mismatch, got %d want %d", gotPool, wantPool)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,18 +4,20 @@ import (
|
|||||||
"blazing/common/socket/errorcode"
|
"blazing/common/socket/errorcode"
|
||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
"blazing/logic/service/pet"
|
"blazing/logic/service/pet"
|
||||||
"blazing/logic/service/player"
|
playersvc "blazing/logic/service/player"
|
||||||
"blazing/modules/player/model"
|
"blazing/modules/player/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetPetInfo 获取精灵信息
|
// GetPetInfo 获取精灵信息
|
||||||
func (h Controller) GetPetInfo(
|
func (h Controller) GetPetInfo(
|
||||||
data *GetPetInfoInboundInfo,
|
data *GetPetInfoInboundInfo,
|
||||||
player *player.Player) (result *model.PetInfo,
|
player *playersvc.Player) (result *model.PetInfo,
|
||||||
err errorcode.ErrorCode) {
|
err errorcode.ErrorCode) {
|
||||||
|
levelLimit := player.CurrentMapPetLevelLimit()
|
||||||
if slot, found := player.FindPetBagSlot(data.CatchTime); found {
|
if slot, found := player.FindPetBagSlot(data.CatchTime); found {
|
||||||
if petInfo := slot.PetInfoPtr(); petInfo != nil {
|
if petInfo := slot.PetInfoPtr(); petInfo != nil {
|
||||||
result = petInfo
|
petCopy := playersvc.ApplyPetLevelLimit(*petInfo, levelLimit)
|
||||||
|
result = &petCopy
|
||||||
return result, 0
|
return result, 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,16 +27,18 @@ func (h Controller) GetPetInfo(
|
|||||||
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
||||||
}
|
}
|
||||||
|
|
||||||
result = &ret.Data
|
petData := ret.Data
|
||||||
|
petData = playersvc.ApplyPetLevelLimit(petData, levelLimit)
|
||||||
|
result = &petData
|
||||||
return result, 0
|
return result, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserBagPetInfo 获取主背包和并列备用精灵列表
|
// GetUserBagPetInfo 获取主背包和并列备用精灵列表
|
||||||
func (h Controller) GetUserBagPetInfo(
|
func (h Controller) GetUserBagPetInfo(
|
||||||
data *GetUserBagPetInfoInboundEmpty,
|
data *GetUserBagPetInfoInboundEmpty,
|
||||||
player *player.Player) (result *pet.GetUserBagPetInfoOutboundInfo,
|
player *playersvc.Player) (result *pet.GetUserBagPetInfoOutboundInfo,
|
||||||
err errorcode.ErrorCode) {
|
err errorcode.ErrorCode) {
|
||||||
return player.GetUserBagPetInfo(), 0
|
return player.GetUserBagPetInfo(player.CurrentMapPetLevelLimit()), 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPetListInboundEmpty 定义请求或响应数据结构。
|
// GetPetListInboundEmpty 定义请求或响应数据结构。
|
||||||
@@ -45,7 +49,7 @@ type GetPetListInboundEmpty struct {
|
|||||||
// GetPetList 获取当前主背包列表
|
// GetPetList 获取当前主背包列表
|
||||||
func (h Controller) GetPetList(
|
func (h Controller) GetPetList(
|
||||||
data *GetPetListInboundEmpty,
|
data *GetPetListInboundEmpty,
|
||||||
player *player.Player) (result *pet.GetPetListOutboundInfo,
|
player *playersvc.Player) (result *pet.GetPetListOutboundInfo,
|
||||||
err errorcode.ErrorCode) {
|
err errorcode.ErrorCode) {
|
||||||
return buildPetListOutboundInfo(player.Info.PetList), 0
|
return buildPetListOutboundInfo(player.Info.PetList), 0
|
||||||
}
|
}
|
||||||
@@ -58,7 +62,7 @@ type GetPetListFreeInboundEmpty struct {
|
|||||||
// GetPetReleaseList 获取仓库可放生列表
|
// GetPetReleaseList 获取仓库可放生列表
|
||||||
func (h Controller) GetPetReleaseList(
|
func (h Controller) GetPetReleaseList(
|
||||||
data *GetPetListFreeInboundEmpty,
|
data *GetPetListFreeInboundEmpty,
|
||||||
player *player.Player) (result *pet.GetPetListOutboundInfo,
|
player *playersvc.Player) (result *pet.GetPetListOutboundInfo,
|
||||||
err errorcode.ErrorCode) {
|
err errorcode.ErrorCode) {
|
||||||
|
|
||||||
return buildPetListOutboundInfo(player.WarehousePetList()), 0
|
return buildPetListOutboundInfo(player.WarehousePetList()), 0
|
||||||
@@ -67,7 +71,7 @@ func (h Controller) GetPetReleaseList(
|
|||||||
// PlayerShowPet 精灵展示
|
// PlayerShowPet 精灵展示
|
||||||
func (h Controller) PlayerShowPet(
|
func (h Controller) PlayerShowPet(
|
||||||
data *PetShowInboundInfo,
|
data *PetShowInboundInfo,
|
||||||
player *player.Player) (result *pet.PetShowOutboundInfo, err errorcode.ErrorCode) {
|
player *playersvc.Player) (result *pet.PetShowOutboundInfo, err errorcode.ErrorCode) {
|
||||||
result = &pet.PetShowOutboundInfo{
|
result = &pet.PetShowOutboundInfo{
|
||||||
UserID: data.Head.UserID,
|
UserID: data.Head.UserID,
|
||||||
CatchTime: data.CatchTime,
|
CatchTime: data.CatchTime,
|
||||||
|
|||||||
@@ -32,17 +32,22 @@ func (p *baseplayer) GetInfo() *model.PlayerInfo {
|
|||||||
return p.Info
|
return p.Info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ApplyPetLevelLimit(pet model.PetInfo, limitlevel uint32) model.PetInfo {
|
||||||
|
originalHP := pet.Hp
|
||||||
|
if limitlevel > 0 {
|
||||||
|
pet.Level = utils.Min(pet.Level, limitlevel)
|
||||||
|
}
|
||||||
|
pet.CalculatePetPane(limitlevel)
|
||||||
|
pet.Hp = utils.Min(originalHP, pet.MaxHp)
|
||||||
|
return pet
|
||||||
|
}
|
||||||
|
|
||||||
func (p *baseplayer) GetPetInfo(limitlevel uint32) []model.PetInfo {
|
func (p *baseplayer) GetPetInfo(limitlevel uint32) []model.PetInfo {
|
||||||
|
|
||||||
var ret []model.PetInfo
|
ret := make([]model.PetInfo, 0, len(p.Info.PetList))
|
||||||
|
|
||||||
for _, pet := range p.Info.PetList {
|
for _, pet := range p.Info.PetList {
|
||||||
if limitlevel > 0 {
|
ret = append(ret, ApplyPetLevelLimit(pet, limitlevel))
|
||||||
pet.Level = utils.Min(pet.Level, limitlevel)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = append(ret, pet)
|
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,12 +106,20 @@ func validatePetBagOrder(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildLimitedPetList(petList []model.PetInfo, limitlevel uint32) []model.PetInfo {
|
||||||
|
result := make([]model.PetInfo, 0, len(petList))
|
||||||
|
for _, petInfo := range petList {
|
||||||
|
result = append(result, ApplyPetLevelLimit(petInfo, limitlevel))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// GetUserBagPetInfo 返回主背包和并列备用精灵列表。
|
// GetUserBagPetInfo 返回主背包和并列备用精灵列表。
|
||||||
func (p *Player) GetUserBagPetInfo() *pet.GetUserBagPetInfoOutboundInfo {
|
func (p *Player) GetUserBagPetInfo(limitlevel uint32) *pet.GetUserBagPetInfoOutboundInfo {
|
||||||
|
|
||||||
result := &pet.GetUserBagPetInfoOutboundInfo{
|
result := &pet.GetUserBagPetInfoOutboundInfo{
|
||||||
PetList: p.Info.PetList,
|
PetList: buildLimitedPetList(p.Info.PetList, limitlevel),
|
||||||
BackupPetList: p.Info.BackupPetList,
|
BackupPetList: buildLimitedPetList(p.Info.BackupPetList, limitlevel),
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -228,6 +228,17 @@ func (p *Player) GetSpace() *space.Space {
|
|||||||
return space.GetSpace(p.Info.MapID)
|
return space.GetSpace(p.Info.MapID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Player) CurrentMapPetLevelLimit() uint32 {
|
||||||
|
if p == nil {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
currentSpace := p.GetSpace()
|
||||||
|
if currentSpace != nil && currentSpace.IsLevelBreakMap {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
|
||||||
// CanFight 检查玩家是否可以进行战斗
|
// CanFight 检查玩家是否可以进行战斗
|
||||||
// 0无战斗,1PVP,2,BOOS,3PVE
|
// 0无战斗,1PVP,2,BOOS,3PVE
|
||||||
func (p *Player) CanFight() errorcode.ErrorCode {
|
func (p *Player) CanFight() errorcode.ErrorCode {
|
||||||
|
|||||||
@@ -42,10 +42,11 @@ type Space struct {
|
|||||||
WeatherType []uint32
|
WeatherType []uint32
|
||||||
TimeBoss info.S2C_2022
|
TimeBoss info.S2C_2022
|
||||||
|
|
||||||
IsTime bool
|
IsTime bool
|
||||||
DropItemIds []uint32
|
IsLevelBreakMap bool
|
||||||
PitS *csmap.CsMap[int, []model.MapPit]
|
DropItemIds []uint32
|
||||||
MapNodeS *csmap.CsMap[uint32, *model.MapNode]
|
PitS *csmap.CsMap[int, []model.MapPit]
|
||||||
|
MapNodeS *csmap.CsMap[uint32, *model.MapNode]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSpace() *Space {
|
func NewSpace() *Space {
|
||||||
@@ -185,6 +186,9 @@ func (ret *Space) init() {
|
|||||||
if r.IsTimeSpace != 0 {
|
if r.IsTimeSpace != 0 {
|
||||||
ret.IsTime = true
|
ret.IsTime = true
|
||||||
}
|
}
|
||||||
|
if r.IsLevelBreakMap != 0 {
|
||||||
|
ret.IsLevelBreakMap = true
|
||||||
|
}
|
||||||
ret.MapBossSInfo = info.MapModelBroadcastInfo{}
|
ret.MapBossSInfo = info.MapModelBroadcastInfo{}
|
||||||
ret.MapBossSInfo.INFO = make([]info.MapModelBroadcastEntry, 0)
|
ret.MapBossSInfo.INFO = make([]info.MapModelBroadcastEntry, 0)
|
||||||
|
|
||||||
|
|||||||
@@ -1,94 +1,97 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/common/rpc"
|
"blazing/common/rpc"
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/yudeguang/ratelimit"
|
"github.com/yudeguang/ratelimit"
|
||||||
|
|
||||||
i18n "blazing/modules/base/middleware"
|
i18n "blazing/modules/base/middleware"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/net/ghttp"
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
"github.com/gogf/gf/v2/os/gcmd"
|
"github.com/gogf/gf/v2/os/gcmd"
|
||||||
"github.com/gogf/gf/v2/os/gfile"
|
"github.com/gogf/gf/v2/os/gfile"
|
||||||
"github.com/xiaoqidun/qqwry"
|
"github.com/xiaoqidun/qqwry"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Main = gcmd.Command{
|
Main = gcmd.Command{
|
||||||
Name: "main",
|
Name: "main",
|
||||||
Usage: "main",
|
Usage: "main",
|
||||||
Brief: "start http server",
|
Brief: "start http server",
|
||||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||||||
|
|
||||||
r := parser.GetOpt("debug", false)
|
r := parser.GetOpt("debug", false)
|
||||||
if r.Bool() {
|
if r.Bool() {
|
||||||
g.DB().SetDebug(true)
|
g.DB().SetDebug(true)
|
||||||
// service.NewServerService().SetServerScreen(0, "sss")
|
// service.NewServerService().SetServerScreen(0, "sss")
|
||||||
cool.Config.ServerInfo.IsDebug = 1
|
cool.Config.ServerInfo.IsDebug = 1
|
||||||
}
|
}
|
||||||
if cool.IsRedisMode {
|
if err = cool.RunAutoMigrate(); err != nil {
|
||||||
go rpc.ListenFunc(ctx)
|
return err
|
||||||
}
|
}
|
||||||
// // 从文件加载IP数据库
|
if cool.IsRedisMode {
|
||||||
if err := qqwry.LoadFile("public/qqwry.ipdb"); err != nil {
|
go rpc.ListenFunc(ctx)
|
||||||
panic(err)
|
}
|
||||||
}
|
// // 从文件加载IP数据库
|
||||||
//go robot()
|
if err := qqwry.LoadFile("public/qqwry.ipdb"); err != nil {
|
||||||
//go reg()
|
panic(err)
|
||||||
go startrobot()
|
}
|
||||||
s := g.Server()
|
//go robot()
|
||||||
s.Use(Limiter, ghttp.MiddlewareHandlerResponse)
|
//go reg()
|
||||||
s.EnableAdmin()
|
go startrobot()
|
||||||
s.SetServerAgent(cool.Config.Name)
|
s := g.Server()
|
||||||
s.BindHookHandler("/*", ghttp.HookBeforeServe, beforeServeHook)
|
s.Use(Limiter, ghttp.MiddlewareHandlerResponse)
|
||||||
// runtime.SetMutexProfileFraction(1) // (非必需)开启对锁调用的跟踪
|
s.EnableAdmin()
|
||||||
// runtime.SetBlockProfileRate(1) // (非必需)开启对阻塞操作的跟踪
|
s.SetServerAgent(cool.Config.Name)
|
||||||
// s.EnablePProf()
|
s.BindHookHandler("/*", ghttp.HookBeforeServe, beforeServeHook)
|
||||||
// 如果存在 data/cool-admin-vue/dist 目录,则设置为主目录
|
// runtime.SetMutexProfileFraction(1) // (非必需)开启对锁调用的跟踪
|
||||||
if gfile.IsDir("public") {
|
// runtime.SetBlockProfileRate(1) // (非必需)开启对阻塞操作的跟踪
|
||||||
s.SetServerRoot("public")
|
// s.EnablePProf()
|
||||||
}
|
// 如果存在 data/cool-admin-vue/dist 目录,则设置为主目录
|
||||||
// i18n 信息
|
if gfile.IsDir("public") {
|
||||||
s.BindHandler("/i18n", i18n.I18nInfo)
|
s.SetServerRoot("public")
|
||||||
// g.Server().BindMiddleware("/*", MiddlewareCORS)
|
}
|
||||||
s.Run()
|
// i18n 信息
|
||||||
return nil
|
s.BindHandler("/i18n", i18n.I18nInfo)
|
||||||
},
|
// g.Server().BindMiddleware("/*", MiddlewareCORS)
|
||||||
}
|
s.Run()
|
||||||
)
|
return nil
|
||||||
|
},
|
||||||
func beforeServeHook(r *ghttp.Request) {
|
}
|
||||||
//glog.Debugf(r.GetCtx(), "beforeServeHook [is file:%v] URI:%s", r.IsFileRequest(), r.RequestURI)
|
)
|
||||||
r.Response.CORSDefault()
|
|
||||||
}
|
func beforeServeHook(r *ghttp.Request) {
|
||||||
|
//glog.Debugf(r.GetCtx(), "beforeServeHook [is file:%v] URI:%s", r.IsFileRequest(), r.RequestURI)
|
||||||
// var limiter = rate.NewLimiter(rate.Limit(150), 50)
|
r.Response.CORSDefault()
|
||||||
var limiter *ratelimit.Rule = ratelimit.NewRule()
|
}
|
||||||
|
|
||||||
// 简单规则案例
|
// var limiter = rate.NewLimiter(rate.Limit(150), 50)
|
||||||
func init() {
|
var limiter *ratelimit.Rule = ratelimit.NewRule()
|
||||||
|
|
||||||
//步骤二:增加一条或者多条规则组成复合规则,此复合规则必须至少包含一条规则
|
// 简单规则案例
|
||||||
limiter.AddRule(time.Second*1, 20)
|
func init() {
|
||||||
//步骤三:调用函数判断某用户是否允许访问 allow:= r.AllowVisit(user)
|
|
||||||
|
//步骤二:增加一条或者多条规则组成复合规则,此复合规则必须至少包含一条规则
|
||||||
}
|
limiter.AddRule(time.Second*1, 20)
|
||||||
|
//步骤三:调用函数判断某用户是否允许访问 allow:= r.AllowVisit(user)
|
||||||
// Limiter is a middleware that implements rate limiting for all HTTP requests.
|
|
||||||
// It returns HTTP 429 (Too Many Requests) when the rate limit is exceeded.
|
}
|
||||||
func Limiter(r *ghttp.Request) {
|
|
||||||
// 3. 为任意键 "some-key" 获取一个速率限制器
|
// Limiter is a middleware that implements rate limiting for all HTTP requests.
|
||||||
// - rate.Limit(2): 表示速率为 "每秒2个请求"
|
// It returns HTTP 429 (Too Many Requests) when the rate limit is exceeded.
|
||||||
// - 2: 表示桶的容量 (Burst),允许瞬时处理2个请求
|
func Limiter(r *ghttp.Request) {
|
||||||
ip := r.GetClientIp()
|
// 3. 为任意键 "some-key" 获取一个速率限制器
|
||||||
if !limiter.AllowVisitByIP4(ip) {
|
// - rate.Limit(2): 表示速率为 "每秒2个请求"
|
||||||
r.Response.WriteStatusExit(429) // Return 429 Too Many Requests
|
// - 2: 表示桶的容量 (Burst),允许瞬时处理2个请求
|
||||||
|
ip := r.GetClientIp()
|
||||||
r.ExitAll()
|
if !limiter.AllowVisitByIP4(ip) {
|
||||||
}
|
r.Response.WriteStatusExit(429) // Return 429 Too Many Requests
|
||||||
r.Middleware.Next()
|
|
||||||
}
|
r.ExitAll()
|
||||||
|
}
|
||||||
|
r.Middleware.Next()
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ type MapConfig struct {
|
|||||||
WeatherType []uint32 `gorm:"type:int[];comment:'天气类型( 0 晴天,1-雨天,2-雪天)'" json:"weather_type"`
|
WeatherType []uint32 `gorm:"type:int[];comment:'天气类型( 0 晴天,1-雨天,2-雪天)'" json:"weather_type"`
|
||||||
//是否超时空
|
//是否超时空
|
||||||
IsTimeSpace int `gorm:"type:int;default:0;comment:'是否超时空'" json:"is_time_space"`
|
IsTimeSpace int `gorm:"type:int;default:0;comment:'是否超时空'" json:"is_time_space"`
|
||||||
|
// 是否等级突破地图
|
||||||
|
IsLevelBreakMap int `gorm:"type:int;default:0;comment:'是否等级突破地图'" json:"is_level_break_map"`
|
||||||
|
|
||||||
// 掉落物配置
|
// 掉落物配置
|
||||||
DropItemIds []uint32 `gorm:"type:int[];comment:'掉落物IDs" json:"drop_item_ids"`
|
DropItemIds []uint32 `gorm:"type:int[];comment:'掉落物IDs" json:"drop_item_ids"`
|
||||||
|
|||||||
Reference in New Issue
Block a user