channeld

package
v0.7.3 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2024 License: Apache-2.0 Imports: 38 Imported by: 7

Documentation

Index

Constants

View Source
const (
	ConnectionState_UNAUTHENTICATED int32 = 0
	ConnectionState_AUTHENTICATED   int32 = 1
	ConnectionState_CLOSING         int32 = 2
)
View Source
const (
	MinY = -3.40282347e+38 / 2
	MaxY = 3.40282347e+38 / 2
)
View Source
const (
	GlobalChannelId common.ChannelId = 0
)
View Source
const MaxPacketSize int = 0x00ffff
View Source
const (
	MaxUpdateMsgBufferSize = 512
)
View Source
const PacketHeaderSize int = 5

Variables

View Source
var (
	ErrNoneAccess                = errors.New("none can access")
	ErrOwnerOnlyAccess           = errors.New("only the channel owenr can access")
	ErrOwnerAndGlobalOwnerAccess = errors.New("only the channel owenr or global channel owner can access")
	ErrIllegalAccessLevel        = errors.New("illegal channel access level")
)
View Source
var ErrEntityChannelFull = errors.New("entity channels are full")
View Source
var ErrNonSpatialChannelFull = errors.New("non-spatial channels are full")
View Source
var ErrSpatialChannelFull = errors.New("spatial channels are full")
View Source
var Event_AuthComplete = &Event[AuthEventData]{}
View Source
var Event_ChannelCreated = &Event[*Channel]{}
View Source
var Event_ChannelRemoved = &Event[common.ChannelId]{}
View Source
var Event_ChannelRemoving = &Event[*Channel]{}
View Source
var Event_FsmDisallowed = &Event[*Connection]{}
View Source
var Event_GlobalChannelPossessed = &Event[*Channel]{}
View Source
var Event_GlobalChannelUnpossessed = &Event[struct{}]{}
View Source
var GlobalSettings = GlobalSettingsType{
	LogLevel:              &NullableInt{},
	LogFile:               &NullableString{},
	ServerReadBufferSize:  0x0001ffff,
	ServerWriteBufferSize: 256,
	ServerFSM:             "config/server_authoratative_fsm.json",
	ClientReadBufferSize:  0x0001ffff,
	ClientWriteBufferSize: 512,
	ClientFSM:             "config/client_non_authoratative_fsm.json",
	CompressionType:       channeldpb.CompressionType_NO_COMPRESSION,

	MaxConnectionIdBits:     31,
	ConnectionAuthTimeoutMs: 5000,
	MaxFailedAuthAttempts:   5,
	MaxFsmDisallowed:        10,
	SpatialChannelIdStart:   0x00010000,
	EntityChannelIdStart:    0x00080000,
	ChannelSettings: map[channeldpb.ChannelType]ChannelSettingsType{
		channeldpb.ChannelType_GLOBAL: {
			TickIntervalMs:                 10,
			DefaultFanOutIntervalMs:        20,
			DefaultFanOutDelayMs:           0,
			RemoveChannelAfterOwnerRemoved: false,
		},
	},
}
View Source
var MessageMap = map[channeldpb.MessageType]*messageMapEntry{
	channeldpb.MessageType_AUTH:                {&channeldpb.AuthMessage{}, handleAuth},
	channeldpb.MessageType_CREATE_CHANNEL:      {&channeldpb.CreateChannelMessage{}, handleCreateChannel},
	channeldpb.MessageType_REMOVE_CHANNEL:      {&channeldpb.RemoveChannelMessage{}, handleRemoveChannel},
	channeldpb.MessageType_LIST_CHANNEL:        {&channeldpb.ListChannelMessage{}, handleListChannel},
	channeldpb.MessageType_SUB_TO_CHANNEL:      {&channeldpb.SubscribedToChannelMessage{}, handleSubToChannel},
	channeldpb.MessageType_UNSUB_FROM_CHANNEL:  {&channeldpb.UnsubscribedFromChannelMessage{}, handleUnsubFromChannel},
	channeldpb.MessageType_CHANNEL_DATA_UPDATE: {&channeldpb.ChannelDataUpdateMessage{}, handleChannelDataUpdate},
	channeldpb.MessageType_DISCONNECT:          {&channeldpb.DisconnectMessage{}, handleDisconnect},

	channeldpb.MessageType_CREATE_SPATIAL_CHANNEL:    {&channeldpb.CreateChannelMessage{}, handleCreateChannel},
	channeldpb.MessageType_QUERY_SPATIAL_CHANNEL:     {&channeldpb.QuerySpatialChannelMessage{}, handleQuerySpatialChannel},
	channeldpb.MessageType_DEBUG_GET_SPATIAL_REGIONS: {&channeldpb.DebugGetSpatialRegionsMessage{}, handleGetSpatialRegionsMessage},
	channeldpb.MessageType_UPDATE_SPATIAL_INTEREST:   {&channeldpb.UpdateSpatialInterestMessage{}, handleUpdateSpatialInterest},
	channeldpb.MessageType_CREATE_ENTITY_CHANNEL:     {&channeldpb.CreateEntityChannelMessage{}, handleCreateEntityChannel},
	channeldpb.MessageType_ENTITY_GROUP_ADD:          {&channeldpb.AddEntityGroupMessage{}, handleAddEntityGroup},
	channeldpb.MessageType_ENTITY_GROUP_REMOVE:       {&channeldpb.RemoveEntityGroupMessage{}, handleRemoveEntityGroup},
}

