game

package
v0.0.0-...-3945403 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2024 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// GlobalEntity在redis里的前缀
	GlobalEntityCachePrefix = db.GlobalDbName
	// GlobalEntity在mongo表里的key前缀
	GlobalEntityCollectionKeyPrefix = "GlobalEntity"
)
View Source
const (
	// 组件名
	ComponentNameActivities = "Activities"
)
View Source
const (
	// 组件名
	ComponentNameBag = "Bags"
)
View Source
const (
	// 组件名
	ComponentNameBaseInfo = "BaseInfo"
)
View Source
const (
	// 组件名
	ComponentNameGuild = "Guild"
)
View Source
const (
	// 组件名
	ComponentNameMoney = "Money"
)
View Source
const (
	// 组件名
	ComponentNamePendingMessages = "PendingMessages"
)
View Source
const (
	// 组件名
	ComponentNameProcessStatInfo = "ProcessStatInfo"
)
View Source
const (
	// 组件名
	ComponentNameQuest = "Quest"
)
View Source
const (
	// Player在redis里的前缀
	PlayerCachePrefix = "p"
)
View Source
const (
	PropertyKey = "Property"
)

Variables

This section is empty.

Functions

func AtomicSetGuildId

func AtomicSetGuildId(playerId int64, guildId int64, oldGuildId int64) bool

mongodb中对玩家公会id进行原子化操作,防止玩家同时存在于多个公会

比如:
step1:玩家向公会A,B发送入会申请
step2:公会A,B的管理员同时操作,同意入会申请,如果没有原子化保证,玩家将同时加入到A,B公会

func AutoRegisterPlayerPacketHandler

func AutoRegisterPlayerPacketHandler(packetHandlerRegister PacketHandlerRegister)

根据proto的命名规则和玩家组件里消息回调的格式,通过反射自动生成消息的注册 类似Java的注解功能

func CreateNewActivity

func CreateNewActivity(activityCfgId int32, activities internal.ActivityMgr, t time.Time) internal.Activity

根据模板创建活动对象

func DeletePendingMessage

func DeletePendingMessage(playerId, messageId int64)

删除1个待处理消息(线程安全)

func GetPlayerMgr

func GetPlayerMgr() internal.PlayerMgr

func InitGlobalEntityStructAndHandler

func InitGlobalEntityStructAndHandler()

注册GlobalEntity的结构体和消息回调

func InitPlayerStructAndHandler

func InitPlayerStructAndHandler()

func OfflinePlayerProcess

func OfflinePlayerProcess(playerId int64, data interface{}, f func(offlinePlayerId int64, offlineData interface{}) bool) bool

对离线玩家的数据处理 NOTE:当对离线玩家进行数据修改时,需要考虑并发问题,比如多个协程都在对同一个玩家进行数据修改 或者该玩家正在上线过程中

func RegisterConditionCheckers

func RegisterConditionCheckers() *internal.ConditionMgr

注册条件接口

func RegisterProgressCheckers

func RegisterProgressCheckers() *internal.ProgressMgr

注册进度接口

func RoutePlayerPacket

func RoutePlayerPacket(playerId int64, packet Packet, opts ...RouteOption) bool

路由玩家消息 ServerA -> ServerB -> Player

WithDirectSendClient(): 消息直接转发给客户端,不做逻辑处理 ServerA -> ServerB -> Client

举例: 有人申请加入公会,公会广播该消息给公会成员,ServerB收到消息后,直接把消息发给客户端(Player.Send),而不需要放入玩家的逻辑消息队列(Player.OnRecvPacket)

WithSaveDb(): 消息先保存数据库再转发,防止丢失 举例: 公会会长同意了玩家A的入会申请,此时玩家A可能不在线,就把该消息存入玩家的数据库,待玩家下次上线时,从数据库取出该消息,并进行相应的逻辑处理

func SetPlayerMgr

func SetPlayerMgr(mgr internal.PlayerMgr)

Types

type Activities

type Activities struct {
	*PlayerMapDataComponent
	Data *gentity.MapData[int32, internal.Activity] `db:""`
}

活动模块

func (*Activities) AddAllActivities

func (this *Activities) AddAllActivities(t time.Time)

func (*Activities) AddNewActivity

