gentity

package module
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2024 License: MIT Imports: 19 Imported by: 10

README

gentity

游戏服务器中的实体对象的序列化,数据读写,缓存等接口,通过配置即可实现对象的数据保存加载,缓存更新,极大的简化编码

基于gentity,游戏服务器框架可以更快的构建

网络库使用gnet

gentity

Entity-Component

Entity-Component模式是类似Unity的GameObject-Component的实体组件模式,便于组件解耦

比如游戏服务器中的玩家对象就属于Entity,玩家的任务模块就是一个Component

实体数据

实体数据的加载和保存是游戏服务器最基础的功能,gentity利用go的struct tag,大大简化了实体数据加载和保存的接口

gentity抽象出了实体的数据库接口EntityDb和实体的缓存接口KvCache

gentity内置了EntityDb的mongodb实现,和KvCache的redis实现

struct tag

使用go的struct tag,设置对象组件的字段,框架接口会自动对这些字段进行数据库读取保存和缓存更新,极大的简化了业务代码对数据库和缓存的操作

设置组件保存数据

// entity的一个组件
type Money struct {
	// 该字段必须导出(首字母大写)
	// 使用struct tag来标记该字段需要存数据库,可以设置存储字段名(proto格式存mongo时,使用全小写格式)
	Data *pb.Money `db:"money"`
}
//entity.SaveDb()会自动把Money.Data保存到mongo,保存时会自动进行proto序列化
//entity.SaveCache()会自动把Money.Data缓存到redis,保存时会自动进行proto序列化

支持明文方式保存数据

// 玩家基础信息组件
type BaseInfo struct {
	// plain表示明文存储,在保存到mongodb时,不会进行proto序列化
	Data *pb.BaseInfo `db:"baseinfo;plain"`
}

支持组合模式

// 任务组件
type Quest struct {
	// 保存数据的子模块:已完成的任务
	Finished *FinishedQuests `child:"finished"`
	// 保存数据的子模块:当前任务列表
	Quests *CurQuests `child:"quests"`
}
// 已完成的任务
type FinishedQuests struct {
    BaseDirtyMark
    // 明文保存
    Finished []int32 `db:"finished;plain"`
}
// 当前任务列表
type CurQuests struct {
    BaseMapDirtyMark
    // protobuf方式保存
    Quests map[int32]*pb.QuestData `db:"quests"`
}

消息回调

支持自动注册消息回调

// 客户端发给服务器的完成任务的消息回调
// 这种格式写的函数可以自动注册客户端消息回调
func (this *Quest) OnFinishQuestReq(reqCmd gnet.PacketCommand, req *pb.FinishQuestReq) {
	// logic code ...
}
// 这种格式写的函数可以自动注册非客户端的消息回调
func (this *BaseInfo) HandlePlayerEntryGameOk(cmd gnet.PacketCommand, msg *pb.PlayerEntryGameOk) { 
	// logic code ...
}

独立协程实体RoutineEntity

每个RoutineEntity分配一个独立的逻辑协程,在自己的独立协程中执行只涉及自身数据的代码,无需加锁

同时,RoutineEntity内置了一个协程安全的计时器

routine entity

示例:gserver 里的玩家对象Player

分布式实体DistributedEntity

分布式实体DistributedEntity在RoutineEntity的基础上增加了数据库加载接口,分布式锁接口,消息路由接口

示例:gserver 里的公会对象Guild

distributed entity

服务器自动组网

服务器注册,发现,组网

项目演示

分布式游戏服务器框架gserver

讨论

QQ群: 764912827

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AutoRegisterComponentHandler added in v0.2.0

func AutoRegisterComponentHandler(entity Entity, packetHandlerRegister gnet.PacketHandlerRegister, clientHandlerPrefix, otherHandlerPrefix, protoPackageName string)

根据proto的命名规则和组件里消息回调的格式,通过反射自动生成消息的注册 类似Java的注解功能 游戏常见有2类消息 1.客户端的请求消息 可以在组件里编写函数: OnXxx(cmd PacketCommand, req *pb.Xxx) 2.服务器内部的逻辑消息 可以在组件里编写函数: HandleXxx(cmd PacketCommand, req *pb.Xxx)

按照这种格式编写的函数,调用AutoRegisterComponentHandler,可以自动注册

func ConvertInterfaceToRealType

func ConvertInterfaceToRealType(typ reflect.Type, v interface{}) interface{}

interface{} -> int or string or proto.Message

func ConvertProtoToMap

func ConvertProtoToMap(protoMessage proto.Message) map[string]interface{}

proto.Message -> map[string]interface{}

func ConvertStringToRealType added in v1.1.2

func ConvertStringToRealType(typ reflect.Type, v string) interface{}

func ConvertValueToInt

func ConvertValueToInt(srcType reflect.Type, v reflect.Value) int64

reflect.Value -> int

func ConvertValueToInterface

func ConvertValueToInterface(srcType, dstType reflect.Type, v reflect.Value) interface{}

reflect.Value -> interface{}