Functions

func CopyArray added in v0.6.0

func CopyArray[FROM UintId, TO UintId](arr []FROM) []TO

func Difference

func Difference[K comparable, V any](thisMap map[K]V, otherMap map[K]V) map[K]V

Returns a map of all the keys in thisMap that are not in otherMap

func GetIP

func GetIP(addr net.Addr) string

func GetNextId

func GetNextId(m *map[uint32]interface{}, start uint32, min uint32, max uint32) (uint32, bool)

func GetNextIdSync

func GetNextIdSync(m *sync.Map, start common.ChannelId, min common.ChannelId, max common.ChannelId) (common.ChannelId, bool)

func GetNextIdTyped added in v0.6.0

func GetNextIdTyped[K UintId, V any](m MapRead[K, V], start K, min K, max K) (K, bool)

func HandleServerToClientUserMessage

func HandleServerToClientUserMessage(ctx MessageContext)

func HashString

func HashString(s string) uint32

func InitAntiDDoS

func InitAntiDDoS()

func InitChannels

func InitChannels()

func InitConnections

func InitConnections(serverFsmPath string, clientFsmPath string)

func InitLogs

func InitLogs()

func InitMetrics

func InitMetrics()

func InitSpatialController

func InitSpatialController()

func Pointer

func Pointer[K any](val K) *K

func ReflectChannelDataMessage

func ReflectChannelDataMessage(channelType channeldpb.ChannelType) (common.ChannelDataMessage, error)

func ReflectMerge

Use protoreflect to merge. No need to write custom merge code but less efficient.

func RegisterChannelDataType

func RegisterChannelDataType(channelType channeldpb.ChannelType, msgTemplate proto.Message)

Register a Protobuf message template as the channel data of a specific channel type. This is needed when channeld doesn't know the package of the message is in, as well as creating a ChannelData using ReflectChannelData()

func RegisterMessageHandler

func RegisterMessageHandler(msgType uint32, msg common.Message, handler MessageHandlerFunc)

func RemoveChannel

func RemoveChannel(ch *Channel)

func SetAuthProvider

func SetAuthProvider(value AuthProvider)

func SetLogLevel added in v0.7.0

func SetLogLevel(level zapcore.Level)

func SetWebSocketTrustedOrigins