func (this *Activities) AddNewActivity(activityCfg *pb.ActivityCfg, t time.Time) internal.Activity

func (*Activities) CanJoin

func (this *Activities) CanJoin(activityCfg *pb.ActivityCfg, t time.Time) bool

检查活动是否能参加

func (*Activities) CheckEnd

func (this *Activities) CheckEnd(t time.Time)

检查已经结束的活动

func (*Activities) CheckEndTime

func (this *Activities) CheckEndTime(activityCfg *pb.ActivityCfg, t time.Time) bool

检查活动时间是否结束

func (*Activities) CheckJoinTime

func (this *Activities) CheckJoinTime(activityCfg *pb.ActivityCfg, t time.Time) bool

检查活动时间能否参加

func (*Activities) GetActivity

func (this *Activities) GetActivity(activityId int32) internal.Activity

func (*Activities) LoadFromBytesMap

func (this *Activities) LoadFromBytesMap(bytesMap any) error

func (*Activities) OnEvent

func (this *Activities) OnEvent(event interface{})

事件分发

func (*Activities) RemoveActivity

func (this *Activities) RemoveActivity(activityId int32)

type ActivityConditionArg

type ActivityConditionArg struct {
	Activities *Activities
	Activity   internal.Activity
}

type ActivityDefault

type ActivityDefault struct {
	ChildActivity
	// 子活动的保存数据必须是一个整体,无法再细分,因为gentity目前只支持2层结构(Activities是第1层,子活动是第2层)
	Base *pb.ActivityDefaultBaseData `db:"Base"`
}

默认活动模板,支持常见的简单活动

func (*ActivityDefault) Exchange

func (this *ActivityDefault) Exchange(exchangeCfgId int32)

兑换物品

商店也是一种兑换功能

func (*ActivityDefault) GetPropertyInt32

func (this *ActivityDefault) GetPropertyInt32(propertyName string) int32

func (*ActivityDefault) OnDateChange

func (this *ActivityDefault) OnDateChange(oldDate time.Time, curDate time.Time)

func (*ActivityDefault) OnEnd

func (this *ActivityDefault) OnEnd(t time.Time)

func (*ActivityDefault) OnEvent

func (this *ActivityDefault) OnEvent(event interface{})

func (*ActivityDefault) ReceiveReward

func (this *ActivityDefault) ReceiveReward(cfgId int32)

领取活动任务奖励

func (*ActivityDefault) Reset

func (this *ActivityDefault) Reset()

重置数据

type ActivityProgressDataWrapper

type ActivityProgressDataWrapper struct {
	*pb.ActivityProgressData
	ActivityId int32
}

增加活动id,以便于更新进度后,调用Activity.SetDirty

type BagCountItem

type BagCountItem struct {
	*gentity.MapData[int32, int32] `db:""`
}

有数量的物品背包

func NewBagCountItem

func NewBagCountItem() *BagCountItem

func (*BagCountItem) AddItem

func (b *BagCountItem) AddItem(arg *pb.AddItemArg) int32

func (*BagCountItem) DelItem

func (b *BagCountItem) DelItem(arg *pb.DelItemArg) int32

func (*BagCountItem) GetCapacity

func (b *BagCountItem) GetCapacity() int32

背包容量

func (*BagCountItem) GetItemCount

func (b *BagCountItem) GetItemCount(itemCfgId int32) int32

type BagEquip

type BagEquip struct {
	*BagUnique[*pb.Equip] `db:""`
}

装备背包

func NewBagEquip

func NewBagEquip() *BagEquip

type BagUnique

type BagUnique[E internal.Uniquely] struct {
	*gentity.MapData[int64, E] `db:""`
	ItemCtor                   func(arg *pb.AddItemArg) E // 物品的构造接口
	// contains filtered or unexported fields
}

func NewBagUnique

func NewBagUnique[E internal.Uniquely](itemCtor func(arg *pb.AddItemArg) E) *BagUnique[E]

func (*BagUnique[E]) AddItem

func (b *BagUnique[E]) AddItem(arg *pb.AddItemArg) int32

func (*BagUnique[E]) AddUniqueItem

func (b *BagUnique[E]) AddUniqueItem(e E) int32

func (*BagUnique[E]) DelItem