func FixEntityDataFromCache

func FixEntityDataFromCache(entity Entity, db EntityDb, kvCache KvCache, cacheKeyPrefix string, entityKey interface{})

根据缓存数据,修复数据 如:服务器crash时,缓存数据没来得及保存到数据库,服务器重启后读取缓存中的数据,保存到数据库,防止数据回档

func GetChildCacheKey

func GetChildCacheKey(parentName, childName string) string

func GetComponentSaveData

func GetComponentSaveData(component Component) (interface{}, error)

获取组件的保存数据

func GetEntityComponentCacheKey

func GetEntityComponentCacheKey(prefix string, entityId interface{}, componentName string) string

获取对象组件的缓存key

func GetEntityComponentChildCacheKey

func GetEntityComponentChildCacheKey(prefix string, entityId interface{}, componentName string, childName string) string

获取对象组件子对象的缓存key

func GetEntitySaveData

func GetEntitySaveData(entity Entity, componentDatas map[string]interface{})

获取实体需要保存到数据库的完整数据

func GetLogger added in v0.2.0

func GetLogger() gnet.Logger

func GetSaveData

func GetSaveData(obj interface{}, parentName string) (interface{}, error)

获取对象的保存数据

func IsDuplicateKeyError

func IsDuplicateKeyError(err error) bool

检查是否是key重复错误

func IsRedisError

func IsRedisError(redisError error) bool

检查redis返回的error是否是异常

func LoadData

func LoadData(obj interface{}, sourceData interface{}) error

加载数据 反序列化

func LoadFromCache

func LoadFromCache(obj interface{}, kvCache KvCache, cacheKey string) (bool, error)

从缓存中恢复数据

func LogStack added in v0.2.0

func LogStack()

func ProcessComponentHandler added in v0.2.0

func ProcessComponentHandler(entity Entity, cmd gnet.PacketCommand, message proto.Message) bool

执行注册的消息回调接口 return true表示执行了接口 return false表示未执行

func RegisterProtoCodeGen added in v0.2.0

func RegisterProtoCodeGen(packetHandlerRegister gnet.PacketHandlerRegister, componentName string, cmd gnet.PacketCommand, protoMessage proto.Message, handler func(c Component, m proto.Message))

用于proto_code_gen工具自动生成的消息注册代码

func SaveChangedDataToCache

func SaveChangedDataToCache(kvCache KvCache, obj interface{}, cacheKeyName string)

把修改数据保存到缓存

func SaveComponentChangedDataToCache

func SaveComponentChangedDataToCache(kvCache KvCache, cacheKeyPrefix string, entityKey interface{}, component Component)

把组件的修改数据保存到缓存

func SaveEntityChangedDataToDb

func SaveEntityChangedDataToDb(entityDb EntityDb, entity Entity, kvCache KvCache, removeCacheAfterSaveDb bool, cachePrefix string) error

Entity的变化数据保存到数据库

key为entity.GetId()

func SaveEntityChangedDataToDbByKey added in v1.1.0

func SaveEntityChangedDataToDbByKey(entityDb EntityDb, entity Entity, entityKey interface{}, kvCache KvCache, removeCacheAfterSaveDb bool, cachePrefix string) error

Entity的变化数据保存到数据库

指定key

func SetApplication added in v0.3.0

func SetApplication(application Application)

func SetLogger

func SetLogger(log gnet.Logger)

设置日志接口

Types

type Application added in v0.3.0

type Application interface {

	// 进程的唯一id
	GetId() int32

	GetContext() context.Context

	GetWaitGroup() *sync.WaitGroup

	// 初始化
	Init(ctx context.Context, configFile string) bool

	// 运行
	Run(ctx context.Context)

	// 定时更新
	OnUpdate(ctx context.Context, updateCount int64)

	// 退出
	Exit()
}

进程接口

func GetApplication added in v0.3.0

func GetApplication() Application

type ApplicationHook added in v0.3.0

type ApplicationHook interface {
	OnApplicationInit(initArg interface{})
	OnApplicationExit()
}

Application回调接口

type BaseComponent

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

func NewBaseComponent added in v0.2.0

func NewBaseComponent(entity Entity, name string) *BaseComponent

func (*BaseComponent) GetEntity

func (this *BaseComponent) GetEntity() Entity

func (*BaseComponent) GetName

func (this *BaseComponent) GetName() string

组件名

func (*BaseComponent) GetNameLower

func (this *BaseComponent) GetNameLower() string

func (*BaseComponent) SetEntity

func (this *BaseComponent) SetEntity(entity Entity)

type BaseDirtyMark

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

func (*BaseDirtyMark) IsChanged

func (this *BaseDirtyMark) IsChanged() bool

数据是否改变过

func (*BaseDirtyMark) IsDirty

func (this *BaseDirtyMark) IsDirty() bool

func (*BaseDirtyMark) ResetChanged

func (this *BaseDirtyMark) ResetChanged()

func (*BaseDirtyMark) ResetDirty

