Files
bl/logic/service/player/player.go

243 lines
5.1 KiB
Go
Raw Normal View History

package player
import (
"blazing/common/data/xmlres"
"blazing/common/socket/errorcode"
"blazing/common/utils"
"blazing/cool"
2025-11-18 23:41:31 +00:00
"blazing/logic/service/common"
2025-11-15 22:17:43 +00:00
"blazing/logic/service/fight/info"
"blazing/logic/service/space"
2025-11-18 22:16:55 +00:00
"sync/atomic"
"blazing/modules/base/service"
blservice "blazing/modules/blazing/service"
"context"
"github.com/antlabs/timer"
"github.com/gogf/gf/v2/frame/g"
"github.com/panjf2000/gnet/v2"
)
func ConutPlayer() int {
count := 0
Mainplayer.Range(func(uint32, *Player) bool {
count++
return true // 继续遍历
})
return count
}
var Mainplayer = &utils.SyncMap[uint32, *Player]{} //玩家数据
type OgreInfo struct {
Data [9]OgrePetInfo
}
type OgrePetInfo struct {
Id uint32
Shiny uint32
Lv uint32 `struc:"skip"` //等级
Item uint32 `struc:"skip"` //奖励,如果有的话
Ext uint32 `struc:"skip"` //是否变尼尔尼奥
}
type Player struct {
MainConn gnet.Conn
baseplayer
IsLogin bool //是否登录
2025-11-16 20:30:17 +00:00
Done
StopChan timer.TimeNoder
context.Context
2025-11-18 23:41:31 +00:00
Fightinfo info.Fightinfo //当前邀请的玩家ID
2025-11-18 22:16:55 +00:00
Logintime uint32 //当前登录时间
OgreInfo OgreInfo
Service *blservice.UserService
User *service.BaseSysUserService
// PVP被邀请信息
2025-11-18 23:41:31 +00:00
HavePVPinfo []common.PlayerI
monsters [3]int
//0 无,1可以刷怪,2是切换过地图
Canmon uint32 //可以刷怪
// Changemap bool //是否切换过地图
}
// PlayerOption 定义配置 Player 的函数类型
type PlayerOption func(*Player)
func WithConn(c gnet.Conn) PlayerOption {
return func(p *Player) {
p.MainConn = c
}
}
func (p *Player) UseCoins(t uint32) bool {
if p.Info.Coins < t {
return false
}
return true
}
func (p *Player) UseGold(t uint32) bool {
if p.User.GetGold(uint(p.Info.UserID)) < t {
return false
}
//p.Info.GoldBean = p.Info.GoldBean - t
return true
}
func (p *Player) GetAction() {
2025-11-18 23:41:31 +00:00
}
func (f *Player) InvitePlayer(ff common.PlayerI) {
f.HavePVPinfo = append(f.HavePVPinfo, ff)
tt := common.NewTomeeHeader(2501, f.GetInfo().UserID)
f.SendPack(tt.Pack(&info.NoteInviteToFightOutboundInfo{
UserID: ff.GetInfo().UserID,
Nick: ff.GetInfo().Nick,
Mode: ff.Getfightinfo().Mode,
}))
2025-11-18 23:41:31 +00:00
}
2025-11-18 22:16:55 +00:00
func (p *Player) Getfightinfo() info.Fightinfo {
2025-11-18 23:41:31 +00:00
return p.Fightinfo
2025-11-16 20:30:17 +00:00
}
2025-11-19 00:09:12 +00:00
func (p *Player) QuitFight() {
p.FightC = nil
2025-11-16 20:30:17 +00:00
atomic.StoreUint32(&p.Fightinfo.Mode, 0)
2025-11-19 00:09:12 +00:00
}
func (p *Player) GetSpace() *space.Space {
return space.GetSpace(p.Info.MapID)
}
2025-11-19 00:09:12 +00:00
// 0无战斗1PVP2,BOOS,3PVE
func (p *Player) CanFight() bool {
2025-11-19 00:09:12 +00:00
if len(p.Info.PetList) == 0 {
atomic.StoreUint32(&p.Fightinfo.Mode, 0)
return false
2025-11-18 22:16:55 +00:00
}
2025-11-18 22:16:55 +00:00
if p.FightC != nil {
atomic.StoreUint32(&p.Fightinfo.Mode, 0)
return false
2025-11-18 22:16:55 +00:00
}
// if p.GetSpace().ARENA.ChallengerID == p.Info.UserID || p.GetSpace().ARENA.Id == p.Info.UserID {
// return false
// }
for _, v := range p.Info.PetList {
if v.Hp > 0 { // 只要找到一个血量大于0的宠物就可以战斗
return true
2025-11-18 22:16:55 +00:00
}
}
// 遍历完所有宠物都没有血量大于0的才不能战斗
atomic.StoreUint32(&p.Fightinfo.Mode, 0)
return false
// }
// return false
}
func (p *Player) SendPack(b []byte) error {
if p.MainConn == nil {
return nil
}
_, ok := p.MainConn.Context().(*ClientData)
if ok {
return p.MainConn.Context().(*ClientData).SendPack(b)
}
return nil
}
2025-11-15 22:17:43 +00:00
// 添加物品 返回成功添加的物品
func (p *Player) ItemAdd(ItemId, ItemCnt uint32) (result bool) {
switch ItemId {
case 1: //塞尔豆
p.Info.Coins = p.Info.Coins + ItemCnt
return true
case 3: //累计经验
p.Info.ExpPool = p.Info.ExpPool + ItemCnt
return true
case 5: //金豆ItemAdd
p.User.SetGold(p.Info.UserID, uint32(p.User.GetGold(uint(p.Info.UserID))+ItemCnt*100))
return true
default:
itemx, ok := xmlres.ItemsMAP[int(ItemId)]
if !ok {
cool.Loger.Error(context.TODO(), "物品不存在", ItemId)
t1 := common.NewTomeeHeader(2601, p.Info.UserID)
t1.Result = uint32(errorcode.ErrorCodes.ErrSystemError200007)
p.SendPack(t1.Pack(nil)) //准备包由各自发,因为协议不一样
return false
}
if itemx.Max == 0 {
itemx.Max = 1
}
if p.Service.Item.CheakItem(ItemId)+ItemCnt > uint32(itemx.Max) {
println(p.Info.UserID, "物品超过拥有最大限制", ItemId)
t1 := common.NewTomeeHeader(2601, p.Info.UserID)
t1.Result = uint32(errorcode.ErrorCodes.ErrTooManyOfItem)
p.SendPack(t1.Pack(nil)) //准备包由各自发,因为协议不一样
return false
}
p.Service.Item.AddItem(ItemId, ItemCnt)
return true
}
return false
}
func (player1 *Player) Kick() {
if player1.IsLogin {
//取成功,否则创建
//player1.Save() //先保存数据再返回
head := common.NewTomeeHeader(1001, player1.Info.UserID)
head.Result = uint32(errorcode.ErrorCodes.ErrAccountLoggedInElsewhere)
//实际上这里有个问题,会造成重复保存问题
player1.SendPack(head.Pack(nil))
CloseChan := make(chan struct{})
player1.MainConn.CloseWithCallback(func(c gnet.Conn, err error) error {
close(CloseChan)
return nil
})
<-CloseChan
}
}
func (p *Player) Cheak(b error) {
if b != nil {
g.Log().Error(context.Background(), "出现错误", p.Info.UserID, b.Error())
}
}