func (b *BagUnique[E]) DelItem(arg *pb.DelItemArg) int32

func (*BagUnique[E]) DelUniqueItem

func (b *BagUnique[E]) DelUniqueItem(uniqueId int64) int32

func (*BagUnique[E]) GetCapacity

func (b *BagUnique[E]) GetCapacity() int32

func (*BagUnique[E]) GetItemCount

func (b *BagUnique[E]) GetItemCount(itemCfgId int32) int32

type BagUniqueItem

type BagUniqueItem struct {
	*BagUnique[*pb.UniqueCountItem] `db:""`
}

不可叠加的普通物品背包

func NewBagUniqueItem

func NewBagUniqueItem() *BagUniqueItem

func (*BagUniqueItem) GetCapacity

func (b *BagUniqueItem) GetCapacity() int32

type Bags

type Bags struct {
	BasePlayerComponent
	BagCountItem  *BagCountItem  `child:"CountItem"`  // 普通物品
	BagUniqueItem *BagUniqueItem `child:"UniqueItem"` // 不可叠加的普通物品(如限时类的普通物品)
	BagEquip      *BagEquip      `child:"Equip"`      // 装备
}

背包模块 演示通过组合模式,整合多个不同的子背包模块,提供更高一级的背包接口

func (*Bags) AddItem

func (b *Bags) AddItem(arg *pb.AddItemArg) int32

背包模块提供对外的添加物品接口 业务层应该尽量使用该接口

func (*Bags) AddItemById

func (b *Bags) AddItemById(cfgId, num int32) int32

func (*Bags) AddItems

func (b *Bags) AddItems(addItemArgs []*pb.AddItemArg) int32

func (*Bags) DelItems

func (b *Bags) DelItems(delItems []*pb.DelItemArg) int32

func (*Bags) GetBag

func (b *Bags) GetBag(itemCfgId int32) internal.Bag

根据物品配置获取对应的子背包

func (*Bags) GetBagByArg

func (b *Bags) GetBagByArg(arg *pb.AddItemArg) internal.Bag

func (*Bags) GetItemCount

func (b *Bags) GetItemCount(itemCfgId int32) int32

func (*Bags) IsEnough

func (b *Bags) IsEnough(items []*pb.DelItemArg) bool

func (*Bags) TriggerPlayerEntryGame

func (b *Bags) TriggerPlayerEntryGame(event *internal.EventPlayerEntryGame)

响应事件:玩家进入游戏

type BaseInfo

type BaseInfo struct {
	PlayerDataComponent
	// plain表示明文存储,在保存到mongo时,不会进行proto序列化
	Data *pb.BaseInfo `db:"plain"`
}

玩家基础信息组件

func (*BaseInfo) GetOnlineSecondsThisTime

func (this *BaseInfo) GetOnlineSecondsThisTime() int32

本次登录在线时长

func (*BaseInfo) GetTotalOnlineSeconds

func (this *BaseInfo) GetTotalOnlineSeconds() int32

总在线时长

func (*BaseInfo) HandlePlayerEntryGameOk

func (this *BaseInfo) HandlePlayerEntryGameOk(msg *pb.PlayerEntryGameOk)

玩家进游戏服成功,非客户端消息 这种格式写的函数可以自动注册非客户端的消息回调

func (*BaseInfo) IncExp

func (this *BaseInfo) IncExp(incExp int32)

func (*BaseInfo) TriggerPlayerExit

func (this *BaseInfo) TriggerPlayerExit(event *internal.EventPlayerExit)

type BasePlayerComponent

type BasePlayerComponent struct {
	// contains filtered or unexported fields
}

玩家组件

func (*BasePlayerComponent) GetCacheKey

func (this *BasePlayerComponent) GetCacheKey() string

组件缓存key

func (*BasePlayerComponent) GetEntity

func (this *BasePlayerComponent) GetEntity() gentity.Entity

func (*BasePlayerComponent) GetName

func (this *BasePlayerComponent) GetName() string

组件名

func (*BasePlayerComponent) GetPlayer

func (this *BasePlayerComponent) GetPlayer() *Player

关联的玩家对象

func (*BasePlayerComponent) GetPlayerId

func (this *BasePlayerComponent) GetPlayerId() int64