func (this *BaseDirtyMark) ResetDirty()

func (*BaseDirtyMark) SetDirty

func (this *BaseDirtyMark) SetDirty()

type BaseEntity

type BaseEntity struct {
	// Entity唯一id
	Id int64
	// contains filtered or unexported fields
}

func (*BaseEntity) AddComponent

func (this *BaseEntity) AddComponent(component Component, sourceData interface{})

func (*BaseEntity) FireEvent added in v0.2.0

func (this *BaseEntity) FireEvent(event interface{})

分发事件

func (*BaseEntity) GetComponentByIndex

func (this *BaseEntity) GetComponentByIndex(componentIndex int) Component

func (*BaseEntity) GetComponentByName

func (this *BaseEntity) GetComponentByName(componentName string) Component

获取组件

func (*BaseEntity) GetComponents

func (this *BaseEntity) GetComponents() []Component

组件列表

func (*BaseEntity) GetId added in v0.2.0

func (this *BaseEntity) GetId() int64

Entity唯一id

func (*BaseEntity) RangeComponent

func (this *BaseEntity) RangeComponent(fun func(component Component) bool)

func (*BaseEntity) SaveCache

func (this *BaseEntity) SaveCache(kvCache KvCache, cacheKeyPrefix string, entityKey interface{}) error

type BaseMapDirtyMark

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

func (*BaseMapDirtyMark) HasCached

func (this *BaseMapDirtyMark) HasCached() bool

func (*BaseMapDirtyMark) IsChanged

func (this *BaseMapDirtyMark) IsChanged() bool

func (*BaseMapDirtyMark) IsDirty

func (this *BaseMapDirtyMark) IsDirty() bool

func (*BaseMapDirtyMark) RangeDirtyMap

func (this *BaseMapDirtyMark) RangeDirtyMap(f func(dirtyKey interface{}, isAddOrUpdate bool))

func (*BaseMapDirtyMark) ResetChanged

func (this *BaseMapDirtyMark) ResetChanged()

func (*BaseMapDirtyMark) ResetDirty

func (this *BaseMapDirtyMark) ResetDirty()

func (*BaseMapDirtyMark) SetCached

func (this *BaseMapDirtyMark) SetCached()

func (*BaseMapDirtyMark) SetDirty

func (this *BaseMapDirtyMark) SetDirty(k interface{}, isAddOrUpdate bool)

type BaseRoutineEntity added in v0.3.0

type BaseRoutineEntity struct {
	BaseEntity
	// contains filtered or unexported fields
}

独立协程的实体

func NewRoutineEntity added in v0.2.0

func NewRoutineEntity(messageChanLen int) *BaseRoutineEntity

func (*BaseRoutineEntity) GetTimerEntries added in v0.3.0

func (this *BaseRoutineEntity) GetTimerEntries() *TimerEntries

func (*BaseRoutineEntity) PushMessage added in v0.3.0

func (this *BaseRoutineEntity) PushMessage(message interface{})

push a message 将会在RoutineEntity的独立协程中被调用

func (*BaseRoutineEntity) RunProcessRoutine added in v0.3.0

func (this *BaseRoutineEntity) RunProcessRoutine(routineEntity RoutineEntity, routineArgs *RoutineEntityRoutineArgs) bool

开启消息处理协程 每个RoutineEntity一个独立的消息处理协程

func (*BaseRoutineEntity) Stop added in v0.3.0

func (this *BaseRoutineEntity) Stop()

停止协程

type BaseServerList added in v0.3.0

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

func NewBaseServerList added in v0.3.0

func NewBaseServerList() *BaseServerList

func (*BaseServerList) AddListUpdateHook added in v0.3.0

func (this *BaseServerList) AddListUpdateHook(onListUpdateFunc ...func(serverList map[string][]ServerInfo, oldServerList map[string][]ServerInfo))

添加服务器列表更新回调

func (*BaseServerList) ConnectServer added in v0.3.0

func (this *BaseServerList) ConnectServer(ctx context.Context, info ServerInfo)

连接其他服务器

func (*BaseServerList) FindAndConnectServers added in v0.3.0

func (this *BaseServerList) FindAndConnectServers(ctx context.Context)

服务发现: 读取服务器列表信息,并连接这些服务器

func (*BaseServerList) GetLocalServerInfo added in v0.3.0

func (this *BaseServerList) GetLocalServerInfo() ServerInfo

自己的服务器信息

func (*BaseServerList) GetServerConnector added in v0.3.0

func (this *BaseServerList) GetServerConnector(serverId int32) gnet.Connection

获取服务器的连接

func (*BaseServerList) GetServerInfo added in v0.3.0

func (this *BaseServerList) GetServerInfo(serverId int32) ServerInfo

获取某个服务器的信息

func (*BaseServerList) GetServersByType added in v0.3.0

func (this *BaseServerList) GetServersByType(serverType string) []ServerInfo

获取某类服务器的信息列表

func (*BaseServerList) OnServerConnectorDisconnect added in v0.3.0

