KBEngine Module
The KBEngine module provides Python script access to entities, especially for registering and removing timers, as well as creating entities.
Member Functions
def addSpaceGeometryMapping( spaceID, mapper, path, shouldLoadOnServer, params ):
def addWatcher( path, dataType, getFunction ):
def address( ):
def MemoryStream( ):
def createEntity( entityType, spaceID, position, direction, params ):
def debugTracing( ):
def delSpaceData( spaceID, key ):
def delWatcher( path ):
def deregisterReadFileDescriptor( fileDescriptor ):
def deregisterWriteFileDescriptor( fileDescriptor ):
def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):
def genUUID64( ):
def getResFullPath( res ):
def getSpaceData( spaceID, key ):
def getSpaceGeometryMapping( spaceID ):
def getWatcher( path ):
def getWatcherDir( path ):
def getAppFlags( ):
def hasRes( res ):
def isShuttingDown( ):
def listPathRes( path, extension ):
def matchPath( res ):
def open( res, mode, encoding ):
def publish( ):
def registerReadFileDescriptor( fileDescriptor, callback ):
def registerWriteFileDescriptor( fileDescriptor, callback ):
def raycast( spaceID, layer, src, dst ):
def reloadScript( fullReload ):
def scriptLogType( logType ):
def setAppFlags( flags ):
def setSpaceData( spaceID, key, value ):
def time( ):
def urlopen( url, callback, postData, headers ):
Callback Functions
def onCellAppData( key, value ):
def onCellAppDataDel( key ):
def onGlobalData( key, value ):
def onGlobalDataDel( key ):
def onInit( isReload ):
def onSpaceData( spaceID, key, value ):
def onSpaceGeometryLoaded( spaceID, mapping ):
def onAllSpaceGeometryLoaded( spaceID, isBootstrap, mapping ):
def onReadyForLogin( isBootstrap ):
Properties
globalData GlobalDataClient
Member Function Documentation
def addSpaceGeometryMapping( spaceID, mapper, path, shouldLoadOnServer, params ):
Description:
Associates a geometry mapping with a given space. After calling this function, both the server and client will load the corresponding geometry data.
On the server, all geometry data from the specified directory is loaded into the specified space. This data may be divided into many chunks, which are loaded asynchronously. When all geometry data is loaded, the following notification method will be called:
def onAllSpaceGeometryLoaded( self, spaceID, mappingName ):
On the server, only the geometry data is loaded for navigation and collision purposes. On the client, textures and other data are also loaded.
3D scenes currently use data exported by the recastnavigation plugin by default, while 2D scenes use data exported by the MapEditor by default.
There is a possibility that onAllSpaceGeometryLoaded() will not be called if multiple CellApps call this method to add geometry to the same space at the same time and CellAppMgr crashes.
Parameters:
spaceID
: uint32, the ID of the space to operate on
mapper
: Currently fill in None
path
: Directory path containing geometry data
shouldLoadOnServer
: Optional boolean parameter, specifies whether to load geometry on the server. Default is True
params
: Optional PyDict parameter, specifies which navmesh to use for different layers
Example:
KBEngine.addSpaceGeometryMapping(self.spaceID, None, resPath, True,
{0 : "srv_xinshoucun_1.navmesh", 1 : "srv_xinshoucun.navmesh"})
def addWatcher( path, dataType, getFunction ):
Description:
Interacts with the debug watcher system, allowing users to register a watch variable.
Example:
>>> def countPlayers( ):
>>> i = 0
>>> for e in KBEngine.entities.values():
>>> if e.__class__.__name__ == "Avatar":
>>> i += 1
>>> return i
>>>
>>> KBEngine.addWatcher( "players", "UINT32", countPlayers )
This function adds a watch variable under the "scripts/players" watch path. The function countPlayers is called when the watcher observes.
Parameters:
path
: Path to create the watcher.
dataType
: Value type of the watch variable. See: Basic Types
getFunction
: This function is called when the watcher retrieves the variable. It takes no arguments and returns the value of the watch variable.
def address( ):
Description:
Returns the address of the internal network interface.
def MemoryStream( ):
Description:
Returns a new MemoryStream object.
The MemoryStream object stores binary information, allowing users to conveniently serialize and deserialize Python basic types in a way consistent with KBEngine's underlying serialization rules.
For example, you can use this object to construct a network packet that KBEngine can parse.
Usage:
>>> s = KBEngine.MemoryStream()
>>> s
>>> b''
>>> s.append("UINT32", 1)
>>> s.pop("UINT32")
>>> 1
Currently, MemoryStream only supports basic data types. See: Basic Types
def createEntity( entityType, spaceID, position, direction, params ):
Description:
createEntity creates a new entity in the specified space of the current process.
This function requires specifying the type, position, and direction of the entity to be created, and optionally allows setting any entity properties (described in the entity's .def file).
Example:
# Create an open door entity at the same position as the "thing" entity
direction = ( 0, 0, thing.yaw )
properties = { "open":1 }
KBEngine.createEntity( "Door", thing.space, thing.position, direction, properties )
Parameters:
entityType
: string, the name of the entity to create, declared in res/scripts/entities.xml.
spaceID
: int32, the ID of the space to place the entity in.
position
: A sequence of 3 floats specifying the spawn point of the new entity in world coordinates.
direction
: A sequence of 3 floats specifying the initial orientation (roll, pitch, yaw) of the new entity, relative to world coordinates.
params
: Optional parameter, a Python dictionary. If a specified key is an Entity property, its value will be used to initialize the property of the Entity.
Returns:
The new entity.
def debugTracing( ):
Description:
Outputs the current count of Python extension objects being traced by KBEngine.
Extension objects include: fixed dictionaries, fixed arrays, Entity, EntityCall, etc.
If the counter is not zero when the server shuts down normally, it indicates a memory leak, and an error message will be output to the log.
ERROR cellapp \[0x0000cd64\] \[2014-11-12 00:38:07,300\] - PyGC::debugTracing(): FixedArray : leaked(128)\
ERROR cellapp \[0x0000cd64\] \[2014-11-12 00:38:07,300\] - PyGC::debugTracing(): EntityCall : leaked(8)
def delSpaceData( spaceID, key ):
Description:
Deletes the space data with the specified key (if the space is split into multiple parts, deletion will be synchronized).
Space data is set by the user via setSpaceData.
Parameters:
spaceID
: int32, the ID of the space.
key
: string, a string key.
def delWatcher( path ):
Description:
Interacts with the debug watcher system, allowing users to delete a watch variable in the script.
Parameters:
path
: Path of the variable to delete.
def deregisterReadFileDescriptor( fileDescriptor ):
Description:
Unregisters a callback previously registered via KBEngine.registerReadFileDescriptor.
Example:
http://www.kbengine.org/assets/other/py/Poller.py
Parameters:
fileDescriptor
: Socket/file descriptor.
def deregisterWriteFileDescriptor( fileDescriptor ):
Description:
Unregisters a callback previously registered via KBEngine.registerWriteFileDescriptor.
Example:
http://www.kbengine.org/assets/other/py/Poller.py
Parameters:
fileDescriptor
: Socket/file descriptor.
def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):
Description:
This script function executes a raw database command, which will be parsed directly by the relevant database.
Note that modifying entity data with this function may not take effect, because if the entity is already checked out, the modified entity data will still be overwritten by the entity's archive.
It is strongly discouraged to use this function to read or modify entity data.
Parameters:
command
: The database command, which varies depending on the database configuration. For MySQL, it is an SQL query.
callback
:
Optional parameter, a callback object (such as a function) with the command execution result. This callback takes 4 parameters: result set, affected rows, auto-increment value, error message. Sample declaration:
def sqlcallback(result, rows, insertid, error):
print(result, rows, insertid, error)
INFO
As shown above:
result
parameter corresponds to the "result set", which is a list of rows. Each row is a list of field values as strings.
If the command does not return a result set (e.g., DELETE command), or if there is an error, this parameter is None.
rows
parameter is the "number of affected rows", an integer indicating the number of rows affected by the command. This parameter is only relevant for commands that do not return a result set (such as DELETE).
If there is a result set or an error, this parameter is None.
insertid
corresponds to the "auto-increment value", similar to the entity's databaseID. When data is successfully inserted into a table with an auto-increment field, it returns the value assigned to the auto-increment field. For more information, see MySQL's mysql_insert_id() method. This parameter is only meaningful for MySQL databases.
error
corresponds to the "error message". If there is an error, this parameter is a string describing the error. If there is no error, this parameter is None.
threadID
: int32, optional parameter, specifies a thread to process this command. Users can use this parameter to control the execution order of certain commands (dbmgr processes commands in multiple threads). Default is unspecified. If threadID is the entity's ID, the command will be added to the entity's archive queue and written sequentially by the thread.
dbInterfaceName
: string, optional parameter, specifies which database interface to use. Default is the "default" interface. Database interfaces are defined in kbengine_defaults.xml->dbmgr->databaseInterfaces.
def genUUID64( ):
Description:
This function generates a 64-bit unique ID.
Note: This function depends on the Cellapps process startup parameter gus. Please set the startup parameter correctly to ensure uniqueness.
Also, if gus exceeds 65535, this function can only guarantee uniqueness within the current process.
Usage:
Generate unique item IDs across multiple service processes without conflicts during server merges.
Generate a room ID across multiple service processes without needing to check for uniqueness.
Returns:
Returns a 64-bit integer.
def getResFullPath( res ):
Description:
Gets the absolute path of a resource.
Note: The resource must be accessible under KBE_RES_PATH.
Parameters:
res
: string, returns the absolute path if it exists, otherwise returns empty.
Returns:
string, the absolute path of the resource.
def getSpaceData( spaceID, key ):
Description:
Gets the space data for the specified key.
Space data is set by the user via setSpaceData.
Parameters:
spaceID
: int32, the ID of the space.
key
: string, a string key.
Returns:
string, the string data for the specified key.
def getSpaceGeometryMapping( spaceID ):
Description:
Returns the geometry mapping name for a specified space.
Parameters:
spaceID
: The ID of the space to query.
Returns:
string, the geometry mapping name.
def getWatcher( path ):
Description:
Gets the value of a watch variable from the KBEngine debug system.
Example: In baseapp1's Python command line:
>>> KBEngine.getWatcher("/root/stats/runningTime")
12673648533
>>> KBEngine.getWatcher("/root/scripts/players")
32133
Parameters:
path
: string, the absolute path of the variable including the variable name (can be viewed in the watcher page of GUIConsole).
Returns:
The value of the variable.
def getWatcherDir( path ):
Description:
Gets a list of elements (directories, variable names) under a watch directory from the KBEngine debug system.
Example: In baseapp1's Python command line:
>>> KBEngine.getWatcher("/root")
('stats', 'objectPools', 'network', 'syspaths', 'ThreadPool',
'cprofiles', 'scripts', 'numProxices', 'componentID',
'componentType', 'uid', 'numClients', 'globalOrder',
'username', 'load', 'gametime', 'entitiesSize', 'groupOrder')
Parameters:
path
: string, the absolute path of the variable (can be viewed in the watcher page of GUIConsole).
Returns:
List of elements (directories, variable names) under the watch directory.
def getAppFlags( ):
Description:
Gets the current engine APP flags, see: KBEngine.setAppFlags.\
Returns:
KBEngine.APP_FLAGS_*.
def hasRes( res ):
Description:
Checks if a resource with a relative path exists.
Note: The resource must be accessible under KBE_RES_PATH.
Example:
>>> KBEngine.hasRes("scripts/entities.xml")
True
Parameters:
res
: string, the relative path of the resource.
Returns:
BOOL, returns True if exists, otherwise returns False.
def isShuttingDown( ):
Description:
Returns whether the server is shutting down. After the onBaseAppShuttingDown callback is called, this function returns True.
Returns:
Returns True if the system is shutting down, otherwise returns False.
def listPathRes( path, extension ):
Description:
Gets a list of resources under a resource directory.
Note: The resource must be accessible under KBE_RES_PATH.
Example:
>>> KBEngine.listPathRes("scripts/cell/interfaces")
('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py',
'/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt')
>>> KBEngine.listPathRes("scripts/cell/interfaces", "txt")
('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt')
>>> KBEngine.listPathRes("scripts/cell/interfaces", "txt|py")
('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py',
'/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt')
>>> KBEngine.listPathRes("scripts/cell/interfaces", ("txt", "py"))
('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py',
'/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt')
Parameters:
res
: string, the relative path of the resource.
extension
: string, optional parameter, file extension.
Returns:
Tuple, list of resources.
def matchPath( res ):
Description:
Gets the absolute path of a resource using its relative path.
Note: The resource must be accessible under KBE_RES_PATH.
Example:
>>> KBEngine.matchPath("scripts/entities.xml")
'/home/kbe/kbengine/demo/res/scripts/entities.xml\'
Parameters:
res
: string, the relative path of the resource (including the resource name).
Returns:
string, the absolute path of the resource.
def open( res, mode, encoding ):
Description:
Opens a resource using its relative path. Note: The resource must be accessible under KBE_RES_PATH.
Parameters:
res
: string, the relative path of the resource.
mode
: string, optional parameter, default is 'r'
File operation modes
r
open for read only
w
open for write
a
open for append (start at EOF, create new file if necessary)
r+
open for read/write
w+
open for read/write (see w)
a+
open for read/write (see a)
rb
open for binary read
wb
open for binary write (see w)
ab
open for binary append (see a)
rb+
open for binary read/write (see r+)
wb+
open for binary read/write (see w+)
ab+
open for binary read/write (see a+)
encoding
: string, optional parameter, the name of the encoding used to decode or encode the file. Default encoding is platform dependent.
def publish( ):
Description:
Returns the current server publish mode.
Returns:
int8
- 0: debug
- 1: release
- Others can be customized.
def raycast( spaceID, layer, src, dst ):
Description:
Casts a ray from the source coordinate to the destination coordinate in the specified layer of the specified space, returning the collision point(s).
Note: The space must have geometry data loaded via addSpaceGeometryMapping.
Example:
>>> KBEngine.raycast( spaceID, entity.layer, (0, 10, 0), (0,-10,0) )
((0.0000, 0.0000, 0.0000), ( (0.0000, 0.0000, 0.0000),
(4.0000, 0.0000, 0.0000), (4.0000, 0.0000, 4.0000)), 0)
Parameters:
spaceID
: int32, the id of the space.
layer
: int8, geometry layer. A space can load multiple navmesh data at the same time, each in a different layer, which can represent ground, water, etc.
Returns:
list, list of collision points.
def registerReadFileDescriptor( fileDescriptor, callback ):
Description:
Registers a callback function, which is called when the file descriptor is readable.
Example:
http://www.kbengine.org/assets/other/py/Poller.py
Parameters:
fileDescriptor
: Socket/file descriptor.
callback
: A callback function, with the socket/file descriptor as its only parameter.
def registerWriteFileDescriptor( fileDescriptor, callback ):
Description:
Registers a callback function, which is called when the socket/file descriptor is writable.
Example:
http://www.kbengine.org/assets/other/py/Poller.py
Parameters:
fileDescriptor
: Socket/file descriptor.
callback
: A callback function, with the socket/file descriptor as its only parameter.
def reloadScript( fullReload ):
Description:
Reloads Python modules related to entities and custom data types. The current entity class will be set to the newly loaded class. This method should only be used in development mode and is not suitable for production. Note the following:
Script reload can only be executed on Cellapp, users should ensure all server components are loaded.
After reloading scripts, custom types should ensure that instantiated objects in memory are also updated.
Example:
for e in KBEngine.entities.values():
if type( e ) is Avatar.Avatar:
e.customData.__class__ = CustomClass
When this method completes, KBEngine.onInit( True ) is called.
Parameters:
fullReload
: Optional boolean parameter, specifies whether to reload entity definitions as well. If False, entity definitions will not be reloaded. Default is True.
Returns:
Returns True if reload is successful, otherwise returns False.
def scriptLogType( logType ):
Description:
Sets the information type for current Python.print output (see: KBEngine.LOG_TYPE_*).
def setAppFlags( flags ):
Description:
Sets the current engine APP flags.
KBEngine.APP_FLAGS_NONE // Default (no flags set)
KBEngine.APP_FLAGS_NOT_PARTCIPATING_LOAD_BALANCING // Not participating in load balancing
Example:
KBEngine.setAppFlags(KBEngine.APP_FLAGS_NOT_PARTCIPATING_LOAD_BALANCING | KBEngine.APP_FLAGS_*)
def setSpaceData( spaceID, key, value ):
Description:
Sets the space data for the specified key.
Space data can be retrieved via getSpaceData.
Parameters:
spaceID
: int32, the ID of the space.
key
: string, a string key.
value
: string, string value.
def time( ):
Description:
Returns the current game time (tick count).
Returns:
uint32, the current game time in ticks. The tick rate is determined by the configuration file kbengine.xml or kbengine_defaults.xml->gameUpdateHertz.
def urlopen( url, callback, postData, headers ):
Description:
This script function provides asynchronous HTTP/HTTPS requests.
Parameters:
url
: Valid HTTP/HTTPS URL, string type.
callback
: Optional parameter, a callback object (such as a function) with the request result. This callback takes 5 parameters: HTTP response code (e.g., 200), response content, HTTP headers, success status, and the request URL.
Sample declaration:
def onHttpCallback(httpcode, data, headers, success, url):
print(httpcode, data, headers, success, url)
INFO
As shown above:
httpcode
: The HTTP response code, an integer.
data
: The response content, a string.
headers
: The HTTP headers returned by the server, e.g., {"Content-Type": "application/x-www-form-urlencoded"}, a dictionary.
success
: Whether the request was successful. If there was an error, this is False. You can use httpcode to further determine the error.
url
: The URL used for the request.
postData
: Optional parameter. Default is GET request. If you need to POST, provide the content to POST. The engine will automatically use POST. This is a bytes object.
headers
: Optional parameter. HTTP headers to use for the request, e.g., {"Content-Type": "application/x-www-form-urlencoded"}, a dictionary.
Callback Function Documentation
def onCellAppData( key, value ):
Description:
Called when KBEngine.cellAppData changes.
Note: This callback must be implemented in the entry module (kbengine_defaults.xml->entryScriptFile).
Parameters:
key
: The key of the changed data.
value
: The value of the changed data.
def onCellAppDataDel( key ):
Description:
Called when KBEngine.cellAppData is deleted.
Note: This callback must be implemented in the entry module (kbengine_defaults.xml->entryScriptFile).
Parameters:
key
: The key of the deleted data.
def onGlobalData( key, value ):
Description:
Called when KBEngine.globalData changes.
Note: This callback must be implemented in the entry module (kbengine_defaults.xml->entryScriptFile).
Parameters:
key
: The key of the changed data.
value
: The value of the changed data.
def onGlobalDataDel( key ):
Description:
Called when KBEngine.globalData is deleted.
Note: This callback must be implemented in the entry module (kbengine_defaults.xml->entryScriptFile).
Parameters:
key
: The key of the deleted data.
def onInit( isReload ):
Description:
Called after the engine has initialized all scripts after startup.
Note: This callback must be implemented in the entry module (kbengine_defaults.xml->entryScriptFile).
Parameters:
isReload
: bool, whether triggered by script reload.
def onSpaceData( spaceID, key, value ):
Description:
Called when space data changes.
Space data is set by the user via setSpaceData.
Parameters:
spaceID
: The ID of the space.
key
: The key of the changed data.
value
: The value of the changed data.
def onSpaceGeometryLoaded( spaceID, mapping ):
Description:
Called when the required mesh collision and other data for the space is loaded.
Set by the user via addSpaceGeometryMapping.
Parameters:
spaceID
: The ID of the space.
mapping
: The mapping value of the mesh collision data.
def onAllSpaceGeometryLoaded( spaceID, isBootstrap, mapping ):
Description:
Called when all required mesh collision and other data for the space is loaded.
Set by the user via addSpaceGeometryMapping.
Parameters:
spaceID
: The ID of the space.
isBootstrap
: If a space is divided and loaded by multiple cells, isBootstrap indicates whether this is the cell that initiated the load request.
mapping
: The mapping value of the mesh collision data.
def onReadyForLogin( isBootstrap ):
Description:
After the engine starts and initializes, this interface is called repeatedly to ask the script layer if it is ready. If the script layer is ready, loginapp allows clients to log in.
Note: This callback must be implemented in the entry module (kbengine_defaults.xml->entryScriptFile).
Parameters:
isBootstrap
: bool, whether this is the first started Cellapp.
Returns:
If the return value is greater than or equal to 1.0, the script layer is ready. Otherwise, return the progress value 0.0~1.0.
Property Documentation
LOG_TYPE_DBG
Description:
Log output type is debug.
Set by scriptLogType.
LOG_TYPE_ERR
Description:
Log output type is error.
Set by scriptLogType.
LOG_TYPE_INFO
Description:
Log output type is info.
Set by scriptLogType.
LOG_TYPE_NORMAL
Description:
Log output type is normal.
Set by scriptLogType.
LOG_TYPE_WAR
Description:
Log output type is warning.
Set by scriptLogType.
NEXT_ONLY
Description:
This constant is currently unused in Cellapp.
cellAppData
Description:
This property contains a dictionary-like object that is automatically synchronized among all CellApps. When a value in the dictionary is modified, the change is broadcast to all CellApps.
Example:
KBEngine.cellAppData[ "hello" ] = "there"
Other CellApps can access:
print KBEngine.cellAppData[ "hello" ]
Keys and values can be any type, but these types must be serializable and deserializable on all target components.
When a value is changed or deleted, a callback function is called on all components. See: KBEngine.onCellAppData and KBEngine.onDelCellAppData.
Note: Only top-level values are broadcast. If you have a value (such as a list) and change an internal value (such as just changing a number), this information will not be broadcast.
Do not do the following:
KBEngine.cellAppData[ "list" ] = [1, 2, 3]
KBEngine.cellAppData[ "list" ][1] = 7
Locally, this is [1, 7, 3], but remotely it is [1, 2, 3].
component
Description:
This is the component currently running in the Python environment. (So far) possible values are 'cellapp', 'baseapp', 'client', 'dbmgr', 'bots', and 'editor'.
entities
Description:
entities is a dictionary containing all entities in the current process, including ghost entities.
Debugging leaked entities (entities that have called destroy but have not been released, usually due to references preventing release):\
>>> KBEngine.entities.garbages.items()
[(1025, Avatar object at 0x7f92431ceae8.)]
>>> e = _[0][1]
>>> import gc
>>> gc.get_referents(e)
[{'spacesIsOk': True, 'bootstrapIdx': 1}, class 'Avatar.Avatar'>]
Debugging leaked KBEngine-wrapped Python objects:
KBEngine.debugTracing
Type:
globalData
Description:
This property contains a dictionary-like object that is automatically replicated among all BaseApps and CellApps. When a value in the dictionary is modified, the change is broadcast to all BaseApps and CellApps. CellAppMgr resolves race conditions to ensure authoritative replication.
Example:
KBEngine.globalData[ "hello" ] = "there"
Other Cellapp or Baseapp can access:
print KBEngine.globalData[ "hello" ]
Keys and values can be any type, but these types must be serializable and deserializable on all target components.
When a value is changed or deleted, a callback function is called on all components. See: KBEngine.onGlobalData and KBEngine.onGlobalDataDel.
Note: Only top-level values are broadcast. If you have a mutable value (such as a list) and change an internal value (such as just changing a number), this information will not be broadcast.
Do not do the following:
KBEngine.globalData[ "list" ] = [1, 2, 3]
KBEngine.globalData[ "list" ][1] = 7
Locally, this is [1, 7, 3], but remotely it is [1, 2, 3].