关联的玩家id

func (*BasePlayerComponent) SetEntity

func (this *BasePlayerComponent) SetEntity(entity gentity.Entity)

type ChildActivity

type ChildActivity struct {
	internal.BaseActivity
	gentity.MapValueDirtyMark[int32]
	Activities *Activities
}

子活动,目前限制子活动只能是单保存字段(SingleField)

func (*ChildActivity) GetActivityCfg

func (this *ChildActivity) GetActivityCfg() *pb.ActivityCfg

活动配置数据

type ConditionCheckerArg

type ConditionCheckerArg struct {
	Player   *Player
	Activity internal.Activity
}

条件检查参数

type GlobalEntity

type GlobalEntity struct {
	gentity.BaseRoutineEntity
	// contains filtered or unexported fields
}

演示全局类的非玩家实体 这里演示的GlobalEntity,每个game进程一个实例

func CreateGlobalEntityFromDb

func CreateGlobalEntityFromDb() *GlobalEntity

从数据库加载的数据构造出GlobalEntity对象

func GetGlobalEntity

func GetGlobalEntity() *GlobalEntity

func NewGlobalEntity

func NewGlobalEntity() *GlobalEntity

func (*GlobalEntity) GetProcessStatInfo

func (this *GlobalEntity) GetProcessStatInfo() *ProcessStatInfo

func (*GlobalEntity) LoadData

func (this *GlobalEntity) LoadData(data interface{}) error

func (*GlobalEntity) RunRoutine

func (this *GlobalEntity) RunRoutine() bool

func (*GlobalEntity) SaveCache

func (this *GlobalEntity) SaveCache(kvCache gentity.KvCache) error

func (*GlobalEntity) SaveDb

func (this *GlobalEntity) SaveDb(removeCacheAfterSaveDb bool) error

type Guild

type Guild struct {
	PlayerDataComponent
	// 这里使用明文方式保存数据,以便使用mongodb语句直接进行操作,如AtomicSetGuildId函数
	Data *pb.PlayerGuildData `db:"plain"`
}

玩家的公会模块

func (*Guild) GetGuildData

func (this *Guild) GetGuildData() *pb.PlayerGuildData

func (*Guild) HandleGuildJoinReqOpResult

func (this *Guild) HandleGuildJoinReqOpResult(msg *pb.GuildJoinReqOpResult)

自己的入会申请的操作结果

这种格式写的函数可以自动注册非客户端的消息回调

func (*Guild) OnGuildCreateReq

func (this *Guild) OnGuildCreateReq(req *pb.GuildCreateReq) (*pb.GuildCreateRes, error)

创建公会

func (*Guild) OnGuildDataViewReq

func (this *Guild) OnGuildDataViewReq(req *pb.GuildDataViewReq) (*pb.GuildDataViewRes, error)

查看自己公会的信息

func (*Guild) OnGuildJoinAgreeReq

func (this *Guild) OnGuildJoinAgreeReq(req *pb.GuildJoinAgreeReq) (*pb.GuildJoinAgreeRes, error)

公会管理员处理申请者的入会申请

func (*Guild) OnGuildJoinReq

func (this *Guild) OnGuildJoinReq(req *pb.GuildJoinReq) (*pb.GuildJoinRes, error)

加入公会请求

func (*Guild) OnGuildListReq

func (this *Guild) OnGuildListReq(req *pb.GuildListReq) (*pb.GuildListRes, error)

查询公会列表

func (*Guild) RoutePacketToGuild

func (this *Guild) RoutePacketToGuild(cmd gnet.PacketCommand, message proto.Message) bool

公会成员的客户端的请求消息路由到自己的公会所在服务器

func (*Guild) RouteRpcToSelfGuild

func (this *Guild) RouteRpcToSelfGuild(message proto.Message, reply proto.Message) error

公会成员的客户端的请求消息路由到自己的公会所在服务器,并阻塞等待返回结果

func (*Guild) RouteRpcToTargetGuild

func (this *Guild) RouteRpcToTargetGuild(targetGuildId int64, message proto.Message, reply proto.Message) error

客户端的请求消息路由到目标公会所在服务器,并阻塞等待返回结果

func (*Guild) SetGuildId

func (this *Guild) SetGuildId(guildId int64)