func (this *BaseServerList) OnServerConnectorDisconnect(serverId int32)

服务器连接断开了

func (*BaseServerList) RegisterLocalServerInfo added in v0.3.0

func (this *BaseServerList) RegisterLocalServerInfo()

服务注册:上传本地服务器的信息

func (*BaseServerList) Send added in v0.3.0

func (this *BaseServerList) Send(serverId int32, cmd gnet.PacketCommand, message proto.Message) bool

发消息给另一个服务器

func (*BaseServerList) SendPacket added in v0.5.2

func (this *BaseServerList) SendPacket(serverId int32, packet gnet.Packet) bool

func (*BaseServerList) SetCache added in v0.3.0

func (this *BaseServerList) SetCache(cache KvCache)

func (*BaseServerList) SetFetchAndConnectServerTypes added in v0.3.0

func (this *BaseServerList) SetFetchAndConnectServerTypes(serverTypes ...string)

设置要获取并连接的服务器类型

func (*BaseServerList) SetFetchServerTypes added in v0.3.0

func (this *BaseServerList) SetFetchServerTypes(serverTypes ...string)

设置要获取的服务器类型

func (*BaseServerList) SetLocalServerInfo added in v0.3.0

func (this *BaseServerList) SetLocalServerInfo(info ServerInfo)

func (*BaseServerList) SetServerConnectorFunc added in v0.3.0

func (this *BaseServerList) SetServerConnectorFunc(connectFunc func(ctx context.Context, info ServerInfo) gnet.Connection)

设置服务器连接创建函数

func (*BaseServerList) SetServerInfoFunc added in v0.3.0

func (this *BaseServerList) SetServerInfoFunc(serverInfoUnmarshal func(bytes []byte) ServerInfo,
	serverInfoMarshal func(info ServerInfo) []byte)

设置ServerInfo的序列化接口

type Component

type Component interface {
	// 组件名
	GetName() string
	GetNameLower() string

	// 所属的实体
	GetEntity() Entity
	SetEntity(entity Entity)
}

实体组件接口

type ComponentHandlerInfo added in v0.2.0

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

组件回调接口信息

type DataComponent

type DataComponent struct {
	BaseComponent
	BaseDirtyMark
}

func NewDataComponent

func NewDataComponent(entity Entity, componentName string) *DataComponent

type DbMgr

type DbMgr interface {
	GetEntityDb(name string) EntityDb
	GetKvDb(name string) KvDb
}

数据表管理接口

type DirtyMark

type DirtyMark interface {
	// 需要保存的数据是否修改了
	IsDirty() bool
	// 设置数据修改标记
	SetDirty()
	// 重置标记
	ResetDirty()
}

保存数据作为一个整体,只要一个字段修改了,整个数据都需要缓存

type DistributedEntityHelper added in v0.4.0

type DistributedEntityHelper interface {
	// 加载数据,创建实体
	LoadEntity(entityId int64) RoutineEntity
	// 创建实体
	CreateEntity(entityData interface{}) RoutineEntity
	// 根据entityId路由到目标服务器
	// 返回值:服务器id
	RouteServerId(entityId int64) int32
	// 消息转换成RoutineEntity的逻辑消息
	PacketToRoutineMessage(from Entity, packet gnet.Packet, to RoutineEntity) interface{}
	// 消息转换成路由消息
	PacketToRoutePacket(from Entity, packet gnet.Packet, toEntityId int64) gnet.Packet
	// 路由消息转换成RoutineEntity的逻辑消息
	RoutePacketToRoutineMessage(packet gnet.Packet, toEntityId int64) interface{}
}

DistributedEntity的回调接口

type DistributedEntityMgr added in v0.3.0

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

分布式实体管理类

func NewDistributedEntityMgr added in v0.3.0

func NewDistributedEntityMgr(distributedLockName string,
	entityDb EntityDb,
	cache KvCache,
	serverList ServerList,
	routineArgs *RoutineEntityRoutineArgs,
	distributedEntityHelper DistributedEntityHelper) *DistributedEntityMgr

func (*DistributedEntityMgr) DeleteDistributeLocks added in v0.3.0

func (this *DistributedEntityMgr) DeleteDistributeLocks()

删除跟本服关联的分布式锁

func (*DistributedEntityMgr) DistributeLock added in v0.3.0

func (this *DistributedEntityMgr) DistributeLock(entityId int64) bool

分布式锁Lock redis实现的分布式锁,保证同一个实体的逻辑处理协程只会在一个服务器上

func (*DistributedEntityMgr) DistributeUnlock added in v0.3.0

func (this *DistributedEntityMgr) DistributeUnlock(entityId int64)

分布式锁UnLock

func (*DistributedEntityMgr) GetEntity added in v0.3.0

func (this *DistributedEntityMgr) GetEntity(entityId int64) RoutineEntity

获取已加载的分布式实体

func (*DistributedEntityMgr) GetEntityDb added in v0.3.0

func (this *DistributedEntityMgr) GetEntityDb() EntityDb

数据库接口

