2026-03-04 22:47:21 +08:00
|
|
|
|
package model
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"blazing/common/data"
|
|
|
|
|
|
"blazing/cool"
|
|
|
|
|
|
|
2026-03-05 11:21:38 +08:00
|
|
|
|
"github.com/gogf/gf/v2/os/gtime"
|
2026-03-04 22:47:21 +08:00
|
|
|
|
"github.com/tnnmigga/enum"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 表名常量
|
|
|
|
|
|
const TableNamePlayerPVP = "player_pvp"
|
|
|
|
|
|
|
|
|
|
|
|
// PVP 对应数据库表 player_pvp,用于记录用户PVP赛季数据及场次统计
|
|
|
|
|
|
type PVP struct {
|
2026-03-04 23:38:21 +08:00
|
|
|
|
*cool.Model
|
2026-03-04 22:47:21 +08:00
|
|
|
|
PlayerID uint64 `gorm:"not null;index:idx_pvp_player_id;comment:'所属玩家ID'" json:"player_id"`
|
2026-03-04 23:38:21 +08:00
|
|
|
|
|
|
|
|
|
|
SeasonData []PVPRankInfo `gorm:"type:jsonb;not null;comment:'赛季核心数据'" json:"season_data"`
|
|
|
|
|
|
|
|
|
|
|
|
RankInfo PVPRankInfo `gorm:"type:jsonb;not null;comment:'本赛季排名信息'" json:"rank_info"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-05 11:21:38 +08:00
|
|
|
|
func (u *PVP) Key() uint32 {
|
|
|
|
|
|
return uint32(u.ID)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果分数不对的话,就按时间排序
|
|
|
|
|
|
func (u *PVP) Less(than *PVP) bool {
|
|
|
|
|
|
if u.RankInfo.Score == than.RankInfo.Score {
|
|
|
|
|
|
return u.RankInfo.LastMatchTime.Unix() < than.RankInfo.LastMatchTime.Unix()
|
|
|
|
|
|
}
|
|
|
|
|
|
return u.RankInfo.Score < than.RankInfo.Score
|
|
|
|
|
|
}
|
2026-03-04 23:38:21 +08:00
|
|
|
|
func NewPVP() *PVP {
|
|
|
|
|
|
return &PVP{
|
|
|
|
|
|
Model: cool.NewModel(),
|
|
|
|
|
|
}
|
2026-03-04 22:47:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PVPSeasonData PVP赛季核心统计数据
|
|
|
|
|
|
// 聚合维度:总场次、胜负、积分、胜率等
|
|
|
|
|
|
type PVPRankInfo struct {
|
2026-03-05 11:21:38 +08:00
|
|
|
|
Rank uint32 `json:"rank"` // 本赛季全服排名(0=未上榜)
|
|
|
|
|
|
Score int `json:"score"` // 当前积分
|
|
|
|
|
|
TotalMatch uint32 `json:"total_match"` // 本赛季总场次
|
|
|
|
|
|
WinMatch uint32 `json:"win_match"` // 本赛季胜利场次
|
|
|
|
|
|
LoseMatch uint32 `json:"lose_match"` // 本赛季失败场次
|
|
|
|
|
|
DrawMatch uint32 `json:"draw_match"` // 本赛季平局场次
|
|
|
|
|
|
TotalScore int32 `json:"total_score"` // 本赛季总积分(胜加负减)
|
|
|
|
|
|
HighestScore int32 `json:"highest_score"` // 本赛季最高积分
|
|
|
|
|
|
ContinuousWin uint32 `json:"continuous_win"` // 本赛季最高连胜次数
|
|
|
|
|
|
LastMatchTime *gtime.Time `json:"last_match_time"` // 最后一场PVP时间(时间戳)
|
2026-03-04 22:47:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NoteReadyToFightInfo 战斗准备就绪消息结构体,NoteReadyToFightInfo
|
|
|
|
|
|
type NoteReadyToFightInfo struct {
|
|
|
|
|
|
//MAXPET uint32 `struc:"skip"` // 最大精灵数 struc:"skip"`
|
|
|
|
|
|
// 战斗类型ID(与野怪战斗为3,与人战斗为1,前端似乎未使用)
|
|
|
|
|
|
// @UInt long
|
|
|
|
|
|
Status uint32 `fieldDesc:"战斗类型ID 但前端好像没有用到 与野怪战斗为3,与人战斗似乎是1" `
|
|
|
|
|
|
//Mode uint32 `struc:"skip"`
|
|
|
|
|
|
// 我方信息
|
|
|
|
|
|
OurInfo FightUserInfo `fieldDesc:"我方信息" serialize:"struct"`
|
|
|
|
|
|
// Our *socket.Player `struc:"skip"`
|
|
|
|
|
|
OurPetListLen uint32 `struc:"sizeof=OurPetList"`
|
|
|
|
|
|
// 我方携带精灵的信息
|
|
|
|
|
|
// ArrayList<ReadyFightPetInfo>,使用切片模拟动态列表
|
|
|
|
|
|
OurPetList []ReadyFightPetInfo `fieldDesc:"我方携带精灵的信息" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
|
|
|
|
|
|
|
|
|
|
|
|
// 对方信息
|
|
|
|
|
|
OpponentInfo FightUserInfo `fieldDesc:"对方信息" serialize:"struct"`
|
|
|
|
|
|
//Opp *socket.Player `struc:"skip"`
|
|
|
|
|
|
OpponentPetListLen uint32 `struc:"sizeof=OpponentPetList"`
|
|
|
|
|
|
// 敌方的精灵信息
|
|
|
|
|
|
// 野怪战斗时:客户端接收此包前已生成精灵PetInfo,将部分信息写入该列表
|
|
|
|
|
|
OpponentPetList []ReadyFightPetInfo `fieldDesc:"敌方的精灵信息 如果是野怪 那么再给客户端发送这个包体时就提前生成好了这只精灵的PetInfo,然后把从PetInfo中把部分信息写入到这个敌方的精灵信息中再发送这个包结构体" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
|
|
|
|
|
|
}
|
|
|
|
|
|
type FightUserInfo struct {
|
|
|
|
|
|
// 用户ID(野怪为0),@UInt long
|
|
|
|
|
|
UserID uint32 `fieldDesc:"userID 如果为野怪则为0" `
|
|
|
|
|
|
|
|
|
|
|
|
// 玩家名称(野怪为UTF-8的'-',固定16字节)
|
|
|
|
|
|
// 使用[16]byte存储固定长度的字节数组
|
|
|
|
|
|
Nick string `struc:"[16]byte"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ReadyFightPetInfo 准备战斗的精灵信息结构体,ReadyFightPetInfo类
|
|
|
|
|
|
type ReadyFightPetInfo struct {
|
|
|
|
|
|
// 精灵ID,@UInt long
|
|
|
|
|
|
ID uint32 `fieldDesc:"精灵ID" `
|
|
|
|
|
|
|
|
|
|
|
|
// 精灵等级,@UInt long
|
|
|
|
|
|
Level uint32 `fieldDesc:"精灵等级" `
|
|
|
|
|
|
|
|
|
|
|
|
// 精灵当前HP,@UInt long
|
|
|
|
|
|
Hp uint32 `fieldDesc:"精灵HP" `
|
|
|
|
|
|
|
|
|
|
|
|
// 精灵最大HP,@UInt long
|
|
|
|
|
|
MaxHp uint32 `fieldDesc:"最大HP" `
|
|
|
|
|
|
SkillListLen uint32 `struc:"sizeof=SkillList"`
|
|
|
|
|
|
// 技能信息列表(固定4个元素,技能ID和剩余PP,无技能则为0)
|
|
|
|
|
|
// List<SkillInfo>,初始化容量为4
|
|
|
|
|
|
SkillList []SkillInfo `fieldDesc:"技能信息 技能ID跟剩余PP 固定32字节 没有给0" serialize:"fixedLength=4,type=structArray"`
|
|
|
|
|
|
|
|
|
|
|
|
// 精灵捕获时间,@UInt long
|
|
|
|
|
|
CatchTime uint32 `fieldDesc:"精灵捕获时间" `
|
|
|
|
|
|
|
|
|
|
|
|
// 捕捉地图(固定给0),@UInt long
|
|
|
|
|
|
CatchMap uint32 `fieldDesc:"捕捉地图 给0" `
|
|
|
|
|
|
|
|
|
|
|
|
// 固定给0,@UInt long
|
|
|
|
|
|
CatchRect uint32 `fieldDesc:"给0" `
|
|
|
|
|
|
|
|
|
|
|
|
// 固定给0,@UInt long
|
|
|
|
|
|
CatchLevel uint32 `fieldDesc:"给0" `
|
|
|
|
|
|
SkinID uint32 `fieldDesc:"精灵皮肤ID" `
|
|
|
|
|
|
// 是否闪光(@UInt long → uint32,0=否,1=是)
|
|
|
|
|
|
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
|
|
|
|
|
|
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
|
|
|
|
|
|
}
|
|
|
|
|
|
type FightOverInfo struct {
|
|
|
|
|
|
//0 正常结束
|
|
|
|
|
|
//1=isPlayerLost 对方玩家退出
|
|
|
|
|
|
// 2=isOvertime 超时
|
|
|
|
|
|
// 3=isDraw 双方平手
|
|
|
|
|
|
// 4=isSysError 系统错误
|
|
|
|
|
|
// 5=isNpcEscape 精灵主动逃跑
|
|
|
|
|
|
|
2026-03-07 00:26:05 +08:00
|
|
|
|
Winpet *PetInfo `struc:"skip"`
|
|
|
|
|
|
Round uint32 `struc:"skip"`
|
|
|
|
|
|
// Duration uint32 `struc:"skip"` // 对局时长(秒)
|
2026-03-04 22:47:21 +08:00
|
|
|
|
//7 切磋结束
|
|
|
|
|
|
Reason EnumBattleOverReason // 固定值0
|
|
|
|
|
|
WinnerId uint32 // 胜者的米米号 野怪为0
|
|
|
|
|
|
TwoTimes uint32 // 双倍经验剩余次数
|
|
|
|
|
|
ThreeTimes uint32 // 三倍经验剩余次数
|
|
|
|
|
|
AutoFightTimes uint32 // 自动战斗剩余次数
|
|
|
|
|
|
EnergyTime uint32 // 能量吸收器剩余次数
|
|
|
|
|
|
LearnTimes uint32 // 双倍学习器剩余次数
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 战斗结束原因枚举
|
|
|
|
|
|
type EnumBattleOverReason int
|
|
|
|
|
|
|
|
|
|
|
|
var BattleOverReason = enum.New[struct {
|
|
|
|
|
|
PlayerOffline EnumBattleOverReason `enum:"1"` //掉线
|
|
|
|
|
|
PlayerOVerTime EnumBattleOverReason `enum:"2"` //超时
|
|
|
|
|
|
NOTwind EnumBattleOverReason `enum:"3"` //打成平手
|
|
|
|
|
|
DefaultEnd EnumBattleOverReason `enum:"4"` //默认结束
|
|
|
|
|
|
PlayerEscape EnumBattleOverReason `enum:"5"` //逃跑
|
|
|
|
|
|
Cacthok EnumBattleOverReason `enum:"6"`
|
|
|
|
|
|
}]()
|
|
|
|
|
|
|
|
|
|
|
|
// AttackValue 战斗中的攻击数值信息
|
|
|
|
|
|
type AttackValue struct {
|
|
|
|
|
|
UserID uint32 `json:"userId" fieldDescription:"玩家的米米号 与野怪对战userid = 0"`
|
|
|
|
|
|
SkillID uint32 `json:"skillId" fieldDescription:"使用技能的id"`
|
|
|
|
|
|
AttackTime uint32 `json:"attackTime" fieldDescription:"是否击中 如果为0 则miss 如果为1 则击中,2为必中"`
|
|
|
|
|
|
LostHp uint32 `json:"lostHp" fieldDescription:"我方造成的伤害"`
|
|
|
|
|
|
GainHp int32 `json:"gainHp" fieldDescription:"我方获得血量"`
|
|
|
|
|
|
RemainHp int32 `json:"remainHp" fieldDescription:"我方剩余血量"`
|
|
|
|
|
|
MaxHp uint32 `json:"maxHp" fieldDescription:"我方最大血量"`
|
|
|
|
|
|
//颜色
|
|
|
|
|
|
State uint32 `json:"state" `
|
|
|
|
|
|
SkillListLen uint32 `struc:"sizeof=SkillList"`
|
|
|
|
|
|
SkillList []SkillInfo `json:"skillList" fieldDescription:"根据精灵的数据插入技能 最多4条 不定长"`
|
|
|
|
|
|
IsCritical uint32 `json:"isCritical" fieldDescription:"是否暴击"`
|
|
|
|
|
|
Status [20]int8 //精灵的状态
|
|
|
|
|
|
// 攻击,防御,特供,特防,速度,命中
|
|
|
|
|
|
Prop [6]int8
|
|
|
|
|
|
Offensive float32
|
|
|
|
|
|
// OwnerMaxShield uint32 `json:"ownerMaxShield" fieldDescription:"我方最大护盾"`
|
|
|
|
|
|
// OwnerCurrentShield uint32 `json:"ownerCurrentShield" fieldDescription:"我方当前护盾"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TableName 返回表名
|
|
|
|
|
|
func (*PVP) TableName() string {
|
|
|
|
|
|
return TableNamePlayerPVP
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GroupName 返回表组名
|
|
|
|
|
|
func (*PVP) GroupName() string {
|
|
|
|
|
|
return "default"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// init 程序启动时自动创建表
|
|
|
|
|
|
func init() {
|
|
|
|
|
|
cool.CreateTable(&PVP{})
|
|
|
|
|
|
}
|