fix(login): 修正用户登录时间字段命名及逻辑

将 `Onlinetime` 字段更名为 `Logintime`,以更准确反映其含义,并确保在登录时正确记录时间戳。

refactor(player): 移除冗余的 Save 方法及相关逻辑

删除 Player 结构体中的 Save、CanGetExp、CompleteLogin 和 IsNewPlayer 方法,
相关功能已迁移或不再使用。

feat(pprof): 更新 pprof 监听地址

修改 README 中的 pprof 示例命令,将监听地址从远程 IP 改为本地回环地址 `127.0.0.1
This commit is contained in:
2025-11-15 13:20:42 +08:00
parent 0e1860bdf4
commit f919047ff6
14 changed files with 120 additions and 112 deletions

View File

@@ -8,7 +8,7 @@
项目结构:
go tool pprof -http :8081 "http://125.208.20.223:54612/debug/debug/pprof/profile"
go tool pprof -http :8081 "http://127.0.0.1:9909/debug/debug/pprof/profile"
详情查看 [文档](./docs)

View File

@@ -66,7 +66,7 @@ func (h *Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.
return
}
t.Info.UserID = data.Head.UserID
t.Onlinetime = uint32(time.Now().Unix()) //保存时间戳
t.Logintime = uint32(time.Now().Unix()) //保存时间戳
t.Changemap = true
cool.Loger.Info(context.Background(), "用户上次重置日期", t.Info.LastResetTime.String())
if !IsToday(t.Info.LastResetTime) { //判断是否是今天

View File

@@ -49,8 +49,8 @@ func main() {
go cool.ListenFunc(gctx.New())
}
go Start(cool.Config.PortBL) //注入service
if cool.Config.PortBL == 1 { //只分析1服务器的
go Start(cool.Config.PortBL) //注入service
if cool.Config.PortBL == 1 || cool.Config.PortBL == 2 { //只分析1服务器的
go PprofWeb()
}

View File

@@ -18,7 +18,7 @@ type Effect112 struct {
func init() {
input.InitEffect(input.EffectType.Skill, 59, &Effect112{})
input.InitEffect(input.EffectType.Skill, 112, &Effect112{})
}

View File

@@ -26,7 +26,7 @@ type Effect52 struct {
func (e *Effect52) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0])
e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0] - 1)
}

View File

@@ -35,6 +35,6 @@ func (e *Effect57) OnSkill() bool {
return true
}
heal := e.Ctx().Our.CurrentPet.GetMaxHP().Div(decimal.NewFromInt(int64(e.Args()[1])))
e.Ctx().Opp.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal)
e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal)
return true
}

View File

@@ -52,7 +52,7 @@ func (e *Effect71) Switch(in *input.Input, at info.AttackValue, oldpet *info.Bat
return true
}
t := &Effect71_sub{}
t.Duration(2)
t.Duration(1)
t.ID(e.ID() + int(input.EffectType.Sub))
e.Ctx().Our.AddEffect(e.Ctx().Our, t)

View File

@@ -234,12 +234,6 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
}
currentskill = oldskill
//attacker.Initeffectcache()
// fmt.Println("开始攻击威力", oldskill.Power)
// if oldskill != nil {
// fmt.Println("开始攻击威力", oldskill.Power)
// }
//是否miss都应该施加解析effect
canuseskill := attacker.Exec(func(t input.Effect) bool { //这个是能否使用技能
//结算状态
@@ -249,11 +243,26 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
})
canuse := canuseskill && //
action.CanUse(currentskill) && //pp还在
attacker.CurrentPet.Info.Hp > 0
if !canuse {
//根本没释放技能,这些效果全部失效
for _, e := range attacker.EffectCache {
e.Alive(false)
}
//这时候将被覆盖的效果全部装回来enterturn
for _, e := range attacker.Effect_Lost {
e.Alive(true)
}
}
// 结算状态
// 然后这里还可以处理自爆类
if canuseskill && //
action.CanUse(currentskill) && //pp还在
attacker.CurrentPet.Info.Hp > 0 { //可以使用技能
if canuse { //可以使用技能
f.processSkillAttack(attacker, defender, currentskill)
currentskill = oldskill //还原技能
@@ -270,19 +279,6 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
skill.PP--
}
} else {
//根本没释放技能,这些效果全部失效
for _, e := range attacker.EffectCache {
e.Alive(false)
}
//这时候将被覆盖的效果全部装回来enterturn
for _, e := range attacker.Effect_Lost {
e.Alive(true)
}
}
//技能使用后

View File

@@ -200,7 +200,7 @@ func NewFight(mode, status info.EnumBattleMode, p1 common.PlayerI, p2 common.Pla
case info.BattleStatus.FIGHT_WITH_PLAYER:
default:
f.Our.Finished = true //PVE 默认boss数据直接加载完成
f.Opp.Finished = true //PVE 默认boss数据直接加载完成
}
f.Our.SetOPP(f.Opp)

View File

@@ -41,6 +41,7 @@ func (p *Player) PET_MELEE() *Player {
//确认是乱斗模式
if value.PVPinfo.Mode == info.BattleMode.PET_MELEE {
lw.PVPinfo = nil //先将自身的准备信息置空
lw = value
return
}

View File

@@ -193,9 +193,9 @@ func NewClientData(c gnet.Conn) *ClientData {
Wsmsg: &WsCodec{},
}
cd.LF = lockfree.NewLockfree[[]byte](
16,
8,
cd,
&lockfree.SchedBlockStrategy{},
lockfree.NewConditionBlockStrategy(),
)
// 启动Lockfree
if err := cd.LF.Start(); err != nil {

View File

@@ -1,7 +1,6 @@
package player
import (
"blazing/common/data/share"
"blazing/common/data/xmlres"
"blazing/common/socket/errorcode"
"blazing/common/utils"
@@ -55,9 +54,9 @@ type Player struct {
StopChan timer.TimeNoder
context.Context
PVPinfo *info.PVPinfo //当前邀请的玩家ID
Onlinetime uint32 //当前登录时间
OgreInfo OgreInfo
PVPinfo *info.PVPinfo //当前邀请的玩家ID
Logintime uint32 //当前登录时间
OgreInfo OgreInfo
Service *blservice.UserService
// PVP被邀请信息
@@ -320,77 +319,3 @@ func LeaveMap(c common.PlayerI) {
}
space.GetSpace(c.GetInfo().MapID).User.Remove(c.GetInfo().UserID)
}
// Save 保存玩家数据
func (p *Player) Save() {
if p.Info == nil {
return
}
if p.FightC != nil {
//ov := make(chan struct{})
go func() {
defer func() {
if err := recover(); err != nil { // 恢复 panicerr 为 panic 错误值
// 1. 打印错误信息
cool.Loger.Error(context.TODO(), "panic 错误:", err)
}
}()
p.FightC.Over(p, info.BattleOverReason.PlayerOffline) //玩家逃跑,但是不能锁线程
}()
//<-ov
select {
case <-p.FightC.GetOverChan(): //等待结束
case <-time.After(time.Second * 5): //等待5秒
cool.Loger.Error(context.TODO(), "战斗崩溃", p.Info.UserID)
}
}
p.Info.TimeToday = p.Info.TimeToday + uint32(time.Now().Unix()) - uint32(p.Onlinetime) //保存电池时间
p.Onlinetime = uint32(time.Now().Unix())
p.Service.Save(p.Info)
LeaveMap(p)
p.StopChan.Stop() //停止刷怪
p.IsLogin = false
Mainplayer.Delete(p.Info.UserID)
share.ShareManager.DeleteUserOnline(p.Info.UserID) //设置用户登录服务器
}
// 是否可以获得经验
func (p *Player) CanGetExp() bool {
ttt := p.Info.TimeLimit - p.Info.TimeToday
return (uint32(time.Now().Unix()) - uint32(p.Onlinetime)) <= ttt
}
// CompleteLogin 标记登录完成并通知等待者
func (lw *Player) CompleteLogin() {
if lw.Info.MapID > 500 || lw.Info.MapID == 0 { //如果位于基地,就重置到传送仓
lw.Info.MapID = 1
}
if lw.IsNewPlayer() { //重置新手地图
lw.Info.MapID = 515
}
lw.IsLogin = true
}
// 定义检查函数判断84-87索引中是否有任意一个元素不等于3
func (lw *Player) IsNewPlayer() bool {
// 遍历84到87的索引
for i := 84; i <= 87; i++ {
if lw.Info.TaskList[i] != 3 {
return true // 只要有一个不等于3就返回true
}
}
return false // 全部等于3则返回false
}

View File

@@ -0,0 +1,85 @@
package player
import (
"blazing/common/data/share"
"blazing/cool"
"blazing/logic/service/fight/info"
"context"
"time"
)
// Save 保存玩家数据
func (p *Player) Save() {
if p.Info == nil {
return
}
if p.FightC != nil {
//ov := make(chan struct{})
go func() {
defer func() {
if err := recover(); err != nil { // 恢复 panicerr 为 panic 错误值
// 1. 打印错误信息
cool.Loger.Error(context.TODO(), "panic 错误:", err)
}
}()
p.FightC.Over(p, info.BattleOverReason.PlayerOffline) //玩家逃跑,但是不能锁线程
}()
//<-ov
select {
case <-p.FightC.GetOverChan(): //等待结束
case <-time.After(time.Second * 5): //等待5秒
cool.Loger.Error(context.TODO(), "战斗崩溃", p.Info.UserID)
}
}
newtime := uint32(time.Now().Unix())
p.Info.TimeToday = p.Info.TimeToday + newtime - uint32(p.Logintime) //保存电池时间
p.Info.OnlineTime = (newtime - uint32(p.Logintime)) / 60 //每次退出时候保存已经在线的分钟数
p.Service.Save(p.Info)
LeaveMap(p)
p.StopChan.Stop() //停止刷怪
p.IsLogin = false
Mainplayer.Delete(p.Info.UserID)
share.ShareManager.DeleteUserOnline(p.Info.UserID) //设置用户登录服务器
}
// 是否可以获得经验
func (p *Player) CanGetExp() bool {
ttt := p.Info.TimeLimit - p.Info.TimeToday
return (uint32(time.Now().Unix()) - uint32(p.Logintime)) <= ttt
}
// CompleteLogin 标记登录完成并通知等待者
func (lw *Player) CompleteLogin() {
if lw.Info.MapID > 500 || lw.Info.MapID == 0 { //如果位于基地,就重置到传送仓
lw.Info.MapID = 1
}
if lw.IsNewPlayer() { //重置新手地图
lw.Info.MapID = 515
}
lw.IsLogin = true
}
// 定义检查函数判断84-87索引中是否有任意一个元素不等于3
func (lw *Player) IsNewPlayer() bool {
// 遍历84到87的索引
for i := 84; i <= 87; i++ {
if lw.Info.TaskList[i] != 3 {
return true // 只要有一个不等于3就返回true
}
}
return false // 全部等于3则返回false
}

View File

@@ -71,6 +71,7 @@ type PlayerInfo struct {
ExpPool uint32 `struc:"skip" json:"exp_pool"` // 累计经验池
LastResetTime time.Time `struc:"skip" json:"last_reset_time"` // 重置时间,比如电池和每日任务
OnlineTime uint32 `struc:"skip" json:"online_time"` //在线分钟数
// OutInfo 字段
UserID uint32 `struc:"uint32" json:"user_id"` // 米米号 通过sid拿到
RegisterTime uint32 `struc:"uint32" json:"register_time"` // 注册时间(秒时间戳)
@@ -100,7 +101,7 @@ type PlayerInfo struct {
AutoCharge uint32 `struc:"uint32" default:"1" json:"auto_charge"` // nono是否自动充电
VipEndTime uint32 `struc:"uint32" default:"4294967295" json:"vip_end_time"` // 超no的结束时间建议尽可能大
FreshManBonus uint32 `struc:"uint32" json:"fresh_man_bonus"` // 邀请活动建议先给固定值0
NonoChipList [80]byte `struc:"[80]byte" json:"nono_chip_list"` // 超no芯片列表
NonoChipList [80]byte `struc:"[80]byte" json:"-"` // 超no芯片列表
DailyResArr [50]byte `struc:"[50]byte" default:"0" json:"daily_res_arr"` // 每日任务状态 40+是谱尼的
Study struct {
TeacherID uint32 `struc:"uint32" json:"teacher_id"` // 教官id