func (*DistributedEntityMgr) LoadEntity added in v0.3.0

func (this *DistributedEntityMgr) LoadEntity(entityId int64, entityData interface{}) RoutineEntity

加载分布式实体 加载成功后,开启独立协程

func (*DistributedEntityMgr) ParseRoutePacket added in v0.3.0

func (this *DistributedEntityMgr) ParseRoutePacket(toEntityId int64, packet gnet.Packet)

处理另一个服务器转发过来的路由消息 解析出实际的消息,放入目标实体的消息队列中

func (*DistributedEntityMgr) Range added in v0.3.0

func (this *DistributedEntityMgr) Range(f func(entity RoutineEntity) bool)

遍历

func (*DistributedEntityMgr) ReBalance added in v0.3.0

func (this *DistributedEntityMgr) ReBalance()

重新平衡 通知已不属于本服务器管理的实体关闭协程

func (*DistributedEntityMgr) RoutePacket added in v0.3.0

func (this *DistributedEntityMgr) RoutePacket(from Entity, toEntityId int64, packet gnet.Packet) bool

路由消息 如果目标实体在本服务器上,则调用RoutineEntity.PushMessage 如果目标实体不在本服务器上,则根据路由规则查找其所在服务器,并封装路由消息发给目标服务器

func (*DistributedEntityMgr) SetLoadEntityWhenGetNil added in v0.3.0

func (this *DistributedEntityMgr) SetLoadEntityWhenGetNil(loadEntityWhenGetNil bool)

GetEntity()==nil时,去加载实体数据

func (*DistributedEntityMgr) StopAll added in v0.3.0

func (this *DistributedEntityMgr) StopAll()

关闭所有实体协程

type Entity

type Entity interface {
	// 唯一id
	GetId() int64

	// 查找某个组件
	GetComponentByName(componentName string) Component

	// 遍历组件
	RangeComponent(fun func(component Component) bool)
}

实体接口

type EntityDb

type EntityDb interface {
	// 根据id查找数据
	FindEntityById(entityKey interface{}, data interface{}) (bool, error)

	// 新建Entity(insert)
	InsertEntity(entityKey interface{}, entityData interface{}) (err error, isDuplicateKey bool)

	// 保存Entity数据(update entity by entityKey)
	SaveEntity(entityKey interface{}, entityData interface{}) error

	// 保存1个组件(update entity's component)
	SaveComponent(entityKey interface{}, componentName string, componentData interface{}) error

	// 批量保存组件(update entity's components...)
	SaveComponents(entityKey interface{}, components map[string]interface{}) error

	// 保存1个组件的一个字段(update entity's component.field)
	SaveComponentField(entityKey interface{}, componentName string, fieldName string, fieldData interface{}) error

	// 删除1个组件的某些字段
	DeleteComponentField(entityKey interface{}, componentName string, fieldName ...string) error
}

Entity的数据库接口

type EventReceiver

type EventReceiver interface {
	OnEvent(event interface{})
}

事件接口

type KvCache

type KvCache interface {
	// redis Get
	Get(key string) (string, error)

	// redis Set
	// value如果是proto.Message,会先进行序列化
	Set(key string, value interface{}, expiration time.Duration) error

	// redis SetNX
	// value如果是proto.Message,会先进行序列化
	SetNX(key string, value interface{}, expiration time.Duration) (bool, error)

	// redis Del
	Del(key ...string) (int64, error)

	// redis Type
	Type(key string) (string, error)

	// 缓存数据加载到map
	// m必须是一个类型明确有效的map,且key类型只能是int或string,value类型只能是int或string或proto.Message
	//
	// example:
	//   testDataMap := make(map[int64]*pb.TestData)
	//   HGetAll("myhash", testDataMap)
	GetMap(key string, m interface{}) error

	// map数据缓存
	// m必须是一个类型明确有效的map,且key类型只能是int或string,value类型只能是int或string或proto.Message
	// NOTE:批量写入数据,并不会删除之前缓存的数据
	//
	// example:
	//   - SetMap("myhash", map[int64]*pb.TestData{1:&pb.TestData{},2:&pb.TestData{}})
	//   - SetMap("myhash", map[string]interface{}{"key1": "value1", "key2": "value2"})
	SetMap(key string, m interface{}) error

	// redis HGetAll
	HGetAll(key string) (map[string]string, error)

	// redis HSet
	// HSet accepts values in following formats:
	//   - HSet("myhash", "key1", "value1", "key2", "value2")
	//   - HSet("myhash", []string{"key1", "value1", "key2", "value2"})
	//   - HSet("myhash", map[string]interface{}{"key1": "value1", "key2": "value2"})
	HSet(key string, values ...interface{}) (int64, error)

	// redis HSetNX
	HSetNX(key, field string, value interface{}) (bool, error)

	// 删除map的项
	HDel(key string, fields ...string) (int64, error)

	// 缓存数据加载到proto.Message
	GetProto(key string, value proto.Message) error
}

常用的kv缓存接口

type KvDb