func SetWebSocketTrustedOrigins(addrs []string)

func StartListening

func StartListening(t channeldpb.ConnectionType, network string, address string)

func StartProfiling

func StartProfiling()

func UintIdHasher added in v0.6.0

func UintIdHasher[T UintId]() func(maphash.Seed, T) uint64

Types

type ACLSettingsType

type ACLSettingsType struct {
	Sub    ChannelAccessLevel
	Unsub  ChannelAccessLevel
	Remove ChannelAccessLevel
}

type AlwaysFailAuthProvider

type AlwaysFailAuthProvider struct{}

Always return AuthResultMessage_INVALID_LT

func (*AlwaysFailAuthProvider) DoAuth

type AuthEventData added in v0.6.0

type AuthEventData struct {
	AuthResult            channeldpb.AuthResultMessage_AuthResult
	Connection            ConnectionInChannel
	PlayerIdentifierToken string
}

type AuthProvider

type AuthProvider interface {
	DoAuth(connId ConnectionId, pit string, lt string) (channeldpb.AuthResultMessage_AuthResult, error)
}

type Channel

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

func CreateChannel

func CreateChannel(t channeldpb.ChannelType, owner ConnectionInChannel) (*Channel, error)

Go-routine safe - should only be called in the GLOBAL channel

func GetChannel

func GetChannel(id common.ChannelId) *Channel

func (*Channel) Broadcast

func (ch *Channel) Broadcast(ctx MessageContext)

func (*Channel) CheckACL

func (ch *Channel) CheckACL(c ConnectionInChannel, accessType ChannelAccessType) (bool, error)

func (*Channel) Data

func (ch *Channel) Data() *ChannelData

func (*Channel) Execute added in v0.6.0

func (ch *Channel) Execute(callback func(ch *Channel))

Runs a function in the channel's go-routine. Any code that modifies the channel's data outside the the channel's go-routine should be run in this way.

func (*Channel) GetAllConnections

func (ch *Channel) GetAllConnections() map[ConnectionInChannel]struct{}

Goroutine-safe read of the subscribed connections

func (*Channel) GetDataMessage

func (ch *Channel) GetDataMessage() common.ChannelDataMessage

CAUTION: this function is not goroutine-safe. Read/write to the channel data message should be done in the the channel's goroutine.

func (*Channel) GetHandoverEntities added in v0.6.0

func (ch *Channel) GetHandoverEntities(notifyingEntityId EntityId) map[EntityId]common.Message

func (*Channel) GetOwner added in v0.7.0

func (c *Channel) GetOwner() ConnectionInChannel

func (*Channel) GetTime

func (ch *Channel) GetTime() ChannelTime

func (*Channel) HasOwner

func (ch *Channel) HasOwner() bool

func (*Channel) Id added in v0.6.0

func (ch *Channel) Id() common.ChannelId

func (*Channel) InitData

func (ch *Channel) InitData(dataMsg common.ChannelDataMessage, mergeOptions *channeldpb.ChannelDataMergeOptions)

func (*Channel) IsRemoving

func (ch *Channel) IsRemoving() bool

func (*Channel) IsSameOwner

func (chA *Channel) IsSameOwner(chB *Channel) bool

func (*Channel) Logger

func (ch *Channel) Logger() *Logger

func (*Channel) PutMessage

func (ch *Channel) PutMessage(msg common.Message, handler MessageHandlerFunc, conn *Connection, pack *channeldpb.MessagePack)

func (*Channel) PutMessageContext

func (ch *Channel) PutMessageContext(ctx MessageContext, handler MessageHandlerFunc)

func (*Channel) PutMessageInternal added in v0.6.0

func (ch *Channel) PutMessageInternal(msgType channeldpb.MessageType, msg common.Message)

Put the message into the channel's message queue. This method is used internally to make sure the message is handled in the channel's goroutine, to avoid race condition.