type Hook

type Hook struct {
}

func (*Hook) OnApplicationExit

func (h *Hook) OnApplicationExit()

服务器关闭回调

func (*Hook) OnApplicationInit

func (h *Hook) OnApplicationInit(initArg interface{})

服务器初始化回调

func (*Hook) OnRegisterServerHandler

func (h *Hook) OnRegisterServerHandler(_ any)

type Money

type Money struct {
	PlayerDataComponent
	// 该字段必须导出(首字母大写)
	// 使用struct tag来标记该字段需要存数据库,可以设置存储字段名
	Data *pb.Money `db:""`
}

玩家的钱财组件

func (*Money) IncCoin

func (this *Money) IncCoin(coin int32)

func (*Money) IncDiamond

func (this *Money) IncDiamond(diamond int32)

func (*Money) OnCoinReq

func (this *Money) OnCoinReq(req *pb.CoinReq) (*pb.CoinRes, error)

请求加coin的消息回调 这种格式写的函数可以自动注册客户端消息回调

type PendingMessages

type PendingMessages struct {
	BasePlayerComponent
	gentity.BaseDirtyMark
	Messages map[int64]*pb.PendingMessage `db:""`
}

待处理消息

NOTE:该组件不会在玩家下线时保存数据库,也不保存缓存,不要SetDirty 因为待处理消息,会有其他进程直接往mongodb写入PendingMessages

func (*PendingMessages) TriggerPlayerEntryGame

func (this *PendingMessages) TriggerPlayerEntryGame(event *internal.EventPlayerEntryGame)

事件接口

type Player

type Player struct {
	gentity.BaseRoutineEntity
	// contains filtered or unexported fields
}

玩家对象

func CreatePlayer

func CreatePlayer(playerId int64, playerName string, accountId int64, regionId int32) *Player

func CreatePlayerFromData

func CreatePlayerFromData(playerData *pb.PlayerData) *Player

从加载的数据构造出玩家对象

func CreateTempPlayer

func CreateTempPlayer(playerId, accountId int64) *Player

func GetPlayer

func GetPlayer(playerId int64) *Player

func (*Player) FireConditionEvent

func (this *Player) FireConditionEvent(event interface{})

分发条件相关事件

func (*Player) FireEvent

func (this *Player) FireEvent(event any)

分发事件

func (*Player) GetAccountId

func (this *Player) GetAccountId() int64

账号id

func (*Player) GetActivities

func (this *Player) GetActivities() *Activities

func (*Player) GetBags

func (p *Player) GetBags() *Bags

func (*Player) GetBaseInfo

func (this *Player) GetBaseInfo() *BaseInfo

func (*Player) GetConnection

func (this *Player) GetConnection() Connection

func (*Player) GetGuild

func (this *Player) GetGuild() *Guild

func (*Player) GetLevel

func (this *Player) GetLevel() int32

func (*Player) GetMoney

func (this *Player) GetMoney() *Money

func (*Player) GetName

func (this *Player) GetName() string

玩家名(unique)

func (*Player) GetPendingMessages

func (this *Player) GetPendingMessages() *PendingMessages

func (*Player) GetPropertyInt32

func (p *Player) GetPropertyInt32(propertyName string) int32

提供一个统一的属性值查询接口

func (*Player) GetQuest

func (this *Player) GetQuest() *Quest

func (*Player) GetRegionId

func (this *Player) GetRegionId() int32

区服id

func (*Player) OnDisconnect

func (this *Player) OnDisconnect(connection Connection)

func (*Player) OnRecvPacket

func (this *Player) OnRecvPacket(packet *ProtoPacket)

放入消息队列

func (*Player) OnTestCmd

func (p *Player) OnTestCmd(req *pb.TestCmd)

直接写在实体上的消息回调

func (*Player) ResetConnection

func (this *Player) ResetConnection()

func (*Player) RunRoutine

func (this *Player) RunRoutine() bool

开启消息处理协程 每个玩家一个独立的消息处理协程 除了登录消息,其他消息都在玩家自己的协程里处理,因此这里对本玩家的操作不需要加锁

func (*Player) SaveCache

func (this *Player) SaveCache(kvCache gentity.KvCache) error

func (*Player) SaveDb