type KvDb interface {
	Find(key interface{}) (interface{}, error)

	FindAndDecode(key interface{}, decodeData interface{}) error

	Insert(key interface{}, value interface{}) (err error, isDuplicateKey bool)

	Update(key interface{}, value interface{}, upsert bool) error

	Inc(key interface{}, value interface{}, upsert bool) (interface{}, error)

	Delete(key interface{}) error
}

Kv数据接口 游戏应用里,除了账号数据和玩家数据之外,其他以Key-Value存储的数据 KvDb接口是为了应用层能够灵活的更换存储数据库(mysql,mongo,redis等)

type MapDataComponent

type MapDataComponent struct {
	BaseComponent
	BaseMapDirtyMark
}

func NewMapDataComponent

func NewMapDataComponent(entity Entity, componentName string) *MapDataComponent

type MapDirtyMark

type MapDirtyMark interface {
	// 需要保存的数据是否修改了
	IsDirty() bool
	// 设置数据修改标记
	SetDirty(k interface{}, isAddOrUpdate bool)
	// 重置标记
	ResetDirty()

	// 是否把整体数据缓存过了
	HasCached() bool
	// 第一次有数据修改时,会把整体数据缓存一次,之后只保存修改过的项(增量更新)
	SetCached()

	RangeDirtyMap(f func(dirtyKey interface{}, isAddOrUpdate bool))
}

map格式的保存数据 第一次有数据修改时,会把整体数据缓存一次,之后只保存修改过的项(增量更新)

type MongoCollection

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

db.EntityDb的mongo实现

func (*MongoCollection) CreateIndex added in v0.5.0

func (this *MongoCollection) CreateIndex(key string, unique bool)

func (*MongoCollection) DeleteComponentField

func (this *MongoCollection) DeleteComponentField(entityKey interface{}, componentName string, fieldName ...string) error

删除1个组件的某些字段

func (*MongoCollection) FindEntityById

func (this *MongoCollection) FindEntityById(entityKey interface{}, data interface{}) (bool, error)

根据id查找数据

func (*MongoCollection) GetCollection

func (this *MongoCollection) GetCollection() *mongo.Collection

func (*MongoCollection) InsertEntity

func (this *MongoCollection) InsertEntity(entityKey interface{}, entityData interface{}) (err error, isDuplicateKey bool)

func (*MongoCollection) SaveComponent

func (this *MongoCollection) SaveComponent(entityKey interface{}, componentName string, componentData interface{}) error

func (*MongoCollection) SaveComponentField

func (this *MongoCollection) SaveComponentField(entityKey interface{}, componentName string, fieldName string, fieldData interface{}) error

func (*MongoCollection) SaveComponents

func (this *MongoCollection) SaveComponents(entityKey interface{}, components map[string]interface{}) error

func (*MongoCollection) SaveEntity

func (this *MongoCollection) SaveEntity(entityKey interface{}, entityData interface{}) error

func (*MongoCollection) ShardCollection added in v0.5.0

func (this *MongoCollection) ShardCollection(hashedShardKey bool) error

设置分片key

type MongoCollectionPlayer

type MongoCollectionPlayer struct {
	MongoCollection
	// contains filtered or unexported fields
}

db.PlayerDb的mongo实现

func (*MongoCollectionPlayer) FindAccountIdByPlayerId

func (this *MongoCollectionPlayer) FindAccountIdByPlayerId(playerId int64) (int64, error)

func (*MongoCollectionPlayer) FindPlayerByAccountId

func (this *MongoCollectionPlayer) FindPlayerByAccountId(accountId int64, regionId int32, playerData interface{}) (bool, error)

根据账号id查找玩家数据 适用于一个账号在一个区服只有一个玩家角色的游戏

func (*MongoCollectionPlayer) FindPlayerIdByAccountId

func (this *MongoCollectionPlayer) FindPlayerIdByAccountId(accountId int64, regionId int32) (int64, error)

func (*MongoCollectionPlayer) FindPlayerIdsByAccountId added in v0.2.0

func (this *MongoCollectionPlayer) FindPlayerIdsByAccountId(accountId int64, regionId int32) ([]int64, error)

type MongoDb

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

db.DbMgr的mongo实现

func NewMongoDb

func NewMongoDb(uri, dbName string) *MongoDb

func (*MongoDb) Connect

func (this *MongoDb) Connect() bool

func (*MongoDb) Disconnect

func (this *MongoDb) Disconnect()

func (*MongoDb) GetEntityDb

func (this *MongoDb) GetEntityDb(name string) EntityDb

func (*MongoDb) GetKvDb added in v0.4.0

func (this *MongoDb) GetKvDb(name string) KvDb

func (*MongoDb) GetMongoClient added in v0.5.0

func (this *MongoDb) GetMongoClient() *mongo.Client

func (*MongoDb) GetMongoDatabase

func (this *MongoDb) GetMongoDatabase() *mongo.Database

func (*MongoDb) RegisterEntityDb