For the MessageContext, the Connection is set as the channel's ownerConnection, and the ChannelId is set as the channel's id.

func (*Channel) SendMessageToOwner added in v0.7.0

func (ch *Channel) SendMessageToOwner(msgType uint32, msg common.Message) bool

func (*Channel) SendToOwner

func (ch *Channel) SendToOwner(ctx MessageContext) bool

func (*Channel) SetDataUpdateConnId

func (ch *Channel) SetDataUpdateConnId(connId ConnectionId)

func (*Channel) SetOwner added in v0.7.0

func (c *Channel) SetOwner(conn ConnectionInChannel)

func (*Channel) String

func (ch *Channel) String() string

func (*Channel) Tick

func (ch *Channel) Tick()

func (*Channel) Type added in v0.6.0

func (ch *Channel) Type() channeldpb.ChannelType

type ChannelAccessLevel

type ChannelAccessLevel uint8
const (
	ChannelAccessLevel_None                ChannelAccessLevel = 0
	ChannelAccessLevel_OwnerOnly           ChannelAccessLevel = 1
	ChannelAccessLevel_OwnerAndGlobalOwner ChannelAccessLevel = 2
	ChannelAccessLevel_Any                 ChannelAccessLevel = 3
)

type ChannelAccessType

type ChannelAccessType uint8
const (
	ChannelAccessType_Sub    ChannelAccessType = 0
	ChannelAccessType_Unsub  ChannelAccessType = 1
	ChannelAccessType_Remove ChannelAccessType = 2
)

type ChannelData

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

func (*ChannelData) OnUpdate

func (d *ChannelData) OnUpdate(updateMsg common.ChannelDataMessage, t ChannelTime, senderConnId ConnectionId, spatialNotifier common.SpatialInfoChangedNotifier)

type ChannelDataInitializer

type ChannelDataInitializer interface {
	common.Message
	Init() error
}

Indicate that the channel data message should be initialized with default values.

type ChannelSettingsType

type ChannelSettingsType struct {
	TickIntervalMs                 uint
	DefaultFanOutIntervalMs        uint32
	DefaultFanOutDelayMs           int32
	RemoveChannelAfterOwnerRemoved bool
	ACLSettings                    ACLSettingsType
	// Optinal. The full name of the Protobuf message type for the channel data (including the package name)
	DataMsgFullName string
}

type ChannelState

type ChannelState uint8
const (
	ChannelState_INIT     ChannelState = 0
	ChannelState_OPEN     ChannelState = 1
	ChannelState_HANDOVER ChannelState = 2
)

type ChannelSubscription

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

type ChannelTime

type ChannelTime int64 // time.Duration

ChannelTime is the relative time since the channel created.

func (ChannelTime) AddMs

func (t ChannelTime) AddMs(ms uint32) ChannelTime

func (ChannelTime) OffsetMs

func (t ChannelTime) OffsetMs(ms int32) ChannelTime

type Connection

type Connection struct {
	ConnectionInChannel
	// contains filtered or unexported fields
}

func AddConnection

func AddConnection(c net.Conn, t channeldpb.ConnectionType) *Connection

NOT goroutine-safe. NEVER call AddConnection in different goroutines.

func GetConnection

func GetConnection(id ConnectionId) *Connection

func (*Connection) AddCloseHandler

func (c *Connection) AddCloseHandler(handlerFunc func())

func (*Connection) Close

func (c *Connection) Close()

func (*Connection) Disconnect

func (c *Connection) Disconnect() error

func (*Connection) GetConnectionType

func (c *Connection) GetConnectionType() channeldpb.ConnectionType

func (*Connection) HasAuthorityOver

func (c *Connection) HasAuthorityOver(ch *Channel) bool

Return true if the connection can 1)remove; 2)sub/unsub another connection to/from; the channel.

func (*Connection) HasInterestIn added in v0.6.0

func (c *Connection) HasInterestIn(spatialChId common.ChannelId) bool

func (*Connection) Id

func (c *Connection) Id() ConnectionId

func (*Connection) IsClosing

func (c *Connection) IsClosing() bool

func (*Connection) IsNil

func (c *Connection) IsNil() bool

Implementation for ConnectionInChannel interface

func (*Connection) Logger

func (c *Connection) Logger() *Logger

func (*Connection) OnAuthenticated

func (c *Connection) OnAuthenticated(pit string)

func (*Connection) RemoteAddr

func (c *Connection) RemoteAddr() net.Addr

func (*Connection) Send

func (c *Connection) Send(ctx MessageContext)

func (*Connection) String

func (c *Connection) String() string

func (*Connection) SubscribeToChannel

func (c *Connection) SubscribeToChannel(ch *Channel, options *channeldpb.ChannelSubscriptionOptions) (*ChannelSubscription, bool)

Returns the subscription instance if successfully subscribed, and true if subscription message should be sent.

func (*Connection) UnsubscribeFromChannel

func (c *Connection) UnsubscribeFromChannel(ch *Channel) (*channeldpb.ChannelSubscriptionOptions, error)

type ConnectionId

type ConnectionId uint32

type ConnectionInChannel

type ConnectionInChannel interface {
	Id() ConnectionId
	GetConnectionType() channeldpb.ConnectionType
	OnAuthenticated(pit string)
	HasAuthorityOver(ch *Channel) bool
	Close()
	IsClosing() bool
	Send(ctx MessageContext)
	// Returns the subscription instance if successfully subscribed, and true if subscription message should be sent.
	SubscribeToChannel(ch *Channel, options *channeldpb.ChannelSubscriptionOptions) (*ChannelSubscription, bool)
	UnsubscribeFromChannel(ch *Channel) (*channeldpb.ChannelSubscriptionOptions, error)

	HasInterestIn(spatialChId common.ChannelId) bool
	Logger() *Logger
	RemoteAddr() net.Addr
	// contains filtered or unexported methods
}

Use this interface instead of Connection for protecting the connection from unsafe writing in the channel goroutine.

type EntityGroup added in v0.6.0

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

func (*EntityGroup) Add added in v0.6.0

func (g *EntityGroup) Add(groupToAdd *EntityGroup)

type EntityGroupController added in v0.6.0

type EntityGroupController interface {
	Initialize(ch *Channel)
	Uninitialize(ch *Channel)

	AddToGroup(t channeldpb.EntityGroupType, entitiesToAdd []EntityId) error
	RemoveFromGroup(t channeldpb.EntityGroupType, entitiesToRemove []EntityId) error
	GetHandoverEntities() []EntityId
	// contains filtered or unexported methods
}

type EntityId added in v0.6.0

type EntityId uint32

type Event

type Event[T EventData] struct {
	// contains filtered or unexported fields
}

func (*Event[T]) Broadcast

func (e *Event[T]) Broadcast(data T)

func (*Event[T]) Listen

func (e *Event[T]) Listen(handlerFunc func(data T))

func (*Event[T]) ListenFor added in v0.6.0

func (e *Event[T]) ListenFor(owner interface{}, handlerFunc func(data T))

func (*Event[T]) ListenOnce

func (e *Event[T]) ListenOnce(handlerFunc func(data T))

func (*Event[T]) UnlistenFor added in v0.6.0

func (e *Event[T]) UnlistenFor(owner interface{})

func (*Event[T]) Wait

func (e *Event[T]) Wait() chan T

type EventData

type EventData interface {
}

type FixedPasswordAuthProvider

type FixedPasswordAuthProvider struct {
	Password string
}

func (*FixedPasswordAuthProvider) DoAuth

type FlatEntityGroupController added in v0.6.0

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

FlatEntityGroupController is a simple implementation of EntityGroupController which has only one layer of handover and lock group. Adding an entities in a group to another group will overwrite the previous group and the overwrite is not revertible.

func (*FlatEntityGroupController) AddToGroup added in v0.6.0

func (ctl *FlatEntityGroupController) AddToGroup(t channeldpb.EntityGroupType, entitiesToAdd []EntityId) error

func (*FlatEntityGroupController) GetHandoverEntities added in v0.6.0

func (ctl *FlatEntityGroupController) GetHandoverEntities() []EntityId

func (*FlatEntityGroupController) Initialize added in v0.6.0

func (ctl *FlatEntityGroupController) Initialize(ch *Channel)

func (*FlatEntityGroupController) RemoveFromGroup added in v0.6.0

func (ctl *FlatEntityGroupController) RemoveFromGroup(t channeldpb.EntityGroupType, entitiesToRemove []EntityId) error

func (*FlatEntityGroupController) Uninitialize added in v0.6.0

func (ctl *FlatEntityGroupController) Uninitialize(ch *Channel)

type GlobalSettingsType

type GlobalSettingsType struct {
	Development   bool
	LogLevel      *NullableInt // zapcore.Level
	LogFile       *NullableString
	ProfileOption func(*profile.Profile)
	ProfilePath   string

	ServerNetwork         string
	ServerAddress         string
	ServerReadBufferSize  int
	ServerWriteBufferSize int
	ServerFSM             string
	ServerBypassAuth      bool

	ClientNetworkWaitMasterServer bool
	ClientNetwork                 string
	ClientAddress                 string
	ClientReadBufferSize          int
	ClientWriteBufferSize         int
	ClientFSM                     string

	CompressionType channeldpb.CompressionType

	MaxConnectionIdBits uint8

	ConnectionAuthTimeoutMs int64
	MaxFailedAuthAttempts   int
	MaxFsmDisallowed        int

	SpatialControllerConfig NullableString
	SpatialChannelIdStart   common.ChannelId
	EntityChannelIdStart    common.ChannelId

	ChannelSettings map[channeldpb.ChannelType]ChannelSettingsType

	EnableRecordPacket bool

	ReplaySessionPersistenceDir string
}

func (GlobalSettingsType) GetChannelSettings

func (*GlobalSettingsType) ParseFlag

func (s *GlobalSettingsType) ParseFlag() error

type HandoverDataMerger added in v0.6.0

type HandoverDataMerger interface {
	// Entity channel data merges itself to the spatial channel data for handover.
	// If fullData is true, merge the full entity data into the spatial channel data; otherwise, merge the entity identifier only.
	MergeTo(spatialChannelData common.Message, fullData bool) error
}

type HandoverDataWithPayload

type HandoverDataWithPayload interface {
	// Clear the payload of the handover data so it won't be send to the connection that don't have the interest
	ClearPayload()
}

type LocalhostAddr

type LocalhostAddr struct {
	NetworkName string
}

func (*LocalhostAddr) Addr

func (addr *LocalhostAddr) Addr() string

func (*LocalhostAddr) Network

func (addr *LocalhostAddr) Network() string

type LogLevel

type LogLevel zapcore.Level
const TraceLevel LogLevel = -4
const VerboseLevel LogLevel = -2
const VeryVerboseLevel LogLevel = -3

type Logger

type Logger struct {
	*zap.Logger
}

func RootLogger

func RootLogger() *Logger

func (*Logger) Trace

func (logger *Logger) Trace(msg string, fields ...zap.Field)

func (*Logger) Verbose

func (logger *Logger) Verbose(msg string, fields ...zap.Field)

func (*Logger) VeryVerbose

func (logger *Logger) VeryVerbose(msg string, fields ...zap.Field)

type LoggingAuthProvider

type LoggingAuthProvider struct {
	Logger *zap.Logger
	Msg    string
}

Do nothing but logging

func (*LoggingAuthProvider) DoAuth

type MapRead added in v0.6.0

type MapRead[K comparable, V any] interface {
	Load(key K) (value V, ok bool)
}

type MergeableChannelData

type MergeableChannelData interface {
	common.Message
	Merge(src common.ChannelDataMessage, options *channeldpb.ChannelDataMergeOptions, spatialNotifier common.SpatialInfoChangedNotifier) error
}

Implement this interface to manually merge the channel data. In most cases it can be MUCH more efficient than the default reflection-based merge.

type MessageContext

type MessageContext struct {
	MsgType channeldpb.MessageType
	// The weak-typed Message object popped from the message queue
	Msg       common.Message
	Broadcast uint32 //channeldpb.BroadcastType
	StubId    uint32
	// The original channelId in the Packet, could be different from Channel.id.
	// Used for both send and receive.
	ChannelId uint32

	// The connection that received the message. Required for BroadcastType_ALL_BUT_SENDER but not for sending.
	Connection ConnectionInChannel
	// The channel that handling the message. Not required for sending or broadcasting.
	Channel *Channel
	// contains filtered or unexported fields
}

The context of a message for both sending and receiving

func (*MessageContext) HasConnection

func (ctx *MessageContext) HasConnection() bool

type MessageHandlerFunc

type MessageHandlerFunc func(ctx MessageContext)

type MessageSender

type MessageSender interface {
	Send(c *Connection, ctx MessageContext) //(c *Connection, channelId ChannelId, msgType channeldpb.MessageType, msg Message)
}

Add an interface before the underlying network layer for the test purpose.

type NullableInt

type NullableInt struct {
	Value    int
	HasValue bool
}

func (*NullableInt) Set

func (i *NullableInt) Set(s string) error

func (NullableInt) String

func (i NullableInt) String() string

type NullableString

type NullableString struct {
	Value    string
	HasValue bool
}

func (*NullableString) Set

func (ns *NullableString) Set(s string) error

func (NullableString) String

func (ns NullableString) String() string

type RemovableMapField

type RemovableMapField interface {
	GetRemoved() bool
}

type SpatialChannelEntityUpdater added in v0.6.0

type SpatialChannelEntityUpdater interface {
	AddEntity(EntityId, common.Message) error
	RemoveEntity(EntityId) error
}

Spatial channel data shoud implement this interface to support entity spawn, destory, and handover

type SpatialController

type SpatialController interface {
	// Initialize the spatial controller parameters from the json config file.
	LoadConfig(config []byte) error
	// Notify() is called in the spatial channels (shared instance)
	common.SpatialInfoChangedNotifier
	// Called in GLOBAL and spatial channels
	GetChannelId(info common.SpatialInfo) (common.ChannelId, error)
	// Called in the spatial channels
	QueryChannelIds(query *channeldpb.SpatialInterestQuery) (map[common.ChannelId]uint, error)
	// Called in GLOBAL channel
	GetRegions() ([]*channeldpb.SpatialRegion, error)
	// Called in the spatial channels
	GetAdjacentChannels(spatialChannelId common.ChannelId) ([]common.ChannelId, error)
	// Create spatial channels for a spatial server.
	// Called in GLOBAL channel
	CreateChannels(ctx MessageContext) ([]*Channel, error)
	// Called in GLOBAL channel
	Tick()
}

func GetSpatialController

func GetSpatialController() SpatialController

type SpatialDampingSettings

type SpatialDampingSettings struct {
	MaxDistance      uint
	FanOutIntervalMs uint32
	DataFieldMasks   []string
}

type StaticGrid2DSpatialController

type StaticGrid2DSpatialController struct {
	SpatialController

	/* Defines how the world is divided into grids */
	// The width of a grid in simulation/engine units
	GridWidth float64
	// The heights of a grid in the simulation/engine units
	GridHeight float64
	// How many grids the world has in X axis. The width of the world = GridWidth x GridCols.
	GridCols uint32
	// How many grids the world has in Z axis. The height of the world = GridHeight x GridRows.
	GridRows uint32

	// In the left-handed coordinate system, the difference between the world origin and the bottom-left corner of the first grid, in the simulation/engine units.
	// This is how we uses the offset value to calculate which grid a (x,z) point is in: gridX = Floor((x - OffsetX) / GridWidth), gridY = Floor((y - OffsetY) / GridHeight)
	// If the world origin is exactly in the middle of the world, the offset should be (-WorldWidth*0.5, -WorldHeight*0.5).
	WorldOffsetX float64
	WorldOffsetZ float64

	/* Defines the authority area of a spatial server, as well as the number of the servers (= ServerCols * ServerRows) */
	// How many servers the world has in X axis.
	ServerCols uint32
	// How many servers the world has in Z axis.
	ServerRows uint32

	/* Defines the extra interest area a spatial server has, adjacent to the authority area */
	// For each side of a server's grids (authority area), how many grids(spatial channels) the server subscribes to, as the extend of its interest area.
	// For example, ServerInterestBorderSize = 1 means a spatial server of 3x3 grids has interest area of 4x4 grids.
	// Remarks: the value should always be less than the size of the authority area (=Min(GridCols/ServerCols, GridRows/ServerRows))
	ServerInterestBorderSize uint32
	// contains filtered or unexported fields
}

Divide the world into GridCols x GridRows static squares on the XZ plane. Each square(grid) represents a spatial channel. Typically, a player's view distance is 150m, so a grid is sized at 50x50m. A 100x100 km world has 2000x2000 grids, which needs about 2^22 spatial channels. By default, we support up to 2^32-2^16 grid-based spatial channels.

func (*StaticGrid2DSpatialController) CreateChannels

func (ctl *StaticGrid2DSpatialController) CreateChannels(ctx MessageContext) ([]*Channel, error)

func (*StaticGrid2DSpatialController) GetAdjacentChannels

func (ctl *StaticGrid2DSpatialController) GetAdjacentChannels(spatialChannelId common.ChannelId) ([]common.ChannelId, error)

func (*StaticGrid2DSpatialController) GetChannelId

func (*StaticGrid2DSpatialController) GetChannelIdNoOffset

func (ctl *StaticGrid2DSpatialController) GetChannelIdNoOffset(info common.SpatialInfo) (common.ChannelId, error)

func (*StaticGrid2DSpatialController) GetChannelIdWithOffset

func (ctl *StaticGrid2DSpatialController) GetChannelIdWithOffset(info common.SpatialInfo, offsetX float64, offsetZ float64) (common.ChannelId, error)

func (*StaticGrid2DSpatialController) GetRegions

func (*StaticGrid2DSpatialController) GridSize

func (ctl *StaticGrid2DSpatialController) GridSize() float64

func (*StaticGrid2DSpatialController) LoadConfig

func (ctl *StaticGrid2DSpatialController) LoadConfig(config []byte) error

func (*StaticGrid2DSpatialController) Notify

func (ctl *StaticGrid2DSpatialController) Notify(oldInfo common.SpatialInfo, newInfo common.SpatialInfo, handoverDataProvider func(common.ChannelId, common.ChannelId, interface{}))

Runs in the source spatial(V1)/entity(V2) channel (shared instance)

func (*StaticGrid2DSpatialController) QueryChannelIds

func (*StaticGrid2DSpatialController) Tick

func (ctl *StaticGrid2DSpatialController) Tick()

func (*StaticGrid2DSpatialController) WorldHeight

func (ctl *StaticGrid2DSpatialController) WorldHeight() float64

func (*StaticGrid2DSpatialController) WorldWidth

func (ctl *StaticGrid2DSpatialController) WorldWidth() float64

type UintId added in v0.6.0

type UintId interface {
	common.ChannelId | ConnectionId | EntityId | uint32
}

Jump to

Keyboard shortcuts

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