From 79213c67d61bc73c243b589bb675257cf83a7d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <1@72wo.cn> Date: Mon, 13 Oct 2025 18:51:41 +0800 Subject: [PATCH] =?UTF-8?q?```=20fix(socket):=20=E4=BF=AE=E5=A4=8DTCP?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=A4=84=E7=90=86=E4=B8=AD=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=8F=96=E5=8F=8D=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复了`handleTcp`函数中对`s.discorse`的判断条件错误,导致CORS配置未正确应用的问题。 feat(player): 增加地图切换标记支持 在`Player`结构体中新增`Changemap`字段,用于标识玩家是否切换过地图,并在相关业务逻辑中进行设置和判断。 feat(pet): 重构精灵生成与经验处理逻辑 将`GenPetInfo`方法从model包迁移至player包,增加个体值、性格、特性等随机生成逻辑,优化技能学习处理方式。 refactor(service): 优化定时任务与连接管理 使用`cool.Cron`替代原生ticker实现刷怪定时任务,优化连接获取方式,确保并发安全。 refactor(model): 移除冗余代码并优化结构 从`pet.go`中移除已迁移至`player`包的函数定义,精简模型结构,提升模块清晰度。 refactor(config): 更新部门及字典名称配置 将`base_sys_department.json`和 --- common/socket/ServerEvent.go | 4 +- common/socket/ServerOption.go | 4 +- logic/controller/fight.go | 4 +- logic/controller/login.go | 1 + logic/controller/map.go | 3 +- logic/controller/pet.go | 2 +- logic/service/fight/playeraction.go | 8 +- logic/service/player/new.go | 27 +--- logic/service/player/pet.go | 117 ++++++++++++++++- logic/service/player/player.go | 34 +++-- logic/service/player/server.go | 7 +- logic/service/player/wscodec.go | 7 ++ .../initjson/base_sys_department.json | 2 +- modules/base/service/base_sys_user.go | 24 +++- .../blazing/controller/admin/monster_get.go | 50 ++++++++ modules/blazing/model/pet.go | 118 ------------------ modules/blazing/service/pet.go | 21 ++++ modules/dict/resource/initjson/dict_info.json | 2 +- public/config/210.xml | 1 - public/config/221.xml | 1 + public/config/226.xml | 2 +- public/config/227.xml | 2 +- public/config/43.xml | 2 +- 23 files changed, 268 insertions(+), 175 deletions(-) create mode 100644 modules/blazing/controller/admin/monster_get.go delete mode 120000 public/config/210.xml create mode 120000 public/config/221.xml diff --git a/common/socket/ServerEvent.go b/common/socket/ServerEvent.go index 401769290..e50210c82 100644 --- a/common/socket/ServerEvent.go +++ b/common/socket/ServerEvent.go @@ -150,7 +150,7 @@ func (s *Server) OnTraffic(c gnet.Conn) (action gnet.Action) { func (s *Server) handleTcp(conn gnet.Conn) (action gnet.Action) { for { - if !s.discorse { + if s.discorse { handle(conn) } data, err := s.codec.Decode(conn) @@ -181,7 +181,7 @@ func (s *Server) handleTcp(conn gnet.Conn) (action gnet.Action) { } func (s *Server) parser(c gnet.Conn, line []byte) { - + c.Context().(*player.ClientData).IsCrossDomain = true //todo 这里待实现注入player实体 s.handler.Handle(c, line) } diff --git a/common/socket/ServerOption.go b/common/socket/ServerOption.go index 01a5bd148..5b03b136a 100644 --- a/common/socket/ServerOption.go +++ b/common/socket/ServerOption.go @@ -37,7 +37,7 @@ func NewServer(options ...Option) *Server { workerPool: goroutine.Default(), bufferSize: 4096, //默认缓冲区大小 multicore: true, - discorse: true, + //discorse: true, } for _, option := range options { option(server) @@ -52,7 +52,7 @@ func WithSocketCodec(codec codec.SocketCodec) Option { } func WithCORS() Option { return func(u *Server) { - u.discorse = false + u.discorse = true } } func WithSocketHandler(handler Handler) Option { diff --git a/logic/controller/fight.go b/logic/controller/fight.go index 343c16ed5..e99bca942 100644 --- a/logic/controller/fight.go +++ b/logic/controller/fight.go @@ -27,7 +27,7 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla petid = 7 } - mo = model.GenPetInfo( + mo = c.GenPetInfo( int(petid), 24, //24个体 -1, 0, //野怪没特性 @@ -55,7 +55,7 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn return nil, errorcode.ErrorCodes.ErrPokemonNotExists } - mo := model.GenPetInfo( + mo := c.GenPetInfo( int(refpet.Id), -1, -1, 0, //野怪没特性 diff --git a/logic/controller/login.go b/logic/controller/login.go index 2e0cfbd6e..88e950c00 100644 --- a/logic/controller/login.go +++ b/logic/controller/login.go @@ -39,6 +39,7 @@ func (h *Controller) Login(data *user.MAIN_LOGIN_IN, c *player.Conn) (result *us t.Info = t.Service.Person(data.Head.UserID) t.Info.UserID = data.Head.UserID t.Onlinetime = uint32(time.Now().Unix()) //保存时间戳 + t.Changemap = true share.ShareManager.SetUserOnline(data.Head.UserID, h.Port) //设置用户登录服务器 diff --git a/logic/controller/map.go b/logic/controller/map.go index 4b1b57d03..668b65999 100644 --- a/logic/controller/map.go +++ b/logic/controller/map.go @@ -36,7 +36,8 @@ func (h Controller) MapHot(data *maphot.InInfo, c *player.Player) (result *mapho } func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *player.Player) (result *space.LeaveMapOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 //result = &maps.LeaveMapOutboundInfo{UserID: c.GetUserID()} - c.Canmon = false //可以刷怪 + c.Canmon = false + c.Changemap = true //可以刷怪 data.Broadcast(c.Info.MapID, space.LeaveMapOutboundInfo{UserID: c.Info.UserID}) //同步广播 space.GetSpace(c.Info.MapID).User.Remove(c.Info.UserID) // 如果有正在运行的刷怪协程,发送停止信号 diff --git a/logic/controller/pet.go b/logic/controller/pet.go index 5e6a12fc3..bc243f471 100644 --- a/logic/controller/pet.go +++ b/logic/controller/pet.go @@ -48,7 +48,7 @@ func (h *Controller) GetPetList( result.ShortInfoList = make([]pet.PetShortInfo, len(tt)) for i, v := range tt { - copier.Copy(&result.ShortInfoList[i], &v) + copier.Copy(&result.ShortInfoList[i], &v.Data) } return result, 0 diff --git a/logic/service/fight/playeraction.go b/logic/service/fight/playeraction.go index 7e910e831..5b149067c 100644 --- a/logic/service/fight/playeraction.go +++ b/logic/service/fight/playeraction.go @@ -7,6 +7,7 @@ import ( "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" "blazing/logic/service/player" + "fmt" "math" "github.com/gogf/gf/v2/util/gconv" @@ -127,17 +128,18 @@ func (f *FightC) ReadyFight(c common.PlayerI) { } switch f.Info.Status { - case 1: //pvp + case info.BattleStatus.FIGHT_WITH_PLAYER: //pvp f.GetInputByPlayer(c, false).Finished = true if f.GetInputByPlayer(c, true).Finished { rrsult() } - case 2: // 6v6 + case info.BattleStatus.FIGHT_WITH_BOSS: // 6v6 rrsult() - case 3: // 野怪战斗 + case info.BattleStatus.FIGHT_WITH_NPC: // 野怪战斗 //判断捕捉率大于0 + fmt.Println("CatchRate", xmlres.PetMAP[int(f.Info.OpponentPetList[0].ID)].CatchRate) if gconv.Int(xmlres.PetMAP[int(f.Info.OpponentPetList[0].ID)].CatchRate) > 0 { rett.Info2.Catchable = 1 t, _ := f.Opp.Player.(*player.AI_player) diff --git a/logic/service/player/new.go b/logic/service/player/new.go index dbc37be90..aa809384f 100644 --- a/logic/service/player/new.go +++ b/logic/service/player/new.go @@ -1,6 +1,7 @@ package player import ( + "blazing/cool" "blazing/modules/blazing/model" "time" ) @@ -14,28 +15,12 @@ func NewPlayer(opts ...PlayerOption) *Player { } p.monsters = generateThreeUniqueNumbers() - p.StopChan = make(chan struct{}) - - // 启动刷怪协程 - go func(stopChan chan struct{}) { - - ticker := time.NewTicker(10 * time.Second) - defer ticker.Stop() - - for { - select { - case <-stopChan: - // 收到停止信号,退出协程 - return - case <-ticker.C: - // 刷新当前地图的怪物 - if p.Canmon && p.FightC == nil { //已经进入地图或者没在战斗中,就可以刷新怪 - p.SpawnMonsters() - } - - } + p.StopChan = cool.Cron.ScheduleFunc(10*time.Second, func() { + if p.Canmon && p.FightC == nil { //已经进入地图或者没在战斗中,就可以刷新怪 + p.SpawnMonsters() } - }(p.StopChan) + }) + for _, opt := range opts { opt(p) } diff --git a/logic/service/player/pet.go b/logic/service/player/pet.go index 651778f99..a76cc9328 100644 --- a/logic/service/player/pet.go +++ b/logic/service/player/pet.go @@ -3,10 +3,13 @@ package player import ( "blazing/common/data/xmlres" "blazing/logic/service/fight/info" + "math/rand" + "time" "blazing/modules/blazing/model" "math" + "github.com/gogf/gf/v2/util/gconv" "github.com/jinzhu/copier" ) @@ -85,7 +88,7 @@ func (p *Player) AddPetExp(petinfo *model.PetInfo, addExp uint32) { //player.SendMessage(generatePetUpdateInfo(petEntity, originalExp+addExp-exp, addition)) // 处理技能学习 - canLearnSkillList := model.LastFourElements(petinfo.GetLevelRangeCanLearningSkills(originalLevel, petinfo.Level)) //获取最后四个技能,如果不足,那就取全部技能 + canLearnSkillList := LastFourElements(petinfo.GetLevelRangeCanLearningSkills(originalLevel, petinfo.Level)) //获取最后四个技能,如果不足,那就取全部技能 for i := 0; i < 4; i++ { @@ -117,3 +120,115 @@ func (p *Player) AddPetExp(petinfo *model.PetInfo, addExp uint32) { // return exp } + +func LastFourElements[T any](s []T) []T { + n := len(s) + if n <= 4 { + // 切片长度小于等于4时,返回整个切片 + return s + } + // 切片长度大于4时,返回最后4个元素(从n-4索引到末尾) + return s[n-4:] +} + +// -1是随机 +// * @param petTypeId 精灵类型ID +// * @param individualValue 个体值 +// * @param natureId 性格ID +// * @param abilityTypeEnum 特性类型 +// * @param isShiny 是否为闪光 +// * @param level 等级 +// * @return 生成的精灵实体 +func (player *Player) GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level int) *model.PetInfo { + // 设置随机数种子,确保每次运行生成不同的随机数序列 + rand.Seed(time.Now().UnixNano()) + + p := &model.PetInfo{ID: uint32(id), + + EffectInfo: make([]model.PetEffectInfo, 0), + CatchTime: uint32(time.Now().Unix()), + Level: uint32(level)} //等级 + + if shinyid != -1 { + p.Shiny = uint32(shinyid) + } + if natureId != -1 { + p.Nature = uint32(natureId) + } else { + p.Nature = uint32(rand.Intn(25)) + } + if dv != -1 { + p.Dv = uint32(dv) + } else { + p.Dv = uint32(CalculateIndividualValue(rand.New(rand.NewSource(time.Now().UnixNano())))) + } + + if abilityTypeEnum != -1 { + if abilityTypeEnum != 0 { + v := xmlres.PlayerEffectMAP[int(abilityTypeEnum)] + p.EffectInfo = append(p.EffectInfo, model.PetEffectInfo{ + Idx: uint16(gconv.Int16(v.Idx)), + Status: 1, + EID: uint16(gconv.Int16(v.Eid)), + Args: v.ArgsS, + }) + } + + } else { + for i, v := range xmlres.PlayerEffectMAP { + if rand.Intn(len(xmlres.PlayerEffectMAP)) == i { + p.EffectInfo = append(p.EffectInfo, model.PetEffectInfo{ + Idx: uint16(gconv.Int16(v.Idx)), + Status: 1, + EID: uint16(gconv.Int16(v.Eid)), + Args: v.ArgsS, + }) + } + + } + + } + + tttt := LastFourElements(p.GetLevelRangeCanLearningSkills(0, p.Level)) //获取最后四个技能,如果不足,那就取全部技能 + for i := 0; i < len(tttt); i++ { + p.SkillList[i].ID = tttt[i] + p.SkillList[i].PP = uint32(xmlres.SkillMap[int(tttt[i])].MaxPP) + + } + p.SkillListLen = uint32(len(tttt)) + p.CalculatePetPane() + p.Hp = p.MaxHp + player.AddPetExp(p, 0) + return p +} + +// 除数数组(放大100倍) +// 数组按递增顺序排列,用于判断个体值等级 +var divisors = []int{ + 600, 1200, 1900, 2700, 3600, 4600, 5700, 6900, 8200, 9600, + 11100, 12700, 14400, 16200, 18100, 20100, 22100, 24000, + 25800, 27500, 29100, 30600, 32000, 33300, 34500, 35600, + 36600, 37500, 38300, 39000, 39600, +} + +// CalculateIndividual 根据给定的a值计算个体值 +// 返回值表示a大于等于多少个除数(范围:0-31) +func CalculateIndividual(a int) int { + individual := 0 + for _, divisor := range divisors { + if a >= divisor { + individual++ + } else { + break // 数组是递增的,可提前跳出循环 + } + } + return individual +} + +// CalculateIndividualValue 计算个体值(0-31) +// 接收外部随机数生成器,便于控制随机性和复用 +func CalculateIndividualValue(random *rand.Rand) int { + // 生成0-40000的随机数,作为个体值计算的输入 + a := random.Intn(40001) + return CalculateIndividual(a) +} diff --git a/logic/service/player/player.go b/logic/service/player/player.go index d69ea12e5..c32196bba 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -19,6 +19,7 @@ import ( "sync" "time" + "github.com/antlabs/timer" "github.com/gobwas/ws" "github.com/gobwas/ws/wsutil" "github.com/gogf/gf/v2/frame/g" @@ -59,17 +60,17 @@ func NewClientData() *ClientData { var Mainplayer = &utils.SyncMap[uint32, *Player]{} //玩家数据 func (c *Conn) SendPack(bytes []byte) error { - if t, ok := c.MainConn.Context().(*ClientData); ok { + if t, ok := c.GetConn().Context().(*ClientData); ok { if t.Wsmsg.Upgraded { // This is the echo server err := wsutil.WriteServerMessage(c.MainConn, ws.OpBinary, bytes) if err != nil { - logging.Infof("conn[%v] [err=%v]", c.MainConn.RemoteAddr().String(), err.Error()) + logging.Infof("conn[%v] [err=%v]", c.GetConn().RemoteAddr().String(), err.Error()) return err } } else { - _, err := c.MainConn.Write(bytes) + _, err := c.GetConn().Write(bytes) if err != nil { glog.Debug(context.Background(), err) @@ -98,17 +99,18 @@ type Player struct { loginChan chan struct{} // 登录完成通知通道 - StopChan chan struct{} //停止刷怪协程 + StopChan timer.TimeNoder context.Context PVPinfo *info.PVPinfo //当前邀请的玩家ID Onlinetime uint32 //当前登录时间 - OgreInfo *OgreInfo + OgreInfo OgreInfo Service *blservice.UserService HavePVPinfo []*Player monsters [3]int Canmon bool //可以刷怪 + Changemap bool //是否切换过地图 } // PlayerOption 定义配置 Player 的函数类型 @@ -131,11 +133,9 @@ func (p *Player) SpawnMonsters() { // 创建数据包 tt := NewTomeeHeader(2004, p.Info.UserID) - p.monsters, _, _ = replaceOneNumber(p.monsters) - p.genMonster(p.Info.MapID) //生成野怪 - p.SendPack(tt.Pack(p.OgreInfo)) + p.SendPack(tt.Pack(&p.OgreInfo)) } @@ -149,6 +149,8 @@ func RandomStringFromSlice(s []string) string { // 应该根据怪物信息决定后端生成 func (p *Player) genMonster(mapid uint32) { + var oldnum, newNum int + p.monsters, oldnum, newNum = replaceOneNumber(p.monsters) // 设置怪物信息 t1 := OgreInfo{} mapss, ok := xmlres.MonsterMap[gconv.Int(mapid)] @@ -170,13 +172,18 @@ func (p *Player) genMonster(mapid uint32) { } - t2 := OgreInfo{} - for i := 0; i < 3; i++ { + if p.Changemap { + p.Changemap = false + p.OgreInfo = OgreInfo{} //切地图清空 + for i := 0; i < 3; i++ { - t2.Data[p.monsters[i]] = t1.Data[p.monsters[i]] + p.OgreInfo.Data[p.monsters[i]] = t1.Data[p.monsters[i]] + } + } else { + p.OgreInfo.Data[oldnum] = OgrePetInfo{} + p.OgreInfo.Data[newNum] = t1.Data[newNum] } - p.OgreInfo = &t2 } // 生成0-9之间三个不重复的随机数 进地图5s @@ -294,7 +301,8 @@ func (p *Player) Save() { p.Service.Save(p.Info) LeaveMap(p) - close(p.StopChan) //停止刷怪 + p.StopChan.Stop() //停止刷怪 + p.IsLogin = false Mainplayer.Delete(p.Info.UserID) diff --git a/logic/service/player/server.go b/logic/service/player/server.go index 097115cc0..4c3502e51 100644 --- a/logic/service/player/server.go +++ b/logic/service/player/server.go @@ -3,11 +3,10 @@ package player import "blazing/common/socket/errorcode" func GetPlayer(c *Conn, userid uint32) *Player { //TODO 这里待优化,可能存在内存泄漏问题 - c.Mu.Lock() - defer c.Mu.Unlock() + //检查player初始化,是否为conn初始后取map,防止二次连接后存在两个player - clientdata := c.MainConn.Context().(*ClientData) + clientdata := c.GetConn().Context().(*ClientData) if clientdata.Player == nil { clientdata.Player = NewPlayer( @@ -38,7 +37,7 @@ func KickPlayer(userid uint32) { //踢出玩家 //实际上这里有个问题,会造成重复保存问题 player1.SendPack(head.Pack(nil)) - player1.MainConn.MainConn.Close() + player1.MainConn.GetConn().Close() // clientdata.Player = player } diff --git a/logic/service/player/wscodec.go b/logic/service/player/wscodec.go index 9d52e4afb..44d01123e 100644 --- a/logic/service/player/wscodec.go +++ b/logic/service/player/wscodec.go @@ -17,6 +17,13 @@ type Conn struct { Mu sync.Mutex } +func (c *Conn) GetConn() gnet.Conn { + c.Mu.Lock() + defer c.Mu.Unlock() + return c.MainConn + +} + func NewConn(c gnet.Conn) *Conn { return &Conn{MainConn: c} } diff --git a/modules/base/resource/initjson/base_sys_department.json b/modules/base/resource/initjson/base_sys_department.json index 0b5eed47b..3cb9ad95e 100644 --- a/modules/base/resource/initjson/base_sys_department.json +++ b/modules/base/resource/initjson/base_sys_department.json @@ -4,7 +4,7 @@ "createTime": "2025-07-05 11:18:43.560949 +00:00", "updateTime": "2025-07-05 11:18:43.560949 +00:00", "deleted_at": null, - "name": "COOL", + "name": "SUN", "parentId": null, "orderNum": 0 }, diff --git a/modules/base/service/base_sys_user.go b/modules/base/service/base_sys_user.go index 8db758ec5..578b92ab2 100644 --- a/modules/base/service/base_sys_user.go +++ b/modules/base/service/base_sys_user.go @@ -80,6 +80,7 @@ func (s *BaseSysUserService) ServiceAdd(ctx context.Context, req *cool.AddReq) ( r = g.RequestFromCtx(ctx) reqmap = r.GetMap() ) + // 如果reqmap["password"]不为空,则对密码进行md5加密 if !r.Get("password").IsNil() { reqmap["password"] = gmd5.MustEncryptString(r.Get("password").String()) @@ -89,6 +90,27 @@ func (s *BaseSysUserService) ServiceAdd(ctx context.Context, req *cool.AddReq) ( return } data = g.Map{"id": lastInsertId} + err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { + + if !r.Get("roleIdList").IsNil() { + inRoleIdSet := gset.NewFrom(r.Get("roleIdList").Ints()) + roleArray := garray.NewArray() + inRoleIdSet.Iterator(func(v interface{}) bool { + roleArray.PushRight(g.Map{ + "userId": gconv.Uint(lastInsertId), + "roleId": gconv.Uint(v), + }) + return true + }) + + _, err = cool.DBM(model.NewBaseSysUserRole()).Fields("userId,roleId").Insert(roleArray) + if err != nil { + return err + } + } + + return + }) return } @@ -252,7 +274,7 @@ func NewBaseSysUserService() *BaseSysUserService { Extend: func(ctx g.Ctx, m *gdb.Model) *gdb.Model { return m.Group(`base_sys_user.id`) }, - KeyWordField: []string{"name", "username", "nickName"}, + KeyWordField: []string{"username", "email"}, }, }, } diff --git a/modules/blazing/controller/admin/monster_get.go b/modules/blazing/controller/admin/monster_get.go new file mode 100644 index 000000000..bc9f6b927 --- /dev/null +++ b/modules/blazing/controller/admin/monster_get.go @@ -0,0 +1,50 @@ +package admin + +import ( + "blazing/cool" + "blazing/modules/blazing/model" + "blazing/modules/blazing/service" + "context" + "fmt" + + "github.com/gogf/gf/v2/frame/g" +) + +type PetBagController struct { + *cool.Controller +} +type PetGetReq struct { + g.Meta `path:"/genpet" method:"POST"` + // 新增:精灵相关参数(完全对齐自定义表单配置) + PetTypeId int `json:"petTypeId" v:"required|min:1" comment:"精灵类型ID,必填,正整数(最小1,无0或负数类型),对应GenPetInfo的id参数"` + IndividualValue int `json:"individualValue" v:"required|between:-1,31" comment:"精灵个体值,必填,范围-1~31(-1表示随机生成满个体,0~31为固定值,决定基础属性上限)"` + NatureId int `json:"natureId" v:"required|between:-1,24" comment:"精灵性格ID,必填,范围-1~24(-1表示随机,0~24对应25种固定性格,影响属性加成)"` + AbilityTypeEnum int `json:"abilityTypeEnum" v:"required|min:-1" comment:"精灵特性类型ID,必填,最小值-1(-1表示随机选择1个特性,0及以上为固定特性ID,需与PlayerEffectMAP匹配)"` + IsShiny int `json:"isShiny" v:"min:-1" comment:"精灵异色(闪光)ID,必填,最小值-1(-1表示随机,0及以上为固定异色状态,稀有精灵特殊外观/属性),原表单hidden但需保留必填逻辑"` + Level int `json:"level" v:"required|between:1,100" comment:"精灵等级,必填,范围1~100(常规游戏等级上限,影响精灵当前属性强度)"` +} + +func init() { + var task_info_controller = &PetBagController{ + &cool.Controller{ + Prefix: "/admin/monster/bag", + Api: []string{"Delete", "Update", "Info", "List", "Page"}, + Service: service.NewPetService(), + }, + } + // 注册路由 + cool.RegisterController(task_info_controller) +} +func (c *PetBagController) GetSession(ctx context.Context, req *PetGetReq) (res *cool.BaseRes, err error) { + + fmt.Println(req) + var ( + admin = cool.GetAdmin(ctx) + //r = g.RequestFromCtx(ctx) + ) + t := model.GenPetInfo( + req.PetTypeId, req.IndividualValue, req.NatureId, req.AbilityTypeEnum, req.IsShiny, req.Level) + service.NewUserService(uint32(admin.UserId)).PetAdd(*t) + return + +} diff --git a/modules/blazing/model/pet.go b/modules/blazing/model/pet.go index a5e933e6b..88c88d840 100644 --- a/modules/blazing/model/pet.go +++ b/modules/blazing/model/pet.go @@ -1,46 +1,9 @@ package model import ( - "blazing/common/data/xmlres" "blazing/cool" - "math/rand" - - "time" - - "github.com/gogf/gf/v2/util/gconv" ) -// 除数数组(放大100倍) -// 数组按递增顺序排列,用于判断个体值等级 -var divisors = []int{ - 600, 1200, 1900, 2700, 3600, 4600, 5700, 6900, 8200, 9600, - 11100, 12700, 14400, 16200, 18100, 20100, 22100, 24000, - 25800, 27500, 29100, 30600, 32000, 33300, 34500, 35600, - 36600, 37500, 38300, 39000, 39600, -} - -// CalculateIndividual 根据给定的a值计算个体值 -// 返回值表示a大于等于多少个除数(范围:0-31) -func CalculateIndividual(a int) int { - individual := 0 - for _, divisor := range divisors { - if a >= divisor { - individual++ - } else { - break // 数组是递增的,可提前跳出循环 - } - } - return individual -} - -// CalculateIndividualValue 计算个体值(0-31) -// 接收外部随机数生成器,便于控制随机性和复用 -func CalculateIndividualValue(random *rand.Rand) int { - // 生成0-40000的随机数,作为个体值计算的输入 - a := random.Intn(40001) - return CalculateIndividual(a) -} - const TableNamePet = "pet" // Pet mapped from table @@ -65,87 +28,6 @@ type PetS struct { Data []PetInfo `orm:"data" dc:"资源规格"` } -func LastFourElements[T any](s []T) []T { - n := len(s) - if n <= 4 { - // 切片长度小于等于4时,返回整个切片 - return s - } - // 切片长度大于4时,返回最后4个元素(从n-4索引到末尾) - return s[n-4:] -} - -// -1是随机 -// * @param petTypeId 精灵类型ID -// * @param individualValue 个体值 -// * @param natureId 性格ID -// * @param abilityTypeEnum 特性类型 -// * @param isShiny 是否为闪光 -// * @param level 等级 -// * @return 生成的精灵实体 -func GenPetInfo(id int, dv, natureId, abilityTypeEnum, shinyid, level int) *PetInfo { - // 设置随机数种子,确保每次运行生成不同的随机数序列 - rand.Seed(time.Now().UnixNano()) - - p := &PetInfo{ID: uint32(id), - - EffectInfo: make([]PetEffectInfo, 0), - CatchTime: uint32(time.Now().Unix()), - Level: uint32(level)} //等级 - - if shinyid != -1 { - p.Shiny = uint32(shinyid) - } - if natureId != -1 { - p.Nature = uint32(natureId) - } else { - p.Nature = uint32(rand.Intn(25)) - } - if dv != -1 { - p.Dv = uint32(dv) - } else { - p.Dv = uint32(CalculateIndividualValue(rand.New(rand.NewSource(time.Now().UnixNano())))) - } - - if abilityTypeEnum != -1 { - if abilityTypeEnum != 0 { - v := xmlres.PlayerEffectMAP[int(abilityTypeEnum)] - p.EffectInfo = append(p.EffectInfo, PetEffectInfo{ - Idx: uint16(gconv.Int16(v.Idx)), - Status: 1, - EID: uint16(gconv.Int16(v.Eid)), - Args: v.ArgsS, - }) - } - - } else { - for i, v := range xmlres.PlayerEffectMAP { - if rand.Intn(len(xmlres.PlayerEffectMAP)) == i { - p.EffectInfo = append(p.EffectInfo, PetEffectInfo{ - Idx: uint16(gconv.Int16(v.Idx)), - Status: 1, - EID: uint16(gconv.Int16(v.Eid)), - Args: v.ArgsS, - }) - } - - } - - } - - tttt := LastFourElements(p.GetLevelRangeCanLearningSkills(0, p.Level)) //获取最后四个技能,如果不足,那就取全部技能 - for i := 0; i < len(tttt); i++ { - p.SkillList[i].ID = tttt[i] - p.SkillList[i].PP = uint32(xmlres.SkillMap[int(tttt[i])].MaxPP) - - } - p.SkillListLen = uint32(len(tttt)) - p.CalculatePetPane() - p.Hp = p.MaxHp - - return p -} - // PetInfo 精灵信息结构(合并后的优化版本) type PetInfo struct { diff --git a/modules/blazing/service/pet.go b/modules/blazing/service/pet.go index 3eb250029..950a55622 100644 --- a/modules/blazing/service/pet.go +++ b/modules/blazing/service/pet.go @@ -3,6 +3,7 @@ package service import ( "blazing/cool" "blazing/modules/blazing/model" + "context" ) // 获取精灵信息 0是仓库,1是背包,2是放生 @@ -43,3 +44,23 @@ func (s *UserService) PetAdd(y model.PetInfo) { m1.Insert(player) } + +func NewPetService() *MonsterService { + return &MonsterService{ + &cool.Service{ + Model: model.NewPet(), + PageQueryOp: &cool.QueryOp{ + Where: func(ctx context.Context) [][]interface{} { + var ( + admin = cool.GetAdmin(ctx) + userId = admin.UserId + ) + return [][]interface{}{ + {"player_id", userId, true}, + {"in_bag", 0, true}, + } + }, + }, + }, + } +} diff --git a/modules/dict/resource/initjson/dict_info.json b/modules/dict/resource/initjson/dict_info.json index 5cf31ac91..b00e1723b 100644 --- a/modules/dict/resource/initjson/dict_info.json +++ b/modules/dict/resource/initjson/dict_info.json @@ -44,7 +44,7 @@ "createTime": "2022-07-06 14:22:18.309000", "updateTime": "2022-07-06 14:22:18.309000", "typeId": 2, - "name": "COOL", + "name": "SUN", "orderNum": 1, "remark": null, "parentId": null diff --git a/public/config/210.xml b/public/config/210.xml deleted file mode 120000 index ad83450da..000000000 --- a/public/config/210.xml +++ /dev/null @@ -1 +0,0 @@ -E:/newcode/blazing/public/assets/210.xml \ No newline at end of file diff --git a/public/config/221.xml b/public/config/221.xml new file mode 120000 index 000000000..f6ab9b54f --- /dev/null +++ b/public/config/221.xml @@ -0,0 +1 @@ +E:/newcode/sun/public/assets/221.xml \ No newline at end of file diff --git a/public/config/226.xml b/public/config/226.xml index ecc5b96aa..0009fc9a4 120000 --- a/public/config/226.xml +++ b/public/config/226.xml @@ -1 +1 @@ -E:/newcode/blazing/public/assets/226.xml \ No newline at end of file +E:/newcode/sun/public/assets/226.xml \ No newline at end of file diff --git a/public/config/227.xml b/public/config/227.xml index 6332090b8..9f828e663 120000 --- a/public/config/227.xml +++ b/public/config/227.xml @@ -1 +1 @@ -E:/newcode/blazing/public/assets/227.xml \ No newline at end of file +E:/newcode/sun/public/assets/227.xml \ No newline at end of file diff --git a/public/config/43.xml b/public/config/43.xml index d4d68bc97..c5315cca3 120000 --- a/public/config/43.xml +++ b/public/config/43.xml @@ -1 +1 @@ -E:/newcode/blazing/public/assets/43.xml \ No newline at end of file +E:/newcode/sun/public/assets/43.xml \ No newline at end of file