func (this *MongoDb) RegisterEntityDb(collectionName string, uniqueId string) EntityDb

注册普通Entity对应的collection

func (*MongoDb) RegisterKvDb added in v0.4.0

func (this *MongoDb) RegisterKvDb(collectionName, keyName, valueName string) KvDb

func (*MongoDb) RegisterPlayerDb added in v0.4.0

func (this *MongoDb) RegisterPlayerDb(collectionName string, playerId, accountId, region string) PlayerDb

注册玩家对应的collection

func (*MongoDb) ShardCollection added in v0.5.0

func (this *MongoDb) ShardCollection(collectionFullName, keyName string, hashedShardKey bool) error

设置database分片

func (*MongoDb) ShardDatabase added in v0.5.0

func (this *MongoDb) ShardDatabase(dbName string) error

设置database分片

type MongoKvDb added in v0.4.0

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

KvDb的mongo实现

func (*MongoKvDb) Delete added in v0.4.0

func (this *MongoKvDb) Delete(key interface{}) error

func (*MongoKvDb) Find added in v0.4.0

func (this *MongoKvDb) Find(key interface{}) (interface{}, error)

func (*MongoKvDb) FindAndDecode added in v0.4.0

func (this *MongoKvDb) FindAndDecode(key interface{}, decodeData interface{}) error

func (*MongoKvDb) GetCollection added in v0.4.0

func (this *MongoKvDb) GetCollection() *mongo.Collection

func (*MongoKvDb) Inc added in v0.4.0

func (this *MongoKvDb) Inc(key interface{}, value interface{}, upsert bool) (interface{}, error)

func (*MongoKvDb) Insert added in v0.4.0

func (this *MongoKvDb) Insert(key interface{}, value interface{}) (err error, isDuplicateKey bool)

func (*MongoKvDb) Update added in v0.4.0

func (this *MongoKvDb) Update(key interface{}, value interface{}, upsert bool) error

type Player added in v0.2.0

type Player interface {
	Entity

	// 玩家名
	GetName() string

	// 账号id
	GetAccountId() int64

	// 区服id
	GetRegionId() int32

	Send(command gnet.PacketCommand, message proto.Message) bool
}

type PlayerDb

type PlayerDb interface {
	EntityDb

	// 根据账号id查找角色id
	// 适用于一个账号在一个区服只有一个玩家角色的游戏
	FindPlayerIdByAccountId(accountId int64, regionId int32) (int64, error)

	// MMORPG类型的游戏,可能一个账号在一个服有多个角色
	FindPlayerIdsByAccountId(accountId int64, regionId int32) ([]int64, error)

	// 根据账号id查找玩家数据
	// 适用于一个账号在一个区服只有一个玩家角色的游戏
	FindPlayerByAccountId(accountId int64, regionId int32, playerData interface{}) (bool, error)

	// 根据角色id查找账号id
	FindAccountIdByPlayerId(playerId int64) (int64, error)
}

玩家数据接口 Db接口是为了应用层能够灵活的更换存储数据库(mysql,mongo,redis等)

type PlayerMgr added in v0.2.0

type PlayerMgr interface {
	GetPlayer(playerId int64) Player
	AddPlayer(player Player)
	RemovePlayer(player Player)
}

type RedisCache

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

KvCache的redis实现

func NewRedisCache

func NewRedisCache(redisClient redis.Cmdable) *RedisCache

func (*RedisCache) Del

func (this *RedisCache) Del(key ...string) (int64, error)

func (*RedisCache) Get

func (this *RedisCache) Get(key string) (string, error)

func (*RedisCache) GetMap

func (this *RedisCache) GetMap(key string, m interface{}) error

redis hash -> map

func (*RedisCache) GetProto

func (this *RedisCache) GetProto(key string, value proto.Message) error

func (*RedisCache) HDel added in v0.3.1

func (this *RedisCache) HDel(key string, fields ...string) (int64, error)

func (*RedisCache) HGetAll added in v0.3.1

func (this *RedisCache) HGetAll(key string) (map[string]string, error)

func (*RedisCache) HSet added in v0.3.1

func (this *RedisCache) HSet(key string, values ...interface{}) (int64, error)

func (*RedisCache) HSetNX added in v0.3.1

func (this *RedisCache) HSetNX(key, field string, value interface{}) (bool, error)

func (*RedisCache) Set

func (this *RedisCache) Set(key string, value interface{}, expiration time.Duration) error

func (*RedisCache) SetMap

func (this *RedisCache) SetMap(k string, m interface{}) error

map -> redis hash

func (*RedisCache) SetNX added in v0.3.1

func (this *RedisCache) SetNX(key string, value interface{}, expiration time.Duration) (bool, error)

func (*RedisCache) Type

func (this *RedisCache) Type(key string) (string, error)

type RoutineEntity added in v0.2.0

type RoutineEntity interface {
	Entity

	// push a message
	// 将会在RoutineEntity的独立协程中被调用
	PushMessage(message interface{})

	// 开启消息处理协程
	// 每个RoutineEntity一个独立的消息处理协程
	RunProcessRoutine(routineEntity RoutineEntity, routineArgs *RoutineEntityRoutineArgs) bool

	// 停止协程
	Stop()
}

独立协程的实体接口

type RoutineEntityRoutineArgs added in v0.2.0

type RoutineEntityRoutineArgs struct {
	// 初始化,返回false时,协程不会启动
	InitFunc func(routineEntity RoutineEntity) bool
	// 消息处理函数
	ProcessMessageFunc func(routineEntity RoutineEntity, message interface{})
	// 有计时函数执行后调用
	AfterTimerExecuteFunc func(routineEntity RoutineEntity, t time.Time)
	// 协程结束时调用
	EndFunc func(routineEntity RoutineEntity)
}

RoutineEntity协程参数

type Saveable

type Saveable interface {
	// 数据是否改变过
	IsChanged() bool

	// 重置
	ResetChanged()
}

保存数据的接口 用于检查数据是否修改过

type SaveableDirtyMark

type SaveableDirtyMark interface {
	Saveable
	DirtyMark
}

同时需要保存数据库和缓存的接口 Saveable:

保存数据库的频率低,比如玩家下线时才会保存数据库,那么Saveable只会在上线期间记录有没有改变过就可以

DirtyMark:

缓存的保存频率高,比如玩家每一次操作都可能引起缓存的更新

type SaveableField

type SaveableField struct {
	StructField reflect.StructField
	FieldIndex  int
	// 是否明文保存
	IsPlain bool
	// 保存的字段名
	Name string
}

字段

type SaveableStruct

type SaveableStruct struct {
	// 单个db字段
	Field *SaveableField
	// 多个child字段
	Children []*SaveableField
}

有需要保存字段的结构

func GetSaveableStruct

func GetSaveableStruct(reflectType reflect.Type) *SaveableStruct

获取对象的结构描述 如果缓存过,则直接从缓存中获取

func (*SaveableStruct) IsSingleField

func (this *SaveableStruct) IsSingleField() bool

是否是单个db字段

type ServerInfo added in v0.3.0

type ServerInfo interface {
	GetServerId() int32
	GetServerType() string
	GetLastActiveTime() int64
}

服务器信息接口

type ServerList added in v0.3.0

type ServerList interface {
	GetServerInfo(serverId int32) ServerInfo

	// 服务发现: 读取服务器列表信息,并连接这些服务器
	FindAndConnectServers(ctx context.Context)

	// 服务注册:上传本地服务器的信息
	RegisterLocalServerInfo()

	Send(serverId int32, cmd gnet.PacketCommand, message proto.Message) bool
}

服务器列表接口

type TimerEntries

type TimerEntries struct {
	Timer *time.Timer
	// contains filtered or unexported fields
}

计时管理 参考https://github.com/robfig/cron 与cron主要用于任务计划不同,TimerEntries主要用于倒计时的管理 如果放在玩家的独立协程中使用,则倒计时的回调可以保证协程安全,使玩家的倒计时回调更简单

example:

go func() {
  defer timerEntries.Stop()
  timerEntries := NewTimerEntries()
  timerEntries.Start()
  for {
      select {
      case timeNow := <-timerEntries.TimerChan():
           timerEntries.Run(timeNow)
      case ...
      }
  }
}

func NewTimerEntries

func NewTimerEntries() *TimerEntries

func NewTimerEntriesWithArgs

func NewTimerEntriesWithArgs(nowFunc func() time.Time, minInterval time.Duration) *TimerEntries

func (*TimerEntries) AddTimer

func (this *TimerEntries) AddTimer(t time.Time, f TimerJob)

指定时间点执行回调

func (*TimerEntries) After

func (this *TimerEntries) After(d time.Duration, f TimerJob)

现在往后多少时间执行回调

func (*TimerEntries) GetMinInterval added in v0.6.1

func (this *TimerEntries) GetMinInterval() time.Duration

func (*TimerEntries) GetTimeOffset added in v0.6.1

func (this *TimerEntries) GetTimeOffset() time.Duration

func (*TimerEntries) Now added in v0.6.1

func (this *TimerEntries) Now() time.Time

func (*TimerEntries) Run

func (this *TimerEntries) Run(now time.Time) bool

func (*TimerEntries) SetMinInterval added in v0.6.1

func (this *TimerEntries) SetMinInterval(minInterval time.Duration)

func (*TimerEntries) SetTimeOffset added in v0.6.1

func (this *TimerEntries) SetTimeOffset(timeOffset time.Duration)

func (*TimerEntries) Start

func (this *TimerEntries) Start()

func (*TimerEntries) Stop

func (this *TimerEntries) Stop()

func (*TimerEntries) TimerChan

func (this *TimerEntries) TimerChan() <-chan time.Time

type TimerJob

type TimerJob func() time.Duration

倒计时回调函数 返回值:下一次执行的时间间隔,返回0表示该回调不会继续执行

Directories

Path Synopsis
pb

Jump to

Keyboard shortcuts

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