func (this *Player) SaveDb(removeCacheAfterSaveDb bool) error

玩家数据保存数据库

func (*Player) Send

func (this *Player) Send(message proto.Message, opts ...SendOption) bool

发包(protobuf) NOTE:调用Send(message)之后,不要再对message进行读写!

func (*Player) SendErrorRes

func (this *Player) SendErrorRes(errorReqCmd PacketCommand, errorMsg string) bool

通用的错误返回消息

func (*Player) SendPacket

func (this *Player) SendPacket(packet Packet, opts ...SendOption) bool

func (*Player) SendWithCommand

func (this *Player) SendWithCommand(cmd PacketCommand, message proto.Message, opts ...SendOption) bool

func (*Player) SetConnection

func (this *Player) SetConnection(connection Connection, useGate bool)

设置关联的连接,支持客户端直连模式和网关模式

type PlayerComponent

type PlayerComponent interface {
	gentity.Component
	// 关联的玩家对象
	GetPlayer() *Player
}

玩家组件接口

type PlayerDataComponent

type PlayerDataComponent struct {
	BasePlayerComponent
	gentity.BaseDirtyMark
}

保存数据作为一个整体的玩家组件 当保存数据的任何一个字段更新时,作为一个整体进行缓存更新

func NewPlayerDataComponent

func NewPlayerDataComponent(player *Player, componentName string) *PlayerDataComponent

type PlayerMapDataComponent

type PlayerMapDataComponent struct {
	BasePlayerComponent
	gentity.BaseMapDirtyMark
}

保存数据为map格式的玩家组件 当对map的某一项增删改时,只对那一项进行缓存更新

func NewPlayerMapDataComponent

func NewPlayerMapDataComponent(player *Player, componentName string) *PlayerMapDataComponent

type PlayerPropertyGetter

type PlayerPropertyGetter func(p *Player, propertyName string) int32

type ProcessStatInfo

type ProcessStatInfo struct {
	*gentity.BaseComponent
	// plain表示明文存储,在保存到mongo时,不会进行proto序列化
	StatInfo *gentity.ProtoData[*pb.ProcessStatInfo] `db:"plain"`
}

进程统计信息组件

func (*ProcessStatInfo) HandleShutdownReq

func (this *ProcessStatInfo) HandleShutdownReq(req *pb.ShutdownReq)

func (*ProcessStatInfo) HandleStartupReq

func (this *ProcessStatInfo) HandleStartupReq(req *pb.StartupReq)

type ProgressEventMapping

type ProgressEventMapping struct {
	// contains filtered or unexported fields
}

进度事件映射

func (*ProgressEventMapping) CheckProgress

func (p *ProgressEventMapping) CheckProgress(event any, progress internal.CfgData)

func (*ProgressEventMapping) OnTriggerEvent

func (p *ProgressEventMapping) OnTriggerEvent(event any)

事件分发后,检查进度更新

type Quest

type Quest struct {
	BasePlayerComponent
	// 保存数据的子模块:已完成的任务
	// 保存数据的子模块必须是导出字段(字段名大写开头)
	Finished *gentity.SliceData[int32] `child:"plain"` // 明文保存
	// 保存数据的子模块:当前任务列表
	Quests *gentity.MapData[int32, *pb.QuestData] `child:""`
}

任务模块 有多个子模块

func (*Quest) AddQuest

func (this *Quest) AddQuest(questData *pb.QuestData)

func (*Quest) OnFinishQuestReq

func (this *Quest) OnFinishQuestReq(req *pb.FinishQuestReq) (*pb.FinishQuestRes, error)

完成任务的消息回调 这种格式写的函数可以自动注册客户端消息回调

func (*Quest) TriggerPlayerEntryGame

func (this *Quest) TriggerPlayerEntryGame(event *internal.EventPlayerEntryGame)

事件接口

type RouteOption

type RouteOption interface {
	// contains filtered or unexported methods
}

func WithConnection

func WithConnection(connection Connection) RouteOption

func WithDirectSendClient

func WithDirectSendClient() RouteOption

func WithError

func WithError(err error) RouteOption

func WithSaveDb

func WithSaveDb() RouteOption

func WithToServerId

func WithToServerId(toServerId int32) RouteOption

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL