build(go): 升级 gf/v2 框架至 v2.7.0

统一将 common、login 和 mysql driver 中的 github.com/gogf/gf/v2 依赖版本从 v2.6.3 更新到 v2.7.0。

feat(logic): 优化道具服务逻辑与数据结构

- 修改 Item 结构体,去除 Data 字段,新增 ItemId 和 ItemCnt 字段以提高可读性和查询效率。
- 调整 Item 相关方法实现,包括 Item(), AddItem(), SubItem() 和 CheakItem() 方法,支持直接按范围获取及增减物品
This commit is contained in:
2025-11-02 18:56:16 +08:00
parent 2b3c4b6ccd
commit 038bd0ce0c
18 changed files with 149 additions and 133 deletions

View File

@@ -4,7 +4,7 @@ go 1.18
require (
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.6.3
github.com/gogf/gf/v2 v2.6.3
github.com/gogf/gf/v2 v2.7.0
gorm.io/driver/mysql v1.5.4
gorm.io/gorm v1.25.7
)

View File

@@ -4,7 +4,7 @@ go 1.19
require github.com/panjf2000/gnet v1.6.7
require github.com/gogf/gf/v2 v2.6.3
require github.com/gogf/gf/v2 v2.7.0
require github.com/antchfx/xmlquery v1.4.4

View File

@@ -74,6 +74,7 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla
}
moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName
break
}
}

View File

@@ -17,15 +17,14 @@ func (h Controller) UserItemList(data *item.ItemListInboundInfo, c *player.Playe
result = &item.ItemListOutboundInfo{}
result.ItemList = make([]model.SingleItemInfo, 0)
c.Service.Item(func(m map[uint32]model.SingleItemInfo) bool {
for _, v := range m {
if int32(v.ItemId) >= int32(data.Param1) && int32(v.ItemId) <= int32(data.Param2) {
v.LeftTime = 360000
result.ItemList = append(result.ItemList, v)
}
}
return false
})
item := c.Service.Item(data.Param1, data.Param2)
for _, v := range item {
var vv model.SingleItemInfo
vv.ItemId = v.ItemId
vv.ItemCnt = v.ItemCnt
vv.LeftTime = 360000
result.ItemList = append(result.ItemList, vv)
}
return result, 0
}

View File

@@ -83,10 +83,7 @@ func (h *Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.
t.Info.DailyResArr[i] = 0 //重置每日任务
}
defer t.Service.Talk(func(m map[uint32]uint32) bool { //挖矿
m = map[uint32]uint32{}
return true
})
defer t.Service.Talk_Reset()
}

View File

@@ -81,7 +81,7 @@ func (h *Controller) PetRelease(
if removeIndex != -1 {
c.Service.PetInfo_One_exec(data.CatchTime, func(t *model.PetEX) {
t.Data = c.Info.PetList[removeIndex]
t.InBag = int(data.Flag)
t.InBag = 0
})
c.Info.PetList = append(c.Info.PetList[:removeIndex], c.Info.PetList[removeIndex+1:]...)
@@ -90,6 +90,7 @@ func (h *Controller) PetRelease(
case 1:
//todo 背包
c.Service.PetInfo_One_exec(data.CatchTime, func(t *model.PetEX) {
t.InBag = 1
c.Info.PetList = append(c.Info.PetList, t.Data)
result.PetInfo = t.Data

View File

@@ -233,41 +233,34 @@ func (p *Player) ItemAdd(t ...model.SingleItemInfo) (result []model.SingleItemIn
}
p.Service.Item(func(rer map[uint32]model.SingleItemInfo) bool {
for _, v := range ttt {
itemx, ok := xmlres.ItemsMAP[int(v.ItemId)]
if !ok {
cool.Loger.Error(context.TODO(), "物品不存在", v.ItemId)
for _, v := range ttt {
itemx, ok := xmlres.ItemsMAP[int(v.ItemId)]
if !ok {
cool.Loger.Error(context.TODO(), "物品不存在", v.ItemId)
t1 := NewTomeeHeader(2601, p.Info.UserID)
t1.Result = uint32(errorcode.ErrorCodes.ErrBaseItemTypeLimit)
p.SendPack(t1.Pack(nil)) //准备包由各自发,因为协议不一样
continue
}
itemm, ok := rer[v.ItemId]
if !ok {
rer[v.ItemId] = v
result = append(result, v)
continue
}
itemm.ItemCnt += v.ItemCnt
if itemm.ItemCnt > uint32(itemx.Max) {
cool.Loger.Error(context.TODO(), "物品超过拥有最大限制", v.ItemId)
t1 := NewTomeeHeader(2601, p.Info.UserID)
t1.Result = uint32(errorcode.ErrorCodes.ErrTooManyOfItem)
p.SendPack(t1.Pack(nil)) //准备包由各自发,因为协议不一样
continue
}
result = append(result, v)
rer[v.ItemId] = itemm
t1 := NewTomeeHeader(2601, p.Info.UserID)
t1.Result = uint32(errorcode.ErrorCodes.ErrBaseItemTypeLimit)
p.SendPack(t1.Pack(nil)) //准备包由各自发,因为协议不一样
continue
}
return true
})
if itemx.Max == 0 {
itemx.Max = 1
}
if p.Service.CheakItem(v.ItemId)+v.ItemCnt > uint32(itemx.Max) {
cool.Loger.Error(context.TODO(), "物品超过拥有最大限制", v.ItemId)
t1 := NewTomeeHeader(2601, p.Info.UserID)
t1.Result = uint32(errorcode.ErrorCodes.ErrTooManyOfItem)
p.SendPack(t1.Pack(nil)) //准备包由各自发,因为协议不一样
continue
}
p.Service.AddItem(v.ItemId, v.ItemCnt)
result = append(result, v)
}
return
}

View File

@@ -4,7 +4,7 @@ go 1.19
require (
github.com/gogf/gf/contrib/nosql/redis/v2 v2.6.3
github.com/gogf/gf/v2 v2.6.3
github.com/gogf/gf/v2 v2.7.0
)
require (

View File

@@ -91,6 +91,20 @@ func (s *BaseSysUserService) ServiceAdd(ctx context.Context, req *cool.AddReq) (
if !r.Get("password").IsNil() {
reqmap["password"] = gmd5.MustEncryptString(r.Get("password").String())
}
if s.UniqueKey != nil {
for k, v := range s.UniqueKey {
if reqmap[k] != nil {
count, err := cool.DBM(s.Model).Where(k, reqmap[k]).Count()
if err != nil {
return nil, err
}
if count > 0 {
err = gerror.New(v)
return nil, err
}
}
}
}
lastInsertId, err := m.Data(reqmap).InsertAndGetId()
if err != nil {
return

View File

@@ -42,6 +42,7 @@ func (c *PetBagController) GetSession(ctx context.Context, req *PetGetReq) (res
)
t := model.GenPetInfo(
req.PetTypeId, req.IndividualValue, req.NatureId, req.AbilityTypeEnum, req.IsShiny, req.Level)
service.NewUserService(uint32(admin.UserId)).PetAdd(*t)
return

View File

@@ -10,11 +10,10 @@ const TableNamePlayerBagItem = "player_bag_item"
type Item struct {
*cool.Model
PlayerID uint64 `gorm:"not null;index:idx_player_bag_item_by_player_id;comment:'所属玩家ID'" json:"player_id"`
Data string ` gorm:"type:text;not null;comment:'全部数据'" json:"data"`
}
type ItemEX struct {
Item
Data map[uint32]SingleItemInfo `orm:"data" json:"data"`
// 物品Id
ItemId uint32 `json:"item_id"`
// 物品数量,
ItemCnt uint32 `json:"item_cnt"`
}
type SingleItemInfo struct {

View File

@@ -22,7 +22,7 @@ type Pet struct {
// FreedTime uint32 `struc:"skip"` //放生时间
//是否可交易这里应该定义在精灵ID里
//是否上架
Data string `gorm:"type:text;not null;comment:'精灵全部数据'" json:"data"`
Data string `gorm:"type:jsonb;not null;comment:'精灵全部数据'" json:"data"`
}
type PetEX struct {
Pet
@@ -63,45 +63,17 @@ type PetInfo struct {
MaxHp uint32 `fieldDesc:"最大生命" `
// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
Prop [5]uint32 `fieldDesc:"属性" `
// // 攻击(@UInt long → uint32
// Attack uint32 `fieldDesc:"攻击" `
// // 防御(@UInt long → uint32
// Defence uint32 `fieldDesc:"防御" `
// * ev:生命学习力,攻击学习力,防御学习力,特攻学习力,特防学习力,速度学习力
Ev [6]uint32 `fieldDesc:"属性" `
// // 特攻(@UInt long → uint32
// SpecialAttack uint32 `fieldDesc:"特攻" `
// // 特防(@UInt long → uint32
// SpecialDefence uint32 `fieldDesc:"特防" `
// // 速度(@UInt long → uint32
// Speed uint32 `fieldDesc:"速度" `
// 生命学习力(@UInt long → uint32
EvHp uint32 `fieldDesc:"生命学习力" `
// 攻击学习力(@UInt long → uint32
EvAttack uint32 `fieldDesc:"攻击学习力" `
// 防御学习力(@UInt long → uint32
EvDefence uint32 `fieldDesc:"防御学习力" `
// 特攻学习力(@UInt long → uint32
EvSpecialAttack uint32 `fieldDesc:"特攻学习力" `
// 特防学习力(@UInt long → uint32注意原Java拼写evSpecialDefense
EvSpecialDefense uint32 `fieldDesc:"特防学习力" `
// 速度学习力(@UInt long → uint32
EvSpeed uint32 `fieldDesc:"速度学习力" `
SkillListLen uint32 `struc:"sizeof=SkillList"`
// 技能信息固定4条空则赋值0固定长度List → [4]SkillInfo零值即符合“赋值0”
SkillList []SkillInfo
// 捕捉时间(@UInt long → 若为时间戳用uint32若需时间类型可改为time.Time需配合序列化处理
CatchTime uint32 `fieldDesc:"捕捉时间" `
CatchTime uint32 //`json:"-"` // 显式忽略,不参与序列化
// 捕捉地图(@UInt long → uint32
CatchMap uint32 `fieldDesc:"捕捉地图" `

View File

@@ -38,14 +38,14 @@ func (p *PetInfo) CalculatePetPane() {
uint32(petxml.HP),
p.Dv,
p.Level,
p.EvHp,
p.Ev[0],
)
// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
p.Prop[0] = p.calculatePetPanelSize(
uint32(petxml.Atk),
p.Dv,
p.Level,
p.EvAttack,
p.Ev[1],
naxml.AttackCorrect,
)
@@ -53,7 +53,7 @@ func (p *PetInfo) CalculatePetPane() {
uint32(petxml.Def),
p.Dv,
p.Level,
p.EvDefence,
p.Ev[2],
naxml.DefenseCorrect,
)
@@ -61,7 +61,7 @@ func (p *PetInfo) CalculatePetPane() {
uint32(petxml.SpAtk),
p.Dv,
p.Level,
p.EvSpecialAttack,
p.Ev[3],
naxml.SaCorrect,
)
@@ -69,7 +69,7 @@ func (p *PetInfo) CalculatePetPane() {
uint32(petxml.SpDef),
p.Dv,
p.Level,
p.EvSpecialDefense,
p.Ev[4],
naxml.SdCorrect,
)
@@ -77,7 +77,7 @@ func (p *PetInfo) CalculatePetPane() {
uint32(petxml.Spd),
p.Dv,
p.Level,
p.EvSpeed,
p.Ev[5],
naxml.SpeedCorrect,
)

View File

@@ -2,32 +2,43 @@ package service
import (
"blazing/modules/blazing/model"
"github.com/gogf/gf/v2/frame/g"
)
func (s *UserService) Item(t func(map[uint32]model.SingleItemInfo) bool) {
func (s *UserService) Item(min, max uint32) []model.Item {
//todo待测试
var player model.ItemEX
m1 := s.Model(s.item.Model)
var ttt []model.Item
s.Model(s.item.Model).Where(g.Map{
"item_id <=": max,
"item_id >=": min,
}).Scan(&ttt)
err := m1.Scan(&player)
if err != nil {
player.PlayerID = uint64(s.userid)
player.Data = make(map[uint32]model.SingleItemInfo)
_, err := m1.Insert(player)
if err != nil {
panic(err)
}
return ttt
}
func (s *UserService) AddItem(id, count uint32) {
if t, _ := s.Model(s.item.Model).Where("item_id", id).Count(); t != 0 {
s.Model(s.item.Model).Where("item_id", id).Increment("item_cnt", count)
} else {
s.Model(s.item.Model).Data(g.Map{
"player_id": s.userid,
"item_id": id,
"item_cnt": count,
}).Insert()
}
if !t(player.Data) {
return
}
_, err = m1.Update(player)
if err != nil {
panic(err)
}
}
func (s *UserService) SubItem(id, count uint32) {
s.Model(s.item.Model).Where("item_id", id).Decrement("item_cnt", count)
}
func (s *UserService) CheakItem(id uint32) uint32 {
var ttt model.Item
s.Model(s.item.Model).Where("item_id", id).Scan(&ttt)
return ttt.ItemCnt
}
// /添加进来的物品一定是保证存在的

View File

@@ -16,6 +16,12 @@ func (s *UserService) PetInfo(flag int) []model.PetEX {
if err != nil {
return []model.PetEX{}
}
for i := 0; i < len(tt); i++ {
tt[i].Data.CatchTime = tt[i].CatchTime
}
return tt
}
@@ -25,6 +31,7 @@ func (s *UserService) PetInfo_One_exec(cachetime uint32, t func(*model.PetEX)) {
m := cool.DBM(s.pet.Model).Where("player_id", s.userid).Where("catch_time", cachetime)
var tt model.PetEX
m.Scan(&tt)
tt.Data.CatchTime = tt.CatchTime
t(&tt)
m.Update(tt)
}
@@ -33,6 +40,7 @@ func (s *UserService) PetInfo_One(cachetime uint32) model.PetEX {
m := cool.DBM(s.pet.Model).Where("player_id", s.userid).Where("catch_time", cachetime)
var tt model.PetEX
m.Scan(&tt)
tt.Data.CatchTime = tt.CatchTime
return tt
}
func (s *UserService) PetAdd(y model.PetInfo) {
@@ -59,6 +67,9 @@ func (s *PetService) ModifyBefore(ctx context.Context, method string, param map[
admin := cool.GetAdmin(ctx)
userId := admin.UserId
if 0 != gconv.Uint(param["in_bag"]) {
err = fmt.Errorf("修改失败")
}
if userId != gconv.Uint(param["player_id"]) {
err = fmt.Errorf("修改失败")
}

View File

@@ -19,3 +19,15 @@ func (s *UserService) Talk(t func(map[uint32]uint32) bool) {
}
}
func (s *UserService) Talk_Reset() {
m1 := s.Model(s.talk.Model)
var talks model.TalkEX
m1.Scan(&talks)
talks.Data = make(map[uint32]uint32)
m1.Update(talks)
}

1
public/config/30001.xml Symbolic link
View File

@@ -0,0 +1 @@
E:/newcode/flash/out/resource/xml/30001.xml

View File

@@ -1576,7 +1576,7 @@ eg:
<Map ID="49" Name="贝塔星荒原" InitX="774" InitY="350" StarExplorationID="8">
<Bosses>
<Boss TaskID="308" AppearTime="0 23" BossVisible="0" Name="SPT雷纳多"
<Boss Id="0" TaskID="308" AppearTime="0 23" BossVisible="0" Name="SPT雷纳多"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5016" ItemBonusOutID="8" SptLevel="1">
<!--BossMon MonID="113" Hp="1500" Lv="75" NewSeIdxs="10 61 73 77"/-->
<!--BossMon MonID="113" Hp="1100" Lv="75" NewSeIdxs="76"/-->
@@ -1793,13 +1793,17 @@ eg:
<Map ID="57" Name="尼古尔星" InitX="695" InitY="418" StarExplorationID="12" PrimaryScene="2">
<Bosses>
<Boss Id="0" TaskID="353" BossVisible="0" AppearTime="0 23" Name="SPT克鲁斯" SptLevel="1">
<BossMon MonID="1521" Hp="6000" Lv="100" NewSeIdxs="58 95 300 301 311 1489 1490" />
<!--<BossMon MonID="1521" Hp="10000" Lv="100" NewSeIdxs="58 311 1489 1490 300 301" />-->
</Boss>
<Boss Id="1" TaskID="2053" BossVisible="0" AppearTime="0 23" Name="SPT克鲁斯" SptLevel="2">
<Boss Id="0" TaskID="311" AppearTime="0 23" BossVisible="0" Name="SPT哈莫雷特"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="2">
<BossMon MonID="216" Hp="3000" Lv="80" NewSeIdxs="10 89 90"/>
</Boss>
<!-- <Boss Id="0" TaskID="353" BossVisible="0" AppearTime="0 23" Name="SPT克鲁斯" SptLevel="1">
<BossMon MonID="1521" Hp="6000" Lv="100" NewSeIdxs="58 95 300 301 311 1489 1490" />
<BossMon MonID="1521" Hp="10000" Lv="100" NewSeIdxs="58 311 1489 1490 300 301" />
</Boss> -->
<!-- <Boss Id="1" TaskID="2053" BossVisible="0" AppearTime="0 23" Name="SPT克鲁斯" SptLevel="2">
<BossMon MonID="1521" Hp="15000" Lv="100" NewSeIdxs="58 300 301 1489 1490 1533 1542" />
</Boss>
</Boss> -->
</Bosses>
<Monsters WildBonusProb="300" WildBonusTotalProb="1000" BonusID="5275" ItemBonusID="1" >
<Monster ID="235" Lv="19 20"/>
@@ -1917,37 +1921,37 @@ eg:
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="6" SptLevel="1">
<BossMon MonID="421" Hp="8000" Lv="80" NewSeIdxs="15 58 79 110 132"/>
</Boss-->
<Boss TaskID="316" AppearTime="0 23" BossVisible="0" Name="周日规则厄尔塞拉"
<Boss Id="0" TaskID="316" AppearTime="0 23" BossVisible="0" Name="周日规则厄尔塞拉"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="6" SptLevel="1">
<BossMon MonID="421" Hp="2500" Lv="80" NewSeIdxs="58 71 79 110 241"/>
<!--<BossMon MonID="421" Hp="2500" Lv="60" NewSeIdxs="58 71 79 110 241"/>-->
</Boss>
<Boss TaskID="316" AppearTime="0 23" BossVisible="0" Name="周一规则厄尔塞拉"
<Boss Id="1" TaskID="316" AppearTime="0 23" BossVisible="0" Name="周一规则厄尔塞拉"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="6" SptLevel="1">
<BossMon MonID="421" Hp="3000" Lv="80" NewSeIdxs="2 79 80 110 95"/>
<!--<BossMon MonID="421" Hp="3000" Lv="60" NewSeIdxs="2 79 80 110 95"/>-->
</Boss>
<Boss TaskID="316" AppearTime="0 23" BossVisible="0" Name="周二规则厄尔塞拉"
<Boss Id="2" TaskID="316" AppearTime="0 23" BossVisible="0" Name="周二规则厄尔塞拉"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="6" SptLevel="1">
<BossMon MonID="421" Hp="2500" Lv="80" NewSeIdxs="58 110 54"/>
<!--<BossMon MonID="421" Hp="2500" Lv="60" NewSeIdxs="58 110 54"/>-->
</Boss>
<Boss TaskID="316" AppearTime="0 23" BossVisible="0" Name="周三规则厄尔塞拉"
<Boss Id="3" TaskID="316" AppearTime="0 23" BossVisible="0" Name="周三规则厄尔塞拉"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="6" SptLevel="1">
<BossMon MonID="421" Hp="2500" Lv="80" NewSeIdxs="2 58 79 110 134"/>
<!--<BossMon MonID="421" Hp="2500" Lv="60" NewSeIdxs="2 58 79 110 134"/>-->
</Boss>
<Boss TaskID="316" AppearTime="0 23" BossVisible="0" Name="周四规则厄尔塞拉"
<Boss Id="4" TaskID="316" AppearTime="0 23" BossVisible="0" Name="周四规则厄尔塞拉"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="6" SptLevel="1">
<BossMon MonID="421" Hp="2000" Lv="80" NewSeIdxs="1 58 79 110 197"/>
<!--<BossMon MonID="421" Hp="2000" Lv="60" NewSeIdxs="1 58 79 110 197"/>-->
</Boss>
<Boss TaskID="316" AppearTime="0 23" BossVisible="0" Name="周五规则厄尔塞拉"
<Boss Id="5" TaskID="316" AppearTime="0 23" BossVisible="0" Name="周五规则厄尔塞拉"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="6" SptLevel="1">
<BossMon MonID="421" Hp="3000" Lv="80" NewSeIdxs="58 79 110"/>
<!--<BossMon MonID="421" Hp="3000" Lv="60" NewSeIdxs="58 79 110"/>-->
</Boss>
<Boss TaskID="316" AppearTime="0 23" BossVisible="0" Name="周六规则厄尔塞拉"
<Boss Id="6" TaskID="316" AppearTime="0 23" BossVisible="0" Name="周六规则厄尔塞拉"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5017" ItemBonusOutID="6" SptLevel="1">
<BossMon MonID="421" Hp="3000" Lv="80" NewSeIdxs="58 79 110 159"/>
<!--<BossMon MonID="421" Hp="3000" Lv="60" NewSeIdxs="58 79 110 159"/>-->
@@ -3241,31 +3245,31 @@ eg:
</GameTriggerGrp>
<Bosses>
<!--以下到谱尼真身的绑定地图对战的boss废弃,但不能删除(切记),会影响region的变化-->
<Boss TaskID="400" AppearTime="0 23" BossVisible="0" Name="普尼">
<Boss Id="0" TaskID="400" AppearTime="0 23" BossVisible="0" Name="普尼">
<BossMon MonID="300" Hp="65000" Lv="115" NewSeIdxs="1 2 58 85 87 88 331 1882"/>
</Boss>
<Boss TaskID="291" AppearTime="0 23" BossVisible="0" Name="普尼第一封印">
<Boss Id="1" TaskID="291" AppearTime="0 23" BossVisible="0" Name="普尼第一封印">
<BossMon MonID="300" Hp="5000" Lv="101" NewSeIdxs="91 331 1882"/>
</Boss>
<Boss TaskID="292" AppearTime="0 23" BossVisible="0" Name="普尼第二封印">
<Boss Id="2" TaskID="292" AppearTime="0 23" BossVisible="0" Name="普尼第二封印">
<BossMon MonID="300" Hp="6000" Lv="105" NewSeIdxs="92 331 1882"/>
</Boss>
<Boss TaskID="293" AppearTime="0 23" BossVisible="0" Name="普尼第三封印">
<Boss Id="3" TaskID="293" AppearTime="0 23" BossVisible="0" Name="普尼第三封印">
<BossMon MonID="300" Hp="7000" Lv="105" NewSeIdxs="93 94 331 1882"/>
</Boss>
<Boss TaskID="294" AppearTime="0 23" BossVisible="0" Name="普尼第四封印">
<Boss Id="4" TaskID="294" AppearTime="0 23" BossVisible="0" Name="普尼第四封印">
<BossMon MonID="300" Hp="8000" Lv="105" NewSeIdxs="101 1 2 106 107 331 1882"/>
</Boss>
<Boss TaskID="295" AppearTime="0 23" BossVisible="0" Name="普尼第五封印">
<Boss Id="5" TaskID="295" AppearTime="0 23" BossVisible="0" Name="普尼第五封印">
<BossMon MonID="300" Hp="10000" Lv="105" NewSeIdxs="109 1 2 110 331 1882"/>
</Boss>
<Boss TaskID="296" AppearTime="0 23" BossVisible="0" Name="普尼第六封印">
<Boss Id="6" TaskID="296" AppearTime="0 23" BossVisible="0" Name="普尼第六封印">
<BossMon MonID="300" Hp="13000" Lv="105" NewSeIdxs="58 1 2 124 331 1882"/>
</Boss>
<Boss TaskID="297" AppearTime="0 23" BossVisible="0" Name="普尼第七封印">
<Boss Id="7" TaskID="297" AppearTime="0 23" BossVisible="0" Name="普尼第七封印">
<BossMon MonID="300" Hp="16000" Lv="105" NewSeIdxs="11 58 139 142 331 1882"/>
</Boss>
<Boss TaskID="298" AppearTime="0 23" BossVisible="0" Name="普尼真身">
<Boss Id="8" TaskID="298" AppearTime="0 23" BossVisible="0" Name="普尼真身">
<BossMon MonID="300" Hp="7000" Lv="105" NewSeIdxs="91 58 331 1882"/>
<BossMon MonID="300" Hp="8000" Lv="105" NewSeIdxs="92 331 1882"/>
<BossMon MonID="300" Hp="9000" Lv="105" NewSeIdxs="93 94 331 1882"/>