KBEngine - Getting Started

KBEngine

什么是KBEngine?

一款开源的游戏服务端引擎，客户端通过简单的约定协议就能与服务端通讯， 使用KBEngine插件能够快速与(Unity3D, OGRE, Cocos2d-x, HTML5, 等等)技术结合形成一个完整的客户端。
服务端底层框架使用C++编写，游戏逻辑层使用Python(支持热更新)，开发者无需重复的实现一些游戏服务端通用的底层技术， 将精力真正集中到游戏开发层面上来，快速的打造各种网络游戏。
(经常被问到承载上限，kbengine底层架构被设计为多进程分布式动态负载均衡方案， 理论上只需要不断扩展硬件就能够不断增加承载上限，单台机器的承载上限取决于游戏逻辑本身的复杂度。)

Homepage
http://www.kbengine.org

Releases
sources : https://github.com/kbengine/kbengine/releases/latest
binarys : https://sourceforge.net/projects/kbengine/files/

Demo sources
unity3d : https://github.com/kbengine/kbengine_unity3d_demo/releases/latest
unity3d : https://github.com/kbengine/kbengine_unity3d_warring/releases/latest
ogre : https://github.com/kbengine/kbengine_ogre_demo/releases/latest
html5 : https://github.com/kbengine/kbengine_html5_demo/releases/latest

Docs
docs : http://www.kbengine.org/docs/
API : https://github.com/kbengine/kbengine/tree/master/docs

Support
Email : kbesrv@gmail.com
Maillist : https://groups.google.com/d/forum/kbengine_maillist

开始

您可以先看安装指南, 了解常用工具之后，您还可以去 GitHub加入开源力量。

相信在对KBEngine有足够的了解之后，您会喜欢她的。

想修改和完善文档?

如果您认为文档中有什么需要改变的，那么您现在就可以改变它。只需要forking kbengine_docs与发起一个pull请求。

同样，如果你发现文档中有任何不明白的地方请提交一个issue，我将会调整该文档，让更多的人能够得到更好的理解。

版权归KBEngine所有。


KBEngine - Keywords

关键词释义

EntityCall:

脚本层与实体远程交互的常规手段(其他参考：allClients、otherClients、clientEntity)。
EntityCall对象在C++底层实现非常简单，它只包含了实体的ID、目的地的地址、实体类型、EntityCall类型。当用户请求一次远程交互时，底层首先能够通过实体类型找到实体定义的描述，
通过实体定义的描述对用户输入的数据进行检查，如果检查合法那么底层将数据打包并发往目的地，目的地进程根据协议进行解包最终调用到脚本层。

注意: EntityCall只能调用其对应def文件中声明过的方法，不能访问实体的属性以及其他任何信息。

一个实体最多可以包含三个部分：
client： 当实体包括客户端部分时(通常为玩家)，在服务端可以访问实体的client(EntityCall)属性。
base：当实体的一部分创建在Baseapp时，在非当前Baseapp中可以访问实体的base(EntityCall)属性。
cell：当实体的一部分创建在Cellapp时，在非当前Cellapp中可以访问实体的cell(EntityCall)属性。

举例:

Avatar.def中定义client远程方法:
    <ClientMethods>
        <hello>
        </hello>
    </ClientMethods>

client\Avatar.py
    class Avatar:
        def hello(self):
            print("hello")

在GUIConsole工具的Debug页输入框中输入(请先在左边列表中勾选要调试的进程)：
首先在服务端Baseapp的日志找到玩家实体(Avatar)的ID, 然后通过实体ID获得玩家实体(Avatar)或者EntityCall:
>>> KBEngine.entities[玩家ID].client.hello()

此时客户端log文件中将输出"hello", 一次远程调用过程完成。

KBE_ROOT:

这是一个KBEngine的环境变量，描述的是KBEngine所在的根目录。

KBE_RES_PATH:

这是一个KBEngine的环境变量，描述的是KBEngine引擎能够读取到的资源目录。

KBE_HYBRID_PATH:

这是一个KBEngine的环境变量，描述的是KBEngine引擎可执行文件所在的目录。

entities.xml:

服务端所有有效的实体类型必须在此进行注册，引擎初始化时会根据此处依次加载实体的描述信息。

kbengine_defaults.xml:

服务端默认配置，在此用户可以修改cellapp、baseapp、loginapp等所有的组件配置。
注意：你可能经常需要对引擎进行升级，直接修改此处可能在升级时产生冲突，另外也不适合多个项目放在同一KBEngine环境的情况。
建议在kbengine.xml中进行重载修改，你只需要对想修改的部分按照格式在xml中重写就可以了。

kbengine.xml:

服务端配置，在此用户可以修改cellapp、baseapp、loginapp等所有的组件配置。

详细请参考kbengine_defaults.xml

实体

实体被定义为服务端最基本的对象，类似Python的基础对象object。
什么时候需要定义实体? 请参见http://www.kbengine.org/docs/programming/entitydef.html

entity

参见: 实体

View

每一个连接到服务器的客户端实体都将拥有一个View，View类似一种视图，让客户端能够对自身View内的事件传达给客户端。
View与空间相关，每个View都能够设定独立的大小范围。
注意：这里描述的空间是一种抽象的概念，不一定需要和物理空间概念绑定（MMORPG除外），对于一个卡牌游戏的核心玩法，也可以认为一个房间内的玩家在一个逻辑空间中。
事件包括: 实体移动、客户端广播类型的属性改变、死亡销毁等等。

Witness

目击者。
只有绑定了Witness的cell实体View才能产生作用，换句话来说witness就是客户端的一个cell代理，cellapp将View内的信息不断的通过Witness同步给客户端。
服务端一个NPC被目击者目击时会调用实体的onWitness回调，服务端可以依赖于此特性降低CPU的消耗，当一个实体
没有被目击时，用户可以停止它的任何行为。

Space

空间，KBEngine在cellapp上分配一个空间，这个空间与其他空间隔离，View、陷阱、实体碰撞等等只在当前空间相互影响。
空间具体是什么由用户来定义，它可以是一个场景、副本、房间...

空间

参见: Space

cell

cell在文档中存在二个不同的意思。
通常如果描述的是Entity.cell属性， 此时实际是在描述实体的CellEntityCall。
如果是在cellapp上有关cell的描述通常是在描述一个空间的一部分，一个空间在cellapp进行负载平衡时有可能被分割成N份，每一份称之为一个cell，每个cell由不同进程维护。

base

通常是指baseapp上的Base实体或者是一个指向Base实体的BaseEntityCall, 例如：Entity.base。

client

通常是指客户端或者是一个指向客户端实体的EntityCall, 例如：Entity.client。

cellapp

Cellapp进程主要负责与位置有关类游戏逻辑、View、AI、场景房间等等。
参见: cellapp

baseapp

Baseapp进程主要负责与客户端通讯、与位置无关类游戏逻辑(公会管理器、聊天系统、游戏大厅、排行榜等等)、存档与备份等等。
参见: baseapp

real

指的是一个cell上的实体，这个实体是真实存在于当期cell上的（有一种实体只是另一个cell广播过来的影像，参见：ghost）。

ghost

这种实体其实是由于cellapp动态负载均衡机制将一个完整的space分割成N份并交给不同的进程中的cell共同维护从而产生的一种边界区影像实体。
由于space被分割成多个区域，所以space存在边界。要让客户端无法感知到边界的存在我们将每个cell边界区域一定范围内的实体同步一份到另一个边邻的cell上，
这样就不会在边界区域时无法和另一个边界区的实体进行交互了。而这种实体只有部分数据被同步过来(CELL_PUBLIC等cell广播类型的属性)。

非ghost实体我们称为real实体。

vector3

描述和管理3D空間的向量。
其中有x，y，z三个属性代表不同的轴向。

脚本中使用的例子： import Math v = Math.Vector3()


KBEngine - Base Types

基本数据类型

[Name]			[Bytes]

UINT8			1
UINT16			2
UINT32			4
UINT64			8

INT8			1
INT16			2
INT32			4
INT64			8

FLOAT			4
DOUBLE			8

VECTOR2			12
VECTOR3			16
VECTOR4			20

STRING			N
UNICODE			N
PYTHON			N
PY_DICT			N
PY_TUPLE		N
PY_LIST			N
ENTITYCALL		N
BLOB			N


KBEngine - KBEngine client 文档

client插件

KBEngine是一个开源的游戏服务端引擎，不包含完整的客户端部分，但我们提供了能与服务端快速对接的客户端插件部分。客户端插件包含了与服务端的通讯、注册账号、登录接口、Entity基础类等等。 插件与客户端表现层之间通过一种机制进行交互，表现层获得插件的数据进行表现(例如：血量变化，实体进入View)，插件获得表现层的输入进行改变(例如：角色位置与朝向)。

KBEngine在不同的前端技术下实现了不同的客户端插件，但每种插件都遵循本API文档中列出的方法与属性，根据该文档不同的客户端插件都拥有了一个实现标准。


KBEngine - KBEngine client 文档

KBEngine模块

KBEngine模块提供了逻辑脚本层访问实体的部分, 以及当前space的数据等等。

类

Entity

成员函数

def login( username, password ):
def createAccount( username, password ):
def reloginBaseapp():
def player( ):
def resetPassword(username):
def bindAccountEmail( emailaddress ):
def newPassword( oldpassword, newpassword ):
def findEntity( entityID ):
def getSpaceData( key ):

回调函数

属性

component | 只读 string
entities | Entities
entity_uuid | uint64
entity_id | int32
spaceID | int32

成员函数文档

def login( username, password ):

功能说明：

登录账号到KBEngine服务端。
注意：如果插件与UI层使用事件交互模式，在UI层不要直接调用，请触发一个"login"事件给插件，事件附带数据username和password。

参数：
username | string，用户名。
password | string，密码。

def createAccount( username, password ):

功能说明：

请求向KBEngine服务端创建一个登录账号。
注意：如果插件与UI层使用事件交互模式，在UI层不要直接调用，请触发一个"createAccount"事件给插件，事件附带数据username和password。

参数：
username | string，用户名。
password | string，密码。

def reloginBaseapp( ):

功能说明：

请求重登录到KBEngine服务端(通常在掉线之后希望更及时的连接到服务端并继续控制服务端角色时使用)。
注意：如果插件与UI层使用事件交互模式，在UI层不要直接调用，请触发一个"reloginBaseapp"事件给插件，事件附带数据为空。

def player( ):

功能说明：

获得当前客户端所控制的实体。

返回：
Entity，返回控制的实体, 如果不存在(如：未能连接到服务端)则返回空。

def resetPassword( username ):

功能说明：

请求loginapp重置账号的密码, 服务端将会向该账号绑定的邮箱发送一封重置密码邮件(通常是忘记密码功能使用)。

参数：
username string，用户名。

def bindAccountEmail( emailaddress ):

功能说明：

请求baseapp绑定账号的email地址。

参数：
emailaddress string，邮箱地址。

def newPassword( oldpassword, newpassword ):

功能说明：

请求设置账号的新密码。

参数：
oldpassword | string，旧密码。
newpassword | string，新密码。

def findEntity( entityID ):

功能说明：

通过实体的ID查找实体的实例对象。

参数：
entityID int32，实体ID。

返回：
Entity，存在返回实体实例，不存在返回空。

def getSpaceData( key ):

功能说明：

获取指定key的space数据。
space数据由用户在服务端通过setSpaceData设置。

参数：
key string，一个字符串关键字。

返回：
string，指定key的字符串数据。

回调函数文档

属性文档

component

说明：

这是正运行在当前脚本环境的组件。（至今为止）可能值有'cell', 'base', 'client', 'database', 'bot' 和 'editor'。

entities

说明：

entities是一个字典对象，包含当前进程上所有的实体。

类型：
Entities

entity_uuid

说明：

实体的uuid，改ID与实体本次登录绑定。当使用重登陆功能时服务端会与此ID进行比对，判断合法性。

entity_id

说明：

当前客户端所控制的实体的ID。

spaceID

说明：

当前客户端控制的实体所在的空间ID(也可以理解为所在对应的场景、房间、副本)。


Entity - KBEngine client 文档

Entity类

[KBEngine模块]

Entity是KBEngine模块的一部分。 更多...

import KBEngine

成员函数

def baseCall( self, methodName, methodArgs ):
def cellCall( self, methodName, methodArgs ):

回调函数

def onDestroy( self ):
def onEnterWorld( self ):
def onLeaveWorld( self ):
def onEnterSpace( self ):
def onLeaveSpace( self ):

属性

direction | Tuple of 3 floats as (roll, pitch, yaw)
id | 只读 Integer
position | Vector3
spaceID | 只读 uint32
isOnGround | 只读 bool
inWorld | 只读 bool
className | 只读 string

详细描述

类Entity的实例代表着在client上的游戏对象。

一个Entity可以通过ENTITYCALL访问在base和cell应用程序上的等价的实体。这需要 一组远程调用的函数（在实体的.def文件里指定）。

成员函数文档

def baseCall( self, methodName, methodArgs ):

功能说明：

调用该实体的base部分的方法。
注意：实体在服务端必须有base部分，在客户端只有客户端控制的玩家实体才可以访问该方法。

例子：
js插件: entity.baseCall("reqCreateAvatar", roleType, name);
c#插件: entity.baseCall("reqCreateAvatar", new object[]{roleType, name});

参数：
methodName | string，方法名称。
methodArgs | objects，方法参数列表。

返回：
由于是远程调用，不可能阻塞等待返回，因此无返回值。

def cellCall( self, methodName, methodArgs ):

功能说明：

调用该实体的cell部分的方法。
注意：实体在服务端必须有cell部分，在客户端只有客户端控制的玩家实体才可以访问该方法。

例子：
js插件: entity.cellCall("xxx", roleType, name);
c#插件: entity.cellCall("xxx", new object[]{roleType, name});

参数：
methodName | string，方法名称。
methodArgs | objects，方法参数列表。

返回：
由于是远程调用，不可能阻塞等待返回，因此无返回值。

回调函数文档

def onDestroy( self ):

实体被销毁时调用。

def onEnterWorld( self ):

如果实体非客户端控制实体，则表明实体进入了服务端上客户端控制的实体的View范围，此时客户端可以看见这个实体了。
如果实体是客户端控制的实体则表明该实体已经在服务端创建了cell并进入了space。

def onLeaveWorld( self ):

如果实体非客户端控制实体，则表明实体离开了服务端上客户端控制的实体的View范围，此时客户端看不见这个实体了。
如果实体是客户端控制的实体则表明该实体已经在服务端销毁了cell并离开了space。

def onEnterSpace( self ):

客户端控制的实体进入了一个新的space。

def onLeaveSpace( self ):

客户端控制的实体离开了当前的space。

属性文档

className

实体的类名。

类型：
只读，string

position

这个实体在世界空间中的坐标(x, y, z)，数据由服务端同步到客户端。

类型：
Vector3

direction

这个属性描述的是Entity在世界空间中的朝向，数据由服务端同步到客户端。

类型：
Vector3, 其中包含(roll, pitch, yaw)，以弧度表示。

isOnGround

如果这个属性的值为True，Entity在地面上，否则为False。
如果是客户端控制的实体该属性将会在改变时同步到服务端，其他实体则由服务端同步到客户端，客户端可以判断这个值来强制贴地避免精度带来的影响。

类型：
可读写， bool


KBEngine - KBEngine cellapp 文档

Cellapp进程

Cellapp进程主要负责与空间位置有关类游戏逻辑，提供将不同Baseapp上的玩家聚合在一个空间中实时交互的功能，Cellapp上通常可实现场景、NPC/怪物、战斗、关卡房间相关逻辑。


KBEngine - KBEngine cell 文档

KBEngine模块

KBEngine模块提供了Python脚本访问实体的部分，特别是它提供了定时器的注册与移除， 以及实体的创建。

类

Entity

成员函数

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 ):
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 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 ):

属性

LOG_TYPE_DBG |
LOG_TYPE_ERR |
LOG_TYPE_INFO |
LOG_TYPE_NORMAL |
LOG_TYPE_WAR |
NEXT_ONLY |
cellAppData |
component | 只读 string
entities | Entities
globalData | GlobalDataClient

成员函数文档

def addSpaceGeometryMapping( spaceID, mapper, path, shouldLoadOnServer, params ):

功能说明：

关联一个给定空间的几何映射，函数调用之后服务端和客户端都会加载相应的几何体数据。

在服务端上，从给定目录里加载所有的几何数据到指定的空间。这些数据可能被分成很多区块，不同区块是异步加载的，当所有的几何数据加载 完成的时候下面的通知方法会被调用：
    def onAllSpaceGeometryLoaded( self, spaceID, mappingName ):

服务端仅加载场景的几何数据提供给导航和碰撞功能使用，客户端除了几何数据外还会加载纹理等数据。
3D场景当前默认使用的是recastnavigation插件所导出的数据，2D场景当前默认使用的是MapEditor编辑器导出的数据。

有一种可能会导致onAllSpaceGeometryLoaded()不被调用，就是如果在某一个 时刻多个CellApp同时调用这个方法来添加几何到相同的空间的时候CellAppMgr崩溃了。

参数：
spaceID | uint32，空间的ID，指定在哪个空间操作
mapper | 目前填None
path | 包含几何数据的目录路径
shouldLoadOnServer | 可选的boolean参数，指定是否在服务端上加载几何。默认为True
params | 可选的PyDict参数，指定不同layer所使用的navmesh，例如： KBEngine.addSpaceGeometryMapping(self.spaceID, None, resPath, True, {0 : "srv_xinshoucun_1.navmesh", 1 : "srv_xinshoucun.navmesh"})

def addWatcher( path, dataType, getFunction ):

功能说明：

与调试监视系统交互，允许用户向监视系统注册一个监视变量。

例：
>>> def countPlayers( ):
>>>     i = 0
>>>     for e in KBEngine.entities.values():
>>>     	if e.__class__.__name__ == "Avatar":
>>>     		i += 1
>>>     return i
>>>
>>> KBEngine.addWatcher( "players", "UINT32", countPlayers )

这个函数添加一个监视变量在"scripts/players"监视路径之下。函数countPlayers在观察者观察时被调用。

参数：
path | 创建监视的路径。
dataType | 监视变量的值类型。参考: 基本类型
getFunction | 这个函数当观察者检索该变量时调用。 这个函数不带参数返回一个代表监视变量的值。

def address( ):

功能说明：

返回内部网络接口的地址。

def MemoryStream( ):

功能说明：

返回一个新的MemoryStream对象。

MemoryStream对象存储的是二进制信息，提供这个类型是为了让用户能够方便的序列化与反序列化Python基本类型同时能与KBEngine底层序列化规则相同。

例如：你可以使用这个对象构造一个KBEngine能解析的网络数据包。

用法：
>>> s = KBEngine.MemoryStream()
>>> s
>>> b''
>>> s.append("UINT32", 1)
>>> s.pop("UINT32")
>>> 1

目前MemoryStream能够支持的类型仅为基本数据类型。参考: 基本类型

def createEntity( entityType, spaceID, position, direction, params ):

功能说明：

createEntity在当前进程指定space中创建一个新的实体。
这个函数需要指定要创建的实体的类别，位置和方向，还可以选择性地设置实体的任意属性（属性在实体的.def文件里描述）。

例子：
# 创建一个打开的门的实体与"thing"实体的位置一样
direction = ( 0, 0, thing.yaw )
properties = { "open":1 }
KBEngine.createEntity( "Door", thing.space, thing.position, direction,
                       properties )

参数：
entityType | string，要创建的实体名称，在/scripts/entities.xml文件里声明。
spaceID | int32，要放置实体的空间的ID。
position | 由3个float组成的序列，指定新实体的出生点，在世界中的坐标。
direction | 由3个float组成的序列，指定新实体的初始朝向(roll, pitch, yaw)，相对于世界坐标系。
params | 可选参数, 一个Python字典对象。 如果一个指定的键是一个Entity属性，他的值会用来初始化这个Entity实体的属性。

返回：
新实体。

def debugTracing( ):

功能说明：

输出当前KBEngine追踪的Python扩展对象计数器。
扩展对象包括：固定字典、固定数组、Entity、EntityCall...
在服务端正常关闭时如果计数器不为零，此时说明泄露已存在，日志将会输出错误信息。

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 ):

功能说明：

删除指定key的space数据（如果space分割成多个部分，将进行同步删除）。
space数据由用户通过setSpaceData设置。

参数：
spaceID | int32，空间的ID。
key | string，一个字符串关键字。

def delWatcher( path ):

功能说明：

与调试监视系统交互，允许用户在脚本删除监视的变量。

参数：
path 要删除的变量的路径。

def deregisterReadFileDescriptor( fileDescriptor ):

功能说明：

注销已经通过KBEngine.registerReadFileDescriptor注册的回调。

例子:
http://www.kbengine.org/assets/other/py/Poller.py

参数：
fileDescriptor socket描述符/文件描述符。

def deregisterWriteFileDescriptor( fileDescriptor ):

功能说明：

注销已经通过KBEngine.registerWriteFileDescriptor注册的回调。

例子:
http://www.kbengine.org/assets/other/py/Poller.py

参数：
fileDescriptor socket描述符/文件描述符。

def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):

功能说明：

这个脚本函数在数据库上执行原始数据库命令，该命令将直接由相关数据库进行解析。

请注意使用该函数修改实体数据可能不生效，因为如果实体已经检出，被修改过的实体数据将仍会被实体存档而导致覆盖。
强烈不推荐这个函数用于读取或修改实体数据。

参数：
command | 这个数据库命令将会因为不同数据库配置方案而不同。对于方案为MySQL数据库它是一个SQL查询语句。
callback

可选参数，带有命令执行结果的回调对象（比如说是一个函数）。这个回调带有4个参数：结果集合，影响的行数，自増长值，错误信息。
声明样例：
def sqlcallback(result, rows, insertid, error):
print(result, rows, insertid, error)

如同上面的例子所示，result参数对应的就是“结果集合”，这个结果集合参数是一个行列表。 每一行是一个包含字段值的字符串列表。
命令执行没有返回结果集合（比如说是DELETE命令）， 或者 命令执行有错误时这个结果集合为None。

rows参数则是“影响的行数”，它是一个整数，表示命令执行受影响的行数。这个参数只和不返回结果结合的命令（如DELETE）相关。
如果有结果集合返回或者命令执行有错误时这个参数为None。

insertid对应的是“自増长值”，类似于实体的databaseID，当成功的向一张带有自増长类型字段的表中插入数据时，它返回该数据在插入时自増长字段所被赋于的值。
更多的信息可以参阅mysql的mysql_insert_id()方法。另外，此参数仅在数据库类型为mysql时有意义。

error则对应了“错误信息”，当命令执行有错误时，这个参数是一个描述错误的字符串。命令执行没有发生错误时这个参数为None。

threadID int32，可选参数，指定一个线程来处理本条命令。用户可以通过这个参数控制某一类命令的执行先后顺序（dbmgr是多线程处理的），默认是不指定，如果threadID是实体的ID，
那么将加入到该实体的存档队列中由线程逐条写入。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

def genUUID64( ):

功能说明：

该函数生成一个64位的唯一ID。
注意：这个函数依赖于Cellapps服务进程启动参数gus，请正确设置启动参数保持唯一性。
另外如果gus超过65535则该函数只能在当前进程上保持唯一性。

用途：
多个服务进程上产生唯一物品ID并且在合服时不会产生冲突。
多个服务进程上产生一个房间ID，不需要进行唯一性校验。

返回：
返回一个64位的integer。

def getResFullPath( res ):

功能说明：

获取资源的绝对路径。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

参数：
res string，如果存在返回资源的绝对路径，否则返回空。

返回：
string，资源的绝对路径。

def getSpaceData( spaceID, key ):

功能说明：

获取指定key的space数据。
space数据由用户通过setSpaceData设置。

参数：
spaceID | int32，空间的ID。
key | string，一个字符串关键字。

返回：
string，指定key的字符串数据。

def getSpaceGeometryMapping( spaceID ):

功能说明：

返回一个指定空间的几何映射名称。

参数：
spaceID 要查询的空间的id。

返回：
string，几何映射名称。

def getWatcher( path ):

功能说明：

从KBEngine调试系统中获取一个监视变量的值。

例子：在baseapp1的Python命令行输入:
>>>KBEngine.getWatcher("/root/stats/runningTime")
12673648533

>>>KBEngine.getWatcher("/root/scripts/players")
32133

参数：
path string，该变量的绝对路径包括变量名(可以在GUIConsole的watcher页查看)。

返回：
该变量的值。

def getWatcherDir( path ):

功能说明：

从KBEngine调试系统中获取一个监视目录下的元素列表(目录、变量名)。

例子：在baseapp1的Python命令行输入:
>>>KBEngine.getWatcher("/root")
('stats', 'objectPools', 'network', 'syspaths', 'ThreadPool', 'cprofiles', 'scripts', 'numProxices', 'componentID', 'componentType', 'uid', 'numClients', 'globalOrder', 'username', 'load', 'gametime', 'entitiesSize', 'groupOrder')

参数：
path string，该变量的绝对路径(可以在GUIConsole的watcher页查看)。

返回：
监视目录下的元素列表(目录、变量名)。

def getAppFlags( ):

功能说明：

获取当前引擎APP的标记, 参考:KBEngine.setAppFlags。

返回：
KBEngine.APP_FLAGS_*。

def hasRes( res ):

功能说明：

使用这个接口可以判断一个相对路径的资源是否存在。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

例子:

>>>KBEngine.hasRes("scripts/entities.xml")
True

参数：
res string，资源的相对路径。

返回：
BOOL, 存在返回True，否则返回False。

def isShuttingDown( ):

功能说明：

返回服务端是否正在关闭中。在onBaseAppShuttingDown回调函数被调用后，这个函数返回True。

返回：
系统正在关闭返回True，否则返回False。

def listPathRes( path, extension ):

功能说明：

获得一个资源目录下的资源列表。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

例子:

>>>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')

参数：
res | string，资源的相对路径。
extension | string，可选参数，扩展名。

返回：
Tuple, 资源列表。

def matchPath( res ):

功能说明：

使用相对路径的资源获得资源的绝对路径。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

例子:

>>>KBEngine.matchPath("scripts/entities.xml")
'/home/kbe/kbengine/demo/res/scripts/entities.xml'

参数：
res string，资源的相对路径(包括资源名称)。

返回：
string, 资源的绝对路径。

def open( res, mode ):

功能说明：

使用这个接口可以使用相对路径来打开相关资源。 注意：资源必须在KBE_RES_PATH之下才可以访问到。

参数：
res | string，资源的相对路径。
mode | string，文件操作模式： w 以写方式打开， a 以追加模式打开 (从 EOF 开始, 必要时创建新文件) r+ 以读写模式打开 w+ 以读写模式打开 (参见 w ) a+ 以读写模式打开 (参见 a ) rb 以二进制读模式打开 wb 以二进制写模式打开 (参见 w ) ab 以二进制追加模式打开 (参见 a ) rb+ 以二进制读写模式打开 (参见 r+ ) wb+ 以二进制读写模式打开 (参见 w+ ) ab+ 以二进制读写模式打开 (参见 a+ )

def publish( ):

功能说明：

这个接口返回当前服务端发行模式。

返回：
int8，0：debug，1：release，其它可自定义。

def raycast( spaceID, layer, src, dst ):

功能说明：

在指定的space中指定的layer中由源坐标向目的坐标射出一道射线，返回碰撞到的坐标点。

注意：space必须使用addSpaceGeometryMapping加载过几何数据。

下面是一个例子:

    >>> 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)

参数：
spaceID | int32, space的id。
layer | int8，几何层。一个space可以同时加载多个navmesh数据，不同的navmesh在不同的layer中，不同的layer可被抽象成地面、水面等等。

返回：
list， 碰撞到的坐标点列表。

def registerReadFileDescriptor( fileDescriptor, callback ):

功能说明：

注册一个回调函数，这个回调函数当文件描述符可读时被调用。

例子:
http://www.kbengine.org/assets/other/py/Poller.py

参数：
fileDescriptor | socket描述符/文件描述符。
callback | 一个回调函数，socket描述符/文件描述符作为它的唯一参数。

def registerWriteFileDescriptor( fileDescriptor, callback ):

功能说明：

注册一个回调函数，这个回调函数当socket描述符/文件描述符可写时被调用。

例子:
http://www.kbengine.org/assets/other/py/Poller.py

参数：
fileDescriptor | socket描述符/文件描述符。
callback | 一个回调函数，socket描述符/文件描述符作为它的唯一参数。

def reloadScript( fullReload ):

功能说明：

重新加载与实体和自定义数据类型相关的Python模块。当前实体类会设置为新加载的类。 这个方法应该只用于开发模式，对于产品模式不合适。下面几点应该注意：

1）重载脚本仅仅能在Cellapp上执行， 用户应该确保所有的服务端组件加载完成。

2）自定义类型在脚本重载后应该确保内存中已经实例化的对象也被更新，下面是一个例子:

for e in KBEngine.entities.values():
   if type( e ) is Avatar.Avatar:
      e.customData.__class__ = CustomClass
当这个方法完成时 KBEngine.onInit( True ) 被调用。

参数：
fullReload 可选的boolean参数，指定是否同时重新加载实体定义。如果这个参数为False，则实体定义不会被重新加载。默认为True。

返回：
重新加载成功返回True，否则返回False。

def scriptLogType( logType ):

功能说明：

设置当前Python.print输出的信息类型(参考: KBEngine.LOG_TYPE_*)。

def setAppFlags( flags ):

功能说明：

设置当前引擎APP的标记。

KBEngine.APP_FLAGS_NONE // 默认的(未设置标记)
KBEngine.APP_FLAGS_NOT_PARTCIPATING_LOAD_BALANCING //不参与负载均衡

例如：
KBEngine.setAppFlags(KBEngine.APP_FLAGS_NOT_PARTCIPATING_LOAD_BALANCING | KBEngine.APP_FLAGS_*)

def setSpaceData( spaceID, key, value ):

功能说明：

设置指定key的space数据。
space数据可以通过getSpaceData获取。

参数：
spaceID | int32，空间的ID。
key | string，一个字符串关键字。
value | string，字符串值。

def time( ):

功能说明：

这个方法返回当前游戏的时间（周期数）。

返回：
uint32，当前游戏的时间，这里指周期数，周期受频率影响，频率由配置文件kbengine.xml或者kbengine_defaults.xml->gameUpdateHertz决定。

回调函数文档

def onCellAppData( key, value ):

功能说明：

KBEngine.cellAppData有改变时回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
key | 被改变数据的键。
value | 被改变数据的值。

def onCellAppDataDel( key ):

功能说明：

KBEngine.cellAppData有删除的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
key 被删除数据的键。

def onGlobalData( key, value ):

功能说明：

KBEngine.globalData有改变的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
key | 被改变数据的键。
value | 被改变数据的值。

def onGlobalDataDel( key ):

功能说明：

KBEngine.globalData有删除的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
key 被删除数据的键。

def onInit( isReload ):

功能说明：

当引擎启动后初始化完所有的脚本后这个接口被调用。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
isReload bool，是否是被重写加载脚本后触发的。

def onSpaceData( spaceID, key, value ):

功能说明：

当space数据有改变的时候被调用。
space数据由用户通过setSpaceData设置。

参数：
spaceID | 空间的ID。
key | 被改变数据的键。
value | 被改变数据的值。

def onSpaceGeometryLoaded( spaceID, mapping ):

功能说明：

空间所需求的网格碰撞等数据加载完毕。
由用户通过addSpaceGeometryMapping设置。

参数：
spaceID | 空间的ID。
mapping | 网格碰撞数据的映射值。

def onAllSpaceGeometryLoaded( spaceID, isBootstrap, mapping ):

功能说明：

空间所需求的网格碰撞等数据全部加载完毕。
由用户通过addSpaceGeometryMapping设置。

参数：
spaceID | 空间的ID。
isBootstrap | 如果一个空间被分割由多个cell共同负载，那么isBootstrap描述的是是否为加载请求的发起cell。
mapping | 网格碰撞数据的映射值。

属性文档

LOG_TYPE_DBG

说明：

日志输出类型为调试类型。
由scriptLogType设置。

LOG_TYPE_ERR

说明：

日志输出类型为错误类型。
由scriptLogType设置。

LOG_TYPE_INFO

说明：

日志输出类型为常规信息类型。
由scriptLogType设置。

LOG_TYPE_NORMAL

说明：

日志输出类型为常规类型。
由scriptLogType设置。

LOG_TYPE_WAR

说明：

日志输出类型为警告类型。
由scriptLogType设置。

NEXT_ONLY

说明：

这个常量目前在Cellapp未被使用。

cellAppData

说明：

这个属性包含一个类字典的对象，这个对象会在所有的CellApps之间自动同步。 当字典的一个值被修改，这个修改会广播到所有的CellApps。

例子：
KBEngine.cellAppData[ "hello" ] = "there"

其余CellApp可以访问下面的：
print KBEngine.cellAppData[ "hello" ]

键和值可以是任意类型，但这些类型必须在所有目标组件上能够被封装和被拆封。

当一个值被改变或被删除，一个回调函数会在所有组件被调用。 参看：KBEngine.onCellAppData和KBEngine.onDelCellAppData。

注意：只有顶层的值才会被广播，如果你有一个值（比如一个列表），它改变了内部的值（比如只是改变一个数），这个信息不会被广播。

不要进行下面的操作：
KBEngine.cellAppData[ "list" ] = [1, 2, 3]
KBEngine.cellAppData[ "list" ][1] = 7
这样，本地访问是[1, 7, 3]，远程访问是[1, 2, 3]。

component

说明：

这是正运行在当前Python环境的组件。（至今为止）可能值有'cell', 'base', 'client', 'database', 'bot' 和 'editor'。

entities

说明：

entities是一个字典对象，包含当前进程上所有的实体，包括ghost实体。

调试泄露的实体（调用过destroy却没有释放内存的实体，通常是由于被引用导致无法释放）：
>>> KBEngine.entities.garbages.items()
[(1025, Avatar object at 0x7f92431ceae8.)]

>>> e = _[0][1]
>>> import gc
>>> gc.get_referents(e)
[{'spacesIsOk': True, 'bootstrapIdx': 1}, ]

调试泄露的KBEngine封装的Python对象：
KBEngine.debugTracing

类型：
Entities

globalData

说明：

这个属性包含一个类字典的对象，这个对象会在所有的BaseApps和CellApps之间自动复制。 当字典的一个值被修改，这个修改会广播到所有的BaseApps和CellApps。CellAppMgr解决竞争条件，保证信息复制的权威性。

例子：
KBEngine.globalData[ "hello" ] = "there"

其余Cellapp或者 Baseapp可以访问下面的：
print KBEngine.globalData[ "hello" ]

键和值可以是任意类型，但这些类型必须在所有目标组件上能够被封装和被拆封。

当一个值被改变或被删除，一个回调函数会在所有组件被调用。 参看：KBEngine.onGlobalData和KBEngine.onGlobalDataDel。

注意：只有顶层的值才会被广播，如果你有一个易变的值（比如一个列表），它改变了内部的值（比如只是改变一个数），这个信息不会被广播。

不要进行下面的操作：
KBEngine.globalData[ "list" ] = [1, 2, 3]
KBEngine.globalData[ "list" ][1] = 7
这样，本地访问是[1, 7, 3]，远程访问是[1, 2, 3]。


Entity - KBEngine cell 文档

Entity类

[KBEngine模块]

Entity是KBEngine模块的一部分。 更多...

import KBEngine

成员函数

def accelerate( self, accelerateType, acceleration ):
def addYawRotator( self, targetYaw, velocity, userArg ):
def addProximity( self, range, userArg ):
def addTimer( self, start, interval=0.0, userData=0 ):
def cancelController( self, controllerID ):
def clientEntity( self, destID ):
def canNavigate( self ):
def debugView( self ):
def delTimer( self, id ):
def destroy( self ):
def destroySpace( self ):
def entitiesInView( self ):
def entitiesInRange( self, range, entityType=None, position=None ):
def isReal( self ):
def moveToEntity( self, destEntityID, velocity, distance, userData, faceMovement, moveVertically, offsetPos ):
def moveToPoint( self, destination, velocity, distance, userData, faceMovement, moveVertically ):
def getViewRadius( self ):
def getViewHystArea( self ):
def getRandomPoints( self, centerPos, maxRadius, maxPoints, layer ):
def navigate( self, destination, velocity, distance, maxMoveDistance, maxSearchDistance, faceMovement, layer, userData ):
def navigatePathPoints( self, destination, maxSearchDistance, layer ):
def setViewRadius( self, radius, hyst=5 ):
def teleport( self, nearbyMBRef, position, direction ):
def writeToDB( self, shouldAutoLoad, dbInterfaceName ):

回调函数

def onDestroy( self ):
def onEnterTrap( self, entity, rangeXZ, rangeY, controllerID, userArg ):
def onEnteredView( self, entity ):
def onGetWitness( self ):
def onLeaveTrap( self, entity, rangeXZ, rangeY, controllerID, userArg ):
def onLoseControlledBy( self, id ):
def onLoseWitness( self ):
def onMove( self, controllerID, userData ):
def onMoveOver( self, controllerID, userData ):
def onMoveFailure( self, controllerID, userData ):
def onRestore( self ):
def onSpaceGone( self ):
def onTurn( self, controllerID, userData ):
def onTeleport( self ):
def onTeleportFailure( self ):
def onTeleportSuccess( self, nearbyEntity ):
def onTimer( self, timerHandle, userData ):
def onUpdateBegin( self ):
def onUpdateEnd( self ):
def onWitnessed( self, isWitnessed ):
def onWriteToDB( self ):

属性

allClients | 只读 PyClient
base | 只读 BaseEntityCall
client | 只读 ClientEntityCall
controlledBy | BaseEntityCall
className | 只读 string
direction | Tuple of 3 floats as (roll, pitch, yaw)
hasWitness | boolean
id | 只读 Integer
isDestroyed | 只读 bool
isWitnessed | 只读 bool
layer | int8
otherClients | 只读 PyClient
position | Vector3
spaceID | 只读 uint32
topSpeed | float
topSpeedY | float
volatileInfo | float

详细描述

类Entity的实例代表着在cell上的游戏对象。一个 Entity可以是"real"或者"ghosted"的，一个"ghost" Entity是一个存活在邻近的cell上 的"real" Entity的拷贝。对于每一个实体来说有一个唯一的"real" Entity实例，和有0个 或者更多的"ghost" Entity实例。

一个Entity实例操控着实体的位置数据，包括他的空间和旋转。它还控制着这些数据发给 客户端的频率（如果可以）。位置的数据可以被唯一的客户端所更新，被控制器对象，被teleport成员函数修改。 控制器是非python对象，可以适用在cell实体上随着时间的过去来改变它们的位置数据，它们通过成员函数如"trackEntity"和"turnToYaw"来 添加到Entity，可以通过"cancelController"移除。

感兴趣的范围，或"View"对于所有属于客户端的KBEngine实体来说是一个重要的概念。 一个实体的View是围绕这个实体的客户端（如果它有）所能感知的区域。这用于选择发给客户端的数据量。View的实际 形状由x轴和z轴上的距离范围定义，还有一个类似形状向外延伸的滞后区域。一个Entity进入 另一个Entity的View，但不会离开它直到它离开滞后区域。一个Entity可以 通过"setViewRadius"修改它的View大小。 可以通过"entitiesInRange"找到一个具体距离之内的所有实体，通过"addProximity"设置一个陷阱捕获进入陷阱的所有实体。

cellApp上新的Entity可以使用KBEngine.createEntity 创建。一个实体还可以通过baseApp远程调用KBEngine.createCellEntity函数 来创建。

一个Entity可以通过ENTITYCALL访问在base和client应用程序上的等价的实体。这需要 一组远程调用的函数（在实体的.def文件里指定）。

成员函数文档

def accelerate( self, accelerateType, acceleration ):

功能说明：

加速实体当前运动。

可影响的运动包括：
Entity.moveToEntity
Entity.moveToPoint
Entity.navigate
Entity.addYawRotator

参数：
accelerateType | string，影响的运动类型，如：Movement、Turn。
velocity | float，每秒的加速度，如果传入的是负值则表示减速度。

返回：
影响后的实体当前速度。

def addYawRotator( self, targetYaw, velocity, userArg ):

功能说明：

控制实体绕yaw旋转，旋转完成将会通过Entity.onTurn通知。

使用Entity.cancelController带上控制器ID或者使用Entity.cancelController("Movement")来删除它。

参看：
Entity.cancelController

参数：
targetYaw | float，给定的目标yaw弧度。
velocity | float，旋转时每秒的弧度。
userArg | 是一个可选的整型，所有控制器共有。如果这个值不为0则传给回调函数。建议 在回调原型里设置默认值为0。

def addProximity( self, rangeXZ, rangeY, userArg ):

功能说明：

创建一个范围触发器，当有其它实体进入或离开这个触发器区域的时候会通知这个Entity。这个区域是一个方形（为了效率）。如果
其它实体在x轴和z轴上均在给定的距离里面，则实体被视为在这个范围里面。这个Entity通过onEnterTrap和onLeaveTrap函数被
通知，这两个函数可以如下定义：

    def onEnterTrap( self, entityEntering, rangeXZ, rangeY, controllerID, userArg = 0 ):
    def onLeaveTrap( self, entityLeaving, rangeXZ, rangeY, controllerID, userArg = 0 ):

由于这个范围触发器是一个控制器，使用Entity.cancelController带上控制器ID来删除它。

需要注意的是回调有可能会立刻被触发，即使在addProximity()调用返回之前。

参看：
Entity.cancelController

参数：
rangeXZ | float，给定触发器xz轴区域的大小，必须大于等于0。
rangeY | float，给定触发器y轴高度，必须大于等于0。 需要注意的是，这个参数要生效必须开放kbengine_defaults.xml->cellapp->coordinate_system->rangemgr_y 开放y轴管理会带来一些消耗，因为一些游戏大量的实体都在同一y轴高度或者在差不多水平线高度，此时碰撞变得非常密集。 3D太空类游戏或者小房间类实体较少的游戏比较适合开放此选项。
userArg | 是一个可选的整型，所有控制器共有。如果这个值不为0则传给回调函数。建议 在回调原型里设置默认值为0。

返回：
返回创建控制器的id。

def addTimer( self, start, interval=0.0, userData=0 ):

功能说明：

注册一个定时器，定时器由回调函数onTimer触发，回调函数将在"initialOffset"秒后被执行第1次，而后将每间隔"repeatOffset"秒执行1次，可设定一个用户参数"userArg"（仅限integer类型）。

onTimer 函数必须在entity的cell部分被定义，且带有2个参数，第1个integer类型的是timer的id（可用于移除timer的"delTimer"函数），第2个是用户参数"userArg"。

例子:
# 这里是使用addTimer的一个例子
import KBEngine

class MyCellEntity( KBEngine.Entity ):

    def __init__( self ):
        KBEngine.Entity.__init__( self )

        # 增加一个定时器，5秒后执行第1次，而后每1秒执行1次，用户参数是9
        self.addTimer( 5, 1, 9 )

        # 增加一个定时器，1秒后执行，用户参数缺省是0
        self.addTimer( 1 )

    # Entity的定时器回调"onTimer"被调用
    def onTimer( self, id, userArg ):
        print "MyCellEntity.onTimer called: id %i, userArg: %i" % ( id, userArg )
        # if 这是不断重复的定时器，当不再需要该定时器的时候，调用下面函数移除:
        #     self.delTimer( id )

参数：
initialOffset | float，指定定时器从注册到第一次回调的时间间隔（秒）。
repeatOffset | float，指定第一次回调执行后每次执行的时间间隔（秒）。必须用函数delTimer移除定时器，否则它会一直重复下去。值小于等于0将被忽略。
userArg | integer，指定底层回调"onTimer"时的userArg参数值。

返回:
integer，该函数返回timer的内部id，这个id可用于delTimer移除定时器。

def cancelController( self, controllerID ):

功能说明：

函数cancelController停止一个控制器对Entity的影响。它只能在一个real实体上被调用。

参数：
controllerID controllerID是要取消的控制器的索引，它是一个整型。一个专用的控制器类型的字符串也可以作为它的类型。 例如，一次只有一个移动/导航控制器可以被激活，这可以用entity.cancelController( "Movement" )取消。

def clientEntity( self, destID ):

功能说明：

通过这个方法可以访问自己客户端（当前实体必须绑定了客户端）中某个实体的方法，只有在View范围内的实体才会同步到客户端。它只能在一个real实体上被调用。

参数：
destID 目标实体的ID。

def canNavigate( self ):

功能说明：

通过这个方法判断当前实体是否可以使用导航（Entity.navigate）功能。它只能在一个real实体上被调用。
通常当实体所在Space使用Entity.addSpaceGeometryMapping加载过有效的导航用的碰撞数据（Navmesh或者2D的tile数据）并且实体在有效导航区域该功能可用。

返回：
bool， 如果实体可在当前Space中使用导航功能返回True，否则返回False。

def debugView( self ):

功能说明：

debugView输出Entity的View的详细信息到cell的调试日志。 一份View系统工作的描述可以在Entity类文档中找到。

一份样品信息如下：
  INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugView: 100 size=4, Seen=4, Pending=0, ViewRadius=50.000, ViewHyst=5.000
  INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugView: 100 Avatar(102), position(771.586.211.002.776.55), dist=0
  INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugView: 100 Monster(1028), position(820.834.211.635.768.749), dist=49.8659
  INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugView: 100 NPC(1025), position(784.024.210.95.782.273), dist=13.6915
  INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugView: 100 Avatar(106), position(771.586.211.002.776.55), dist=0
信息的第一行告诉我们：
  • 实体#1000的数据
  • 有4个实体在它的View区域并且已经同步给客户端。
  • 有0个实体在它的View区域，正在等待同步到客户端。
  • View的半径是 50.000
  • View的滞后区域向外延伸了5.000

def delTimer( self, id ):

功能说明：

函数delTimer用于移除一个注册的定时器，移除后的定时器不再执行。只执行1次的定时器在执行回调后自动移除，不必要使用delTimer移除。 如果delTimer函数使用一个无效的id（例如已经移除），将会产生错误。

参数：
id integer，它指定要移除的定时器id。

def destroy( self ):

功能说明：

这个函数销毁它的本地Entity实例，如果实体在其他进程上存在ghost部分也会同时通知销毁。 这个函数最好由实体自己调用，如果这个实体是一个ghost则会抛出一个异常。如果回调函数onDestroy()被实现则被调用。

def destroySpace( self ):

功能说明：

销毁这个实体所在的空间。

def entitiesInView( self ):

功能说明：

获得这个实体的View范围内的实体列表。

def entitiesInRange( self, range, entityType=None, position=None ):

功能说明：

在给定的距离内搜索实体。这是一个球形的搜索，3个轴的距离 都要测量。这可以找到在这个实体的View范围之外的实体，但不能找到其他cell的实体。

例子：
  self.entitiesInRange( 100, 'Creature', (100, 0, 100) )
搜索到‘Creature’类型的实体列表（‘Creature’的子类实例化的实体）。中心点是(100, 0, 100)，搜索半径是100米。
  [ e for e in self.entitiesInRange( 100, None, (100,0,100) ) if isinstance( e, BaseType ) ]
将给出一个来自‘BaseType’或‘BaseType’的子类实例化的实体列表。

参数：
range | 围绕这个实体搜索的距离，float类型
entityType | 一个可选的字符串参数，实体的类型名称，用于匹配实体。如果实体类型是一个有效的类名（ 有效的实体类型在/scripts/entities.xml列出 ）， 则只有这个类型的实体会被返回，否则将这个范围的所有实体都返回。
position | 一个可选的Vector3类型参数，作为搜索半径的中心, 默认以实体自身为中心。

返回：
在给定范围内的Entity对象列表。

def isReal( self ):

功能说明：

这个函数返回这个Entity是real的还是一个ghost的。

这个函数很少被用到但对调试很有用。

返回：
bool， 如果是real实体返回True，否则返回False。

def moveToEntity( self, destEntityID, velocity, distance, userData, faceMovement, moveVertically, offsetPos ):

功能说明：

直线移动实体到另一个Entity位置。
任何实体，在任意时刻只能有一个移动控制器，重复调用任何移动函数将终止之前的移动控制器。
调用后函数将返回一个可以用于取消这次移动的控制器ID。

例如，Entity.cancelController( movementID )。 移动取消还可以调用Entity.cancelController( "Movement" )。当移动被取消之后回调通知方法将不被调用。

    def onMove( self, controllerID, userData ):
    def onMoveOver( self, controllerID, userData ):
    def onMoveFailure( self, controllerID, userData ):

参考:
Entity.cancelController

参数：
destEntityID | int，目标Entity的ID
velocity | float，Entity移动的速度，单位m/s
distance | float，距离目标小于该值停止移动，如果该值为0则移动到目标位置。
userData | object，可选参数，回调通知被调用时其中userData参数将为此值。
faceMovement | bool，可选参数，如果实体面向移动方向则为true。如果是其它机制则为false。
moveVertically | bool，可选参数，设为True指移动为直线移动，设为False指贴着地面直线移动。
offsetPos | Vector3，可选参数，设置一定的偏移值，例如使移动目标位置位于实体的左侧。

返回：
int，新创建的控制器ID。

def moveToPoint( self, destination, velocity, distance, userData, faceMovement, moveVertically ):

功能说明：

直线移动Entity到给定的坐标点，成功或失败会调用回调函数。
任何实体，在任意时刻只能有一个移动控制器，重复调用任何移动函数将终止之前的移动控制器。
返回一个可以用于取消这次移动的控制器ID。

例如：
Entity.cancelController( movementID )。 移动取消还可以调用Entity.cancelController( "Movement" )。当移动被取消之后通知方法将 不被调用。

回调函数如下定义：
    def onMove( self, controllerID, userData ):
    def onMoveOver( self, controllerID, userData ):
    def onMoveFailure( self, controllerID, userData ):

参看：
Entity.cancelController

参数：
destination | Vector3，Entity要移动到的目标位置点
velocity | float，Entity的移动速度，单位m/s
distance | float，距离目标小于该值停止移动，如果该值为0则移动到目标位置。
userData | object，传给通知函数的数据
faceMovement | bool，如果实体面向移动方向则为true。如果是其它机制则为false。
moveVertically | bool，设为true指移动为直线移动，设为false指贴着地面移动。

返回：
int，新创建的控制器ID。

def getViewRadius( self ):

功能说明：

这个函数返回这个Entity当前的View半径值。

数据可以通过 Entity.setViewRadius( radius, hyst )设置。

返回：
float， View半径。

def getViewHystArea( self ):

功能说明：

这个函数返回这个Entity的View当前滞后区域值。

数据可以通过 Entity.setViewRadius( radius, hyst )设置。

返回：
float， View当前滞后区域值。

def getRandomPoints( self, centerPos, maxRadius, maxPoints, layer ):

功能说明：

这个函数用于获取以某个坐标点为中心一定区域内Entity.navigate可到达的随机坐标点。

参数：
centerPos | Vector3，Entity中心坐标点
maxRadius | float，最大的搜索半径
maxPoints | uint32，最多返回的随机坐标点数量。
layer | int8，使用某个层的navmesh来搜索。

返回：
tuple，包含一个或者多个坐标的数组。

def navigate( self, destination, velocity, distance, maxMoveDistance, maxSearchDistance, faceMovement, layer, userData ):

功能说明：

使用导航系统来使这个Entity向一个目标点移动，成功或失败会调用回调函数。
KBEngine可以有数个预先生成好的导航网格，不同的网格大小（会导致不同的导航路径）。
任何实体，在任意时刻只能有一个移动控制器，重复调用任何移动函数将终止之前的移动控制器。
返回一个可以用于取消这次移动的控制器ID。

例如：
Entity.cancelController( movementID )。 移动取消还可以调用Entity.cancelController( "Movement" )。当移动被取消之后通知方法将 不被调用。

回调函数如下定义：
    def onMove( self, controllerID, userData ):
    def onMoveOver( self, controllerID, userData ):
    def onMoveFailure( self, controllerID, userData ):

参看：
Entity.cancelController

参数：
destination | Vector3，Entity移向的目标点。
velocity | float，Entity的移动速度，单位m/s
distance | float，距离目标小于该值停止移动，如果该值为0则移动到目标位置。
maxMoveDistance | float，最大的移动距离。
maxSearchDistance | float，从导航数据中最大搜索距离。
faceMovement | bool，如果实体面向移动方向则为true（默认）。如果是其它机制则为false。
layer | int8，使用某个层的navmesh来寻路。
userData | object，传给通知函数的数据。

返回：
int，新创建的控制器ID。

def navigatePathPoints( self, destination, maxSearchDistance, layer ):

功能说明：

这个函数返回有当前Entity的位置到destination位置所经过的路径点列表。

参数：
destination | Vector3，Entity移向的目标点
maxSearchDistance | float，最大的搜索距离
layer | int8，使用某个层的navmesh来查找路径列表。

def setViewRadius( self, radius, hyst=5 ):

功能说明：

指定Entity的感兴趣的区域大小。

这个函数只能用于有Witness关联的实体。

注意： 你可以通过设置kbengine.xml配置选项'cellapp/defaultViewRadius'来设置默认的View半径。

数据可以通过 Entity.getViewRadius( )与Entity.getViewHystArea( )获得。

参数：
radius | float，radius指定View区域的半径
hyst | float，指定超过View区域的滞后区域的大小。合理的设定滞后区域将能够降低View碰撞的敏感度从而提高CPU执行效率。 一个实体进入另一个实体的View必须跨越View半径区域，但实体离开View区域则需要移出View半径区域包括滞后区域。

返回：
None

def teleport( self, nearbyMBRef, position, direction ):

功能说明：

瞬间移动一个Entity到一个指定的空间。这个函数允许指定实体移动后的位置与朝向。
如果需要在不同空间跳转（ 通常用于不同场景或者房间跳转 ），可以传一个CellEntityCall给这个函数（ 这个entityCall所对应的实体必须在目的空间中 ）。

这个函数只能在real的实体上被调用。

参数：
nearbyMBRef | 一个决定Entity跳往哪个Space的CellEntityCall（ 这个entityCall所对应的实体必须在目的Space中 ），它被认为是传送目的地。 这个可以设为None，在这种情形下它会在当前的cell完成瞬移。
position | Entity瞬移后的坐标，是一个有3个float(x, y, z)组成的序列。
direction | Entity瞬移后的朝向，是一个由3个float组成的序列(roll,pitch, yaw)。

def writeToDB( self, shouldAutoLoad, dbInterfaceName ):

功能说明：

这个函数保存与这个实体相关的数据到数据库，包括base实体的数据。在数据确认传到数据库之前base实体的onWriteToDB函数会被调用。

cell实体的数据同时备份在base实体，确保遇到灾难恢复数据时数据是最新的。

这个函数只能在real实体且实体必须存在base部分时才允许被调用。

参数：
shouldAutoLoad 这个可选参数指定这个实体在服务启动的时候是否需要从数据库加载。
注意：服务器启动时自动加载实体，底层默认将会调用createEntityAnywhereFromDBID将实体创建到一个负载最小的baseapp上，整个过程将会在第一个启动的baseapp调用onBaseAppReady之前完成。

脚本层可以在个性化脚本(kbengine_defaults.xml->baseapp->entryScriptFile定义)中重新实现实体的创建方法，例如：
def onAutoLoadEntityCreate(entityType, dbid):
KBEngine.createEntityFromDBID(entityType, dbid)
dbInterfaceName string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

回调函数文档

def onDestroy( self ):

如果这个函数在脚本中有实现，这个函数在调用Entity.destroy()后，在实际销毁之前被调用。 这个函数没有参数。

def onEnterTrap( self, entity, rangeXZ, rangeY, controllerID, userArg ):

当注册了使用Entity.addProximity注册了一个范围触发器，有其他实体进入触发器时，该回调函数被调用。

参数：
entity | 已经进入了范围的实体。
rangeXZ | float，给定触发器xz轴区域的大小，必须大于等于0。
rangeY | float，给定触发器y轴高度，必须大于等于0。 需要注意的是，这个参数要生效必须开放kbengine_defaults.xml->cellapp->coordinate_system->rangemgr_y 开放y轴管理会带来一些消耗，因为一些游戏大量的实体都在同一y轴高度或者在差不多水平线高度，此时碰撞变得非常密集。 3D太空类游戏或者小房间类实体较少的游戏比较适合开放此选项。
controllerID | 这个触发器的控制器id。
userArg | 这个参数的值由用户调用addProximity时给出，用户可以根据此参数对当前行为做一些判断。

def onEnteredView( self, entity ):

如果这个函数在脚本中有实现，当一个实体进入了当前实体的View范围，该回调被触发。

参数：
entity 进入View范围的实体。

def onGetWitness( self ):

如果这个函数在脚本中有实现，当实体绑定了Witness时被调用。
也可以访问实体属性Entity.hasWitness得到实体当前的状态。

def onLeaveTrap( self, entity, rangeXZ, rangeY, controllerID, userArg ):

如果这个函数在脚本中有实现，当实体离开了当前实体注册的范围触发器区域时被触发，范围触发器由Entity.addProximity注册。

参数：
entity | 已经离开触发器区域的实体。
rangeXZ | float，给定触发器xz轴区域的大小，必须大于等于0。
rangeY | float，给定触发器y轴高度，必须大于等于0。 需要注意的是，这个参数要生效必须开放kbengine_defaults.xml->cellapp->coordinate_system->rangemgr_y 开放y轴管理会带来一些消耗，因为一些游戏大量的实体都在同一y轴高度或者在差不多水平线高度，此时碰撞变得非常密集。 3D太空类游戏或者小房间类实体较少的游戏比较适合开放此选项。
controllerID | 这个触发器的控制器ID。
userArg | 这个参数的值由用户调用addProximity时给出，用户可以根据此参数对当前行为做一些判断。

def onLoseControlledBy( self, id ):

如果这个函数在脚本中有实现，当Entity.controlledBy 所关联的实体丢失时改回调方法被调用。

参数：
id controlledBy实体的ID。

def onLoseWitness( self ):

如果这个函数在脚本中有实现，当实体解除Witness时，该回调被触发。
也可以访问实体属性Entity.hasWitness得到实体当前的状态。

def onMove( self, controllerID, userData ):

如果这个函数在脚本中有实现，相关的Entity.moveToPoint与Entity.moveToEntity还有Entity.navigate方法被调用并且成功后底层每帧移动都会回调此函数。

参数：
controllerID | 与某个移动相关的控制器ID。
userData | 这个参数值由用户在请求移动相关接口时给出。

def onMoveOver( self, controllerID, userData ):

如果这个函数在脚本中有实现，相关的Entity.moveToPoint与Entity.moveToEntity还有Entity.navigate方法被调用后到达指定目标点时会回调此函数。

参数：
controllerID | 与某个移动相关的控制器ID。
userData | 这个参数值由用户在请求移动相关接口时给出。

def onMoveFailure( self, controllerID, userData ):

如果这个函数在脚本中有实现，相关的Entity.moveToPoint与Entity.moveToEntity还有Entity.navigate方法被调用并且失败时会回调此函数。

参数：
controllerID | 与某个移动相关的控制器ID。
userData | 这个参数值由用户在请求移动相关接口时给出。

def onRestore( self ):

如果这个函数在脚本中有实现，这个函数在Cell应用程序崩溃后在其它Cell应用程序上重新创建该实体时被调用。这个函数没有参数。

def onSpaceGone( self ):

如果这个函数在脚本中有实现，当前实体所在的Space将要销毁时触发 。这个函数没有参数。

def onTurn( self, controllerID, userData ):

如果这个函数在脚本中有实现，相关的Entity.addYawRotator方法被调用后到达指定yaw时会回调此函数。

参数：
controllerID | Entity.addYawRotator返回的控制器ID。
userData | 这个参数值由用户在请求移动相关接口时给出。

def onTeleport( self ):

如果这个函数在脚本中有实现，在通过baseapp的Entity.teleport调用发生的实体传送中，实体(Real entity)被传送之前的时刻此方法会被调用。
请注意，在cell上调用实体的teleport并不会回调此接口，如果你需要这个功能请在Entity.teleport之后调用此回调。

def onTimer( self, timerHandle, userData ):

功能说明：

这个函数当一个与此实体关联的定时器触发的时候被调用。 一个定时器可以使用Entity.addTimer函数添加。

参数：
timerHandle | 定时器的id。
userData | 传进Entity.addTimer的integer用户数据。

def onTeleportFailure( self ):

如果这个函数在脚本中有实现，当用户调用Entity.teleport失败时该回调被调用。

def onTeleportSuccess( self, nearbyEntity ):

如果这个函数在脚本中有实现，当用户调用Entity.teleport成功时该回调被调用。

参数：
nearbyEntity 这个参数由用户调用 Entity.teleport时给出。这是一个real实体。

def onUpdateBegin( self ):

当同步一帧开始时被调用。

def onUpdateEnd( self ):

当同步一帧结束时被调用。

def onWitnessed( self, isWitnessed ):

如果这个函数在脚本中有实现，如果当前实体进入了另一个绑定了Witness的实体的View范围（也可以理解为一个实体被观察者观察到了），则该实体的回调函数被调用。
可以利用这个函数在实体被观察时激活实体的AI，实体停止被观察时可以停止AI的执行，这样可以降低服务端的计算量从而提升效率。

参数：
isWitnessed bool，实体被观察时为True，实体被停止观察时是False。
也可以访问实体属性Entity.isWitnessed得到实体当前的状态。

def onWriteToDB( self ):

如果这个函数在脚本中有实现，这个函数在实体将要存档到数据库时被调用。

属性文档

allClients

通过这个属性调用实体的客户端远程方法，引擎会将这个消息广播给实体View范围内所有的其他绑定了客户端的实体(包括自己的客户端，绑定了客户端的实体通常为玩家)。

例子：
avatar的View范围内有玩家A和玩家B以及怪物C。
avatar.allClients.attack(monsterID，skillID, damage)

此时，玩家自己和玩家A还有玩家B的客户端都会调用到该实体attack方法，在他们的客户端可以调用指定技能的攻击动作做表现。

其他参考：
Entity.clientEntity
Entity.otherClients

base

base是用于联系Entity实体的entityCall。这个属性是只读的，且如果这个实体没有关联的Entity实体时属性是None。

其他参考：
Entity.clientEntity
Entity.allClients
Entity.otherClients

类型：
只读的，ENTITYCALL

className

实体的类名。

类型：
只读，string

client

client是用于联系客户端的entityCall。这个属性是只读的，且如果这个实体没有关联的客户端时属性是None。

其他参考：
Entity.clientEntity
Entity.allClients
Entity.otherClients

类型：
只读的，ENTITYCALL

controlledBy

该属性如果设置为某个客户端所关联的服务端实体的BaseEntityCall，那么该实体由对应的客户端来控制移动，如果该属性为None则实体由服务端移动。 当客户端登陆后调用giveClientTo到该实体时，该属性会自动的设置为自己的BaseEntityCall。
脚本可以灵活的控制该实体由服务端控制移动或是由客户端（自己的客户端或是其他客户端）控制移动。

其他参考：
Entity.onLoseControlledBy

类型：
BaseEntityCall

direction

这个属性描述的是Entity在世界空间中的朝向，用户可以改变这个属性，数据会同步到客户端。
例子： self.direction.y = 1.0 self.direction.z = 1.0

类型：
Vector3, 其中包含(roll, pitch, yaw)，以弧度表示。

hasWitness

这个只读属性如果为True，表示实体已经绑定了一个Witness，绑定了Witness的实体则客户端可以通过实体获得实体View范围内的信息。否则为False。

类型：
只读的， bool

id

id是Entity的对象id。这个id是一个整型，在base，cell和client相关联的实体之间是相同的。 这个属性是只读的。

类型：
只读的，int32

isDestroyed

如果这个属性的值为True，Entity则已经被销毁了。

类型：
只读的， bool

isOnGround

如果这个属性的值为True，Entity在地面上，否则为False。

类型：
只读的， bool

isWitnessed

如果当前实体进入了另一个绑定了Witness的实体的View范围（也可以理解为一个实体被观察者观察到了, 这个属性值为True，否则为False。

参考：
Entity.onWitnessed

类型：
只读的， bool

layer

一个space可以同时加载多个navmesh数据，不同的navmesh在不同的layer中，不同的layer可被抽象成地面、水面等等。 通过这个属性决定一个实体存在于哪个layer中。

参考：
KBEngine.addSpaceGeometryMapping

类型：
int8

otherClients

通过这个属性调用实体的客户端远程方法，引擎会将这个消息广播给实体View范围内所有的其他绑定了客户端的实体(不包括自己的客户端，绑定了客户端的实体通常为玩家)。

例子：
avatar的View范围内有玩家A和玩家B以及怪物C。
avatar.otherClients.attack(monsterID，skillID, damage)

此时，玩家A与玩家B的客户端都会调用到该实体attack方法，在他们的客户端可以调用指定技能的攻击动作做表现。

其他参考：
Entity.clientEntity
Entity.otherClients

position

这个实体在世界空间中的坐标(x, y, z)，这个属性可以被用户改变，改变后会同步到客户端。 需要注意的是，不要引用这个属性，引用这个属性很有可能错误的修改了实体的真实坐标。

例子：
self.position.y = 10.0

如果你想拷贝这个属性值可以使用如下方式：
    import Math
    self.copyPosition = Math.Vector3( self.position )

类型：
Vector3

spaceID

这个属性是实体所在的空间的ID，cell与客户端这个值都保持一致。

类型：
只读的，Integer

topSpeed

实体的最大xz轴移动速度（米/秒），这个属性通常要比实际移动速度要大一些，服务端通过这个属性检查客户端的移动合法性，如果移动距离超出速度限制则被强制拉回上一个坐标位置。

其他参考：
Entity.topSpeedY

类型：
float

topSpeedY

实体的最大y轴移动速度（米/秒），这个属性通常要比实际移动速度要大一些，服务端通过这个属性检查客户端的移动合法性，如果移动距离超出速度限制则被强制拉回上一个坐标位置。

其他参考：
Entity.topSpeed

类型：
float

volatileInfo

这个属性指定Entity的易变类数据同步到客户端的策略。
易变类数据包括实体的坐标position和实体的朝向direction，易变类数据由于极易改变的特性，引擎底层使用了一套优化的方案将其同步到客户端。
这个属性是四个float（position，yaw，pitch，roll）代表距离值，当一个实体靠近当前实体达到距离则服务端向其同步相关数据。如果距离值大于View半径则代表总是同步。

还有一个特殊的bool属性optimized，它的作用是控制服务器同步时是否进行优化，目前主要的优化是Y轴。
如果为true，在一些行为(如：navigate)导致服务器能确定实体在地面时，服务器不同步实体的Y轴坐标，当同步大量实体时能节省大量带宽，默认为true。

用户也可以在.def制定不同实体的同步策略：
<Volatile>
    <position/>           <!-- 总是同步 -->
    <yaw/>                <!-- 总是同步 -->
    <pitch>20</pitch>     <!-- 相距20米或以内同步     -->
    <optimized> true </optimized>
</Volatile>               <!-- roll未指明则总是同步  -->

类型：
sequence， 四个浮点数(float, float, float, float)


KBEngine - KBEngine baseapp 文档

Baseapp进程

Baseapp进程主要负责与客户端通讯、与空间或位置无关类游戏逻辑(公会管理器、聊天系统、游戏大厅、排行榜等等)、存档与备份等等。


KBEngine - KBEngine base 文档

KBEngine模块

KBEngine模块提供了Python脚本访问实体的部分，特别是它提供了定时器的注册与移除， 以及实体的创建。

类

Entity
Proxy

成员函数

def addWatcher( path, dataType, getFunction ):
def address( ):
def MemoryStream( ):
def charge( ordersID, dbID, byteDatas, pycallback ):
def createEntity( ):
def createEntityAnywhere( entityType, *params, callback ):
def createEntityRemotely( entityType, baseMB, *params, callback ):
def createEntityFromDBID( entityType, dbID, callback, dbInterfaceName ):
def createEntityAnywhereFromDBID( entityType, dbID, callback, dbInterfaceName ):
def createEntityRemotelyFromDBID( entityType, dbID, baseMB, callback, dbInterfaceName ):
def createEntityLocally( entityType, *params ):
def debugTracing( ):
def delWatcher( path ):
def deleteEntityByDBID( entityType, dbID, callback, dbInterfaceName ):
def deregisterReadFileDescriptor( fileDescriptor ):
def deregisterWriteFileDescriptor( fileDescriptor ):
def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):
def genUUID64( ):
def getResFullPath( res ):
def getWatcher( path ):
def getWatcherDir( path ):
def getAppFlags( ):
def hasRes( res ):
def isShuttingDown( ):
def listPathRes( path, extension ):
def lookUpEntityByDBID( entityType, dbID, callback, dbInterfaceName ):
def matchPath( res ):
def open( res, mode ):
def publish( ):
def quantumPassedPercent( ):
def registerReadFileDescriptor( fileDescriptor, callback ):
def registerWriteFileDescriptor( fileDescriptor, callback ):
def reloadScript( fullReload ):
def scriptLogType( logType ):
def setAppFlags( flags ):
def time( ):

回调函数

def onBaseAppReady( isBootstrap ):
def onBaseAppShutDown( state ):
def onCellAppDeath( addr ):
def onFini( ):
def onBaseAppData( key, value ):
def onBaseAppDataDel( key ):
def onGlobalData( key, value ):
def onGlobalDataDel( key ):
def onInit( isReload ):
def onLoseChargeCB( orderID, dbID, success, datas ):
def onReadyForLogin( isBootstrap ):
def onReadyForShutDown( ):
def onAutoLoadEntityCreate( entityType, dbID ):

属性

LOG_ON_ACCEPT |
LOG_ON_REJECT |
LOG_ON_WAIT_FOR_DESTROY |
LOG_TYPE_DBG |
LOG_TYPE_ERR |
LOG_TYPE_INFO |
LOG_TYPE_NORMAL |
LOG_TYPE_WAR |
NEXT_ONLY |
component | 只读 string
entities | Entities
baseAppData | GlobalDataClient
globalData | GlobalDataClient

成员函数文档

def addWatcher( path, dataType, getFunction ):

功能说明：

与调试监视系统交互，允许用户向监视系统注册一个监视变量。

例：
>>> def countPlayers( ):
>>>     i = 0
>>>     for e in KBEngine.entities.values():
>>>     	if e.__class__.__name__ == "Avatar":
>>>     		i += 1
>>>     return i
>>>
>>> KBEngine.addWatcher( "players", "UINT32", countPlayers )

这个函数添加一个监视变量在"scripts/players"监视路径之下。函数countPlayers在观察者观察时被调用。

参数：
path | 创建监视的路径。
dataType | 监视变量的值类型。参考: 基本类型
getFunction | 这个函数当观察者检索该变量时调用。 这个函数不带参数返回一个代表监视变量的值。

def address( ):

功能说明：

返回内部网络接口的地址。

def MemoryStream( ):

功能说明：

返回一个新的MemoryStream对象。

MemoryStream对象存储的是二进制信息，提供这个类型是为了让用户能够方便的序列化与反序列化Python基本类型同时能与KBEngine底层序列化规则相同。

例如：你可以使用这个对象构造一个KBEngine能解析的网络数据包。

用法：
>>> s = KBEngine.MemoryStream()
>>> s
>>> b''
>>> s.append("UINT32", 1)
>>> s.pop("UINT32")
>>> 1

目前MemoryStream能够支持的类型仅为基本数据类型。参考: 基本类型

def charge( ordersID, dbID, byteDatas, pycallback ):

功能说明：

计费接口。

参数：
ordersID | string，订单ID。
dbID | uint64，实体的databaseID。
byteDatas | bytes，附带数据，由开发者自己解析和定义。
pycallback | 计费回调。 计费回调原型: (当在interfaces中调用KBEngine.chargeResponse后，如果某个订单设置过回调则该回调被调用) def on**ChargeCB(self, orderID, dbID, success, datas): ordersID：string，订单ID dbID：uint64，通常为entity的databaseID success：bool，是否成功 datas：bytes，附带数据，由开发者自己解析和定义

def createEntity( ):

功能说明：

KBEngine.createEntityLocally的别名.

def createEntityAnywhere( entityType, params, callback ):

功能说明：

创建一个新的Entity实体， 服务端可能选择任何的Baseapp来创建Entity实体。

这个方法应作为KBEngine.createEntityLocally的首选， 这样服务端会灵活地选择一个合适的Baseapp来创建实体。

函数参数需要提供创建的实体的类型，还有一个Python字典作为参数来初始化实体的值。

这个Python字典不需要用户提供所有的属性，没有提供的属性默认为实体定义文件".def"提供的默认值。

例子：
params = {
    "name" : "kbe", # base, BASE_AND_CLIENT
    "HP" : 100,	# cell, ALL_CLIENT, in cellData
    "tmp" : "tmp"	# baseEntity.tmp
}

def onCreateEntityCallback(entity)
    print(entity)

createEntityAnywhere("Avatar", params, onCreateEntityCallback)

参数：
entityType | string，指定要创建的Entity实体的类型。有效的实体类型在/scripts/entities.xml列出。
params | 可选参数, 一个Python字典对象。 如果一个指定的键是一个Entity属性，他的值会用来初始化这个Entity实体的属性。 如果这个键是一个Cell属性，它会被添加到Entity实体的'cellData'属性，这个'cellData'属性是一个Python字典， 然后在后面会用来初始化cell实体的属性。
callback | callback是一个可选的回调函数，当实体完成创建时被调用。回调函数带有一个参数，当成功的时候是Entity实体的entityCall，失败时是None。

返回：
通过回调返回Entity实体的entityCall。

def createEntityRemotely( entityType, baseMB, params, callback ):

功能说明：

通过baseMB参数在一个指定的baseapp上创建一个新的Entity实体。

应该将KBEngine.createEntityAnywhere方法作为首选。

函数参数需要提供创建的实体的类型，还有一个Python字典作为参数来初始化实体的值。

这个Python字典不需要用户提供所有的属性，没有提供的属性默认为实体定义文件".def"提供的默认值。

例子：
params = {
    "name" : "kbe", # base, BASE_AND_CLIENT
    "HP" : 100,	# cell, ALL_CLIENT, in cellData
    "tmp" : "tmp"	# baseEntity.tmp
}

def onCreateEntityCallback(entity)
    print(entity)

createEntityRemotely("Avatar", baseEntityCall, params, onCreateEntityCallback)

参数：
entityType | string，指定要创建的Entity实体的类型。有效的实体类型在/scripts/entities.xml列出。
baseMB | BaseEntityCall，这是一个Entity的EntityCall。实体将被创建在该Entity对应的Baseapp进程上。
params | 可选参数, 一个Python字典对象。 如果一个指定的键是一个Entity属性，他的值会用来初始化这个Entity实体的属性。 如果这个键是一个Cell属性，它会被添加到Entity实体的'cellData'属性，这个'cellData'属性是一个Python字典， 然后在后面会用来初始化cell实体的属性。
callback | callback是一个可选的回调函数，当实体完成创建时被调用。回调函数带有一个参数，当成功的时候是Entity实体的entityCall，失败时是None。

返回：
通过回调返回Entity实体的entityCall。

def createEntityFromDBID( entityType, dbID, callback, dbInterfaceName ):

功能说明：

从数据库里加载数据创建一个Entity实体。 这个新的Entity实体会在调用这个函数的Baseapp上创建。 如果该实体已经从数据库检出，那么将返回这个存在的Entity实体的引用。

参数：
entityType | string，指定要加载的Entity实体类型。实体类型在/scripts/entities.xml列出。
dbID | 指定要创建的实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。
callback | 这是一个可选的回调函数，当操作完成的时候它会被调用。回调函数带有3个参数：baseRef，databaseID和wasActive。 如果操作成功，baseRef会是一个entityCall或者是新创建的Entity实体的直接引用，databaseID会是实体的数据库ID，无论该实体是否已经激活 wasActive都会有所指示，如果wasActive是True则baseRef是已经存在的实体的引用(已经从数据库检出)。如果操作失败这三个参数的值，baseRef将会是None，databaseID将会是0，wasActive将会是False。 失败最常见的原因是实体在数据库里不存在，但偶尔也会出现其它错误比如说超时或者是分配ID失败。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

def createEntityAnywhereFromDBID( entityType, dbID, callback, dbInterfaceName ):

功能说明：

从数据库里加载数据创建一个Entity实体。 服务端可能选择任何的Baseapp来创建Entity实体。

使用这个函数将有助于BaseApps负载平衡。

如果该实体已经从数据库检出，那么将返回这个存在的Entity实体的引用。

参数：
entityType | string，指定要创建的Entity实体的类型。有效的实体类型在/scripts/entities.xml列出。
dbID | 这是一个指定要创建的实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。
callback | 这是一个可选的回调函数，当操作完成的时候它会被调用。回调函数带有3个参数：baseRef，databaseID和wasActive。 如果操作成功，baseRef会是一个entityCall或者是新创建的Entity实体的直接引用，databaseID会是实体的数据库ID，无论该实体是否已经激活 wasActive都会有所指示，如果wasActive是True则baseRef是已经存在的实体的引用(已经从数据库检出)。如果操作失败这三个参数的值，baseRef将会是None，databaseID将会是0，wasActive将会是False。 失败最常见的原因是实体在数据库里不存在，但偶尔也会出现其它错误比如说超时或者是分配ID失败。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

返回：
通过回调返回Entity实体的entityCall。

def createEntityRemotelyFromDBID( entityType, dbID, baseMB, callback, dbInterfaceName ):

功能说明：

从数据库里加载数据并通过baseMB参数在一个指定的baseapp上创建一个Entity实体。

如果该实体已经从数据库检出，那么将返回这个存在的Entity实体的引用。

参数：
entityType | string，指定要创建的Entity实体的类型。有效的实体类型在/scripts/entities.xml列出。
dbID | 这是一个指定要创建的实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。
baseMB | BaseEntityCall，这是一个Entity的EntityCall。实体将被创建在该Entity对应的Baseapp进程上。
callback | 这是一个可选的回调函数，当操作完成的时候它会被调用。回调函数带有3个参数：baseRef，databaseID和wasActive。 如果操作成功，baseRef会是一个entityCall或者是新创建的Entity实体的直接引用，databaseID会是实体的数据库ID，无论该实体是否已经激活 wasActive都会有所指示，如果wasActive是True则baseRef是已经存在的实体的引用(已经从数据库检出)。如果操作失败这三个参数的值，baseRef将会是None，databaseID将会是0，wasActive将会是False。 失败最常见的原因是实体在数据库里不存在，但偶尔也会出现其它错误比如说超时或者是分配ID失败。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

返回：
通过回调返回Entity实体的entityCall。

def createEntityLocally( entityType, params ):

功能说明：

创建一个新的Entity实体。
函数参数需要提供创建的实体的类型，还有一个Python字典作为参数来初始化实体的值。

这个Python字典不需要用户提供所有的属性，没有提供的属性默认为实体定义文件".def"提供的默认值。

KBEngine.createEntityAnywhere应该作为这个方法的首选，因为服务端可以灵活地 在合适的Baseapp上创建实体。

例子：
params = {
    "name" : "kbe", # base, BASE_AND_CLIENT
    "HP" : 100,	# cell, ALL_CLIENT, in cellData
    "tmp" : "tmp"	# baseEntity.tmp
}

baseEntity = createEntityLocally("Avatar", params)

参数：
entityType | string，指定要创建的Entity实体的类型。有效的实体类型在/scripts/entities.xml列出。
params | 可选参数, 一个Python字典对象。 如果一个指定的键是一个Entity属性，他的值会用来初始化这个Entity实体的属性。 如果这个键是一个Cell属性，它会被添加到Entity实体的'cellData'属性，这个'cellData'属性是一个Python字典， 然后在后面会用来初始化cell实体的属性。

返回：
新创建的Entity实体（参考Entity）

def debugTracing( ):

功能说明：

输出当前KBEngine追踪的Python扩展对象计数器。
扩展对象包括：固定字典、固定数组、Entity、EntityCall...
在服务端正常关闭时如果计数器不为零，此时说明泄露已存在，日志将会输出错误信息。

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)

参数：
path 要删除的变量的路径。

def delWatcher( path ):

功能说明：

与调试监视系统交互，允许用户在脚本删除监视的变量。

参数：
path 要删除的变量的路径。

def deleteEntityByDBID( entityType, dbID, callback, dbInterfaceName ):

功能说明：

从数据库删除指定的实体（包括属性所产生的子表数据），如果实体没有从数据库检出则删除成功， 如果实体已经从数据库检出那么KBEngine服务系统将会删除失败，并且从回调中返回 Entity实体的entityCall。

参数：
entityType | string，指定要删除的Entity实体的类型。有效的实体类型在/scripts/entities.xml列出。
dbID | 指定要删除的实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。
callback | callback是一个可选的回调函数，只有一个参数，当实体没有从数据库检出时将会成功删除数据，参数是True。如果实体已经从数据库检出那么参数是Entity实体的entityCall。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

def deregisterReadFileDescriptor( fileDescriptor ):

功能说明：

注销已经通过KBEngine.registerReadFileDescriptor注册的回调。

例子:
http://www.kbengine.org/assets/other/py/Poller.py

参数：
fileDescriptor socket描述符/文件描述符。

def deregisterWriteFileDescriptor( fileDescriptor ):

功能说明：

注销已经通过KBEngine.registerWriteFileDescriptor注册的回调。

例子:
http://www.kbengine.org/assets/other/py/Poller.py

参数：
fileDescriptor socket描述符/文件描述符。

def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):

功能说明：

这个脚本函数在数据库上执行原始数据库命令，该命令将直接由相关数据库进行解析。

请注意使用该函数修改实体数据可能不生效，因为如果实体已经检出，被修改过的实体数据将仍会被实体存档而导致覆盖。
强烈不推荐这个函数用于读取或修改实体数据。

参数：
command | 这个数据库命令将会因为不同数据库配置方案而不同。对于方案为MySQL数据库它是一个SQL查询语句。
callback

可选参数，带有命令执行结果的回调对象（比如说是一个函数）。这个回调带有4个参数：结果集合，影响的行数，自増长值，错误信息。
声明样例：
def sqlcallback(result, rows, insertid, error):
print(result, rows, insertid, error)

如同上面的例子所示，result参数对应的就是“结果集合”，这个结果集合参数是一个行列表。 每一行是一个包含字段值的字符串列表。
命令执行没有返回结果集合（比如说是DELETE命令）， 或者 命令执行有错误时这个结果集合为None。

rows参数则是“影响的行数”，它是一个整数，表示命令执行受影响的行数。这个参数只和不返回结果结合的命令（如DELETE）相关。
如果有结果集合返回或者命令执行有错误时这个参数为None。

insertid对应的是“自増长值”，类似于实体的databaseID，当成功的向一张带有自増长类型字段的表中插入数据时，它返回该数据在插入时自増长字段所被赋于的值。
更多的信息可以参阅mysql的mysql_insert_id()方法。另外，此参数仅在数据库类型为mysql时有意义。

error则对应了“错误信息”，当命令执行有错误时，这个参数是一个描述错误的字符串。命令执行没有发生错误时这个参数为None。

threadID int32，可选参数，指定一个线程来处理本条命令。用户可以通过这个参数控制某一类命令的执行先后顺序（dbmgr是多线程处理的），默认是不指定，如果threadID是实体的ID，
那么将加入到该实体的存档队列中由线程逐条写入。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

def genUUID64( ):

功能说明：

该函数生成一个64位的唯一ID。
注意：这个函数依赖于Baseapps服务进程启动参数gus，请正确设置启动参数保持唯一性。
另外如果gus超过65535则该函数只能在当前进程上保持唯一性。

用途：
多个服务进程上产生唯一物品ID并且在合服时不会产生冲突。
多个服务进程上产生一个房间ID，不需要进行唯一性校验。

返回：
返回一个64位的integer。

def getResFullPath( res ):

功能说明：

获取资源的绝对路径。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

参数：
res string，资源的相对路径。

返回：
string，如果存在返回资源的绝对路径，否则返回空。

def getWatcher( path ):

功能说明：

从KBEngine调试系统中获取一个监视变量的值。

例子：在baseapp1的Python命令行输入:
>>>KBEngine.getWatcher("/root/stats/runningTime")
12673648533

>>>KBEngine.getWatcher("/root/scripts/players")
32133

参数：
path string，该变量的绝对路径包括变量名(可以在GUIConsole的watcher页查看)。

返回：
该变量的值。

def getWatcherDir( path ):

功能说明：

从KBEngine调试系统中获取一个监视目录下的元素列表(目录、变量名)。

例子：在baseapp1的Python命令行输入:
>>>KBEngine.getWatcher("/root")
('stats', 'objectPools', 'network', 'syspaths', 'ThreadPool', 'cprofiles', 'scripts', 'numProxices', 'componentID', 'componentType', 'uid', 'numClients', 'globalOrder', 'username', 'load', 'gametime', 'entitiesSize', 'groupOrder')

参数：
path string，该变量的绝对路径(可以在GUIConsole的watcher页查看)。

返回：
监视目录下的元素列表(目录、变量名)。

def getAppFlags( ):

功能说明：

获取当前引擎APP的标记, 参考:KBEngine.setAppFlags。

返回：
KBEngine.APP_FLAGS_*。

def hasRes( res ):

功能说明：

使用这个接口可以判断一个相对路径的资源是否存在。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

例子:

>>>KBEngine.hasRes("scripts/entities.xml")
True

参数：
res string，资源的相对路径。

返回：
BOOL, 存在返回True，否则返回False。

def isShuttingDown( ):

功能说明：

返回服务端是否正在关闭中。
在onBaseAppShutDown(state=0)回调函数被调用后，这个函数返回True。

返回：
系统正在关闭返回True，否则返回False。

def listPathRes( path, extension ):

功能说明：

获得一个资源目录下的资源列表。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

例子:

>>>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')

参数：
res | string，资源的相对路径。
extension | string，可选参数，扩展名。

返回：
Tuple, 资源列表。

def lookUpEntityByDBID( entityType, dbID, callback, dbInterfaceName ):

功能说明：

查询一个实体是否从数据库检出， 如果实体已经从数据库检出那么KBEngine服务系统将从回调中返回Entity实体的entityCall。

参数：
entityType | string，指定要查询的Entity实体的类型。有效的实体类型在/scripts/entities.xml列出。
dbID | 指定要查询的Entity实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。
callback | callback只有一个参数，当实体没有从数据库检出时将会返回True。如果实体已经从数据库检出那么将返回Entity实体的entityCall, 其他任何情况返回False。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

def matchPath( res ):

功能说明：

使用相对路径的资源获得资源的绝对路径。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

例子:

>>>KBEngine.matchPath("scripts/entities.xml")
'/home/kbe/kbengine/demo/res/scripts/entities.xml'

参数：
res string，资源的相对路径(包括资源名称)。

返回：
string, 资源的绝对路径。

def open( res, mode ):

功能说明：

使用这个接口可以使用相对路径来打开相关资源。
注意：资源必须在KBE_RES_PATH之下才可以访问到。

参数：
res | string，资源的相对路径。
mode | string，文件操作模式： w 以写方式打开， a 以追加模式打开 (从 EOF 开始, 必要时创建新文件) r+ 以读写模式打开 w+ 以读写模式打开 (参见 w ) a+ 以读写模式打开 (参见 a ) rb 以二进制读模式打开 wb 以二进制写模式打开 (参见 w ) ab 以二进制追加模式打开 (参见 a ) rb+ 以二进制读写模式打开 (参见 r+ ) wb+ 以二进制读写模式打开 (参见 w+ ) ab+ 以二进制读写模式打开 (参见 a+ )

def publish( ):

功能说明：

这个接口返回当前服务端发行模式。

返回：
int8，0：debug，1：release，其它可自定义。

def quantumPassedPercent( ):

功能说明：

返回取得当前tick占用一个时钟周期的百分比。

返回：
返回取得当前tick占用一个时钟周期的百分比。

def registerReadFileDescriptor( fileDescriptor, callback ):

功能说明：

注册一个回调函数，这个回调函数当文件描述符可读时被调用。

例子:
http://www.kbengine.org/assets/other/py/Poller.py

参数：
fileDescriptor | socket描述符/文件描述符。
callback | 一个回调函数，socket描述符/文件描述符作为它的唯一参数。

def registerWriteFileDescriptor( fileDescriptor, callback ):

功能说明：

注册一个回调函数，这个回调函数当socket描述符/文件描述符可写时被调用。

例子:
http://www.kbengine.org/assets/other/py/Poller.py

参数：
fileDescriptor | socket描述符/文件描述符。
callback | 一个回调函数，socket描述符/文件描述符作为它的唯一参数。

def reloadScript( fullReload ):

功能说明：

重新加载与实体和自定义数据类型相关的Python模块。当前实体类会设置为新加载的类。 这个方法应该只用于开发模式，对于产品模式不合适。下面几点应该注意：

1）重载脚本仅仅能在Baseapp上执行， 用户应该确保所有的服务端组件加载完成。

2）自定义类型在脚本重载后应该确保内存中已经实例化的对象也被更新，下面是一个例子:

for e in KBEngine.entities.values():
   if type( e ) is Avatar.Avatar:
      e.customData.__class__ = CustomClass
当这个方法完成时 KBEngine.onInit( True ) 被调用。

参数：
fullReload 可选的boolean参数，指定是否同时重新加载实体定义。如果这个参数为False，则实体定义不会被重新加载。默认为True。

返回：
重新加载成功返回True，否则返回False。

def scriptLogType( logType ):

功能说明：

设置当前Python.print输出的信息类型(参考: KBEngine.LOG_TYPE_*)。

def setAppFlags( flags ):

功能说明：

设置当前引擎APP的标记。

KBEngine.APP_FLAGS_NONE // 默认的(未设置标记)
KBEngine.APP_FLAGS_NOT_PARTCIPATING_LOAD_BALANCING //不参与负载均衡

例如：
KBEngine.setAppFlags(KBEngine.APP_FLAGS_NOT_PARTCIPATING_LOAD_BALANCING | KBEngine.APP_FLAGS_*)

def time( ):

功能说明：

这个方法返回当前游戏的时间（周期数）。

返回：
uint32，当前游戏的时间，这里指周期数，周期受频率影响，频率由配置文件kbengine.xml或者kbengine_defaults.xml->gameUpdateHertz决定。

回调函数文档

def onBaseAppReady( isBootstrap ):

功能说明：

当前Baseapp进程已经准备好的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
isBootstrap bool，是否为第一个启动的Baseapp。

def onBaseAppShutDown( state ):

功能说明：

Baseapp关闭过程会回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
state 如果state为0，意指在断开所有客户端之前，如果state为1，意指在将所有实体写入数据库之前，如果state为2，意指在所有实体被写入数据库之后。

def onCellAppDeath( addr ):

功能说明：

某个cellapp死亡会回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
addr 死亡的cellapp地址。
tuple:(ip, port) 网络字节序

def onFini( ):

功能说明：

引擎正式关闭后回调此函数。
注意：该回调接口必须实现在入口模块kbengine_defaults.xml->entryScriptFile)中。

def onBaseAppData( key, value ):

功能说明：

KBEngine.baseAppData有改变时回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
key | 被改变数据的键。
value | 被改变数据的值。

def onBaseAppDataDel( key ):

功能说明：

KBEngine.baseAppData有删除的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
key 被删除数据的键。

def onGlobalData( key, value ):

功能说明：

KBEngine.globalData有改变的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
key | 被改变数据的键。
value | 被改变数据的值。

def onGlobalDataDel( key ):

功能说明：

KBEngine.globalData有删除的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
key 被删除数据的键。

def onInit( isReload ):

功能说明：

当引擎启动后初始化完所有的脚本后这个接口被调用。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
isReload bool，是否是被重写加载脚本后触发的。

def onLoseChargeCB( orderID, dbID, success, datas ):

功能说明：

当在interfaces中调用KBEngine.chargeResponse后，如果该订单丢失或者是不明interfaces未被记录的订单会收到此回调通知。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
ordersID | string，订单ID。
dbID | uint64，实体的数据库ID, 参见: Entity.databaseID。
success | bool，是否成功。
datas | bytes，附带信息。

def onReadyForLogin( isBootstrap ):

功能说明：

当引擎启动并初始化完成后会一直调用此接口询问脚本层是否准备完毕，如果脚本层准备完毕则loginapp允许客户端登录。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
isBootstrap bool，是否为第一个启动的Baseapp。

返回：
返回值大于等于1.0则脚本层准备完成，否则返回准备的进度值0.0~1.0。

def onReadyForShutDown( ):

功能说明：

如果这个函数在脚本中有实现，当进程准备退出时，该回调函数被调用。

可以通过该回调控制进程退出的时机。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

返回：
bool，如果返回True，则允许进入进程退出流程，返回其它值则进程会过一段时间后再次询问。

def onAutoLoadEntityCreate( entityType, dbID ):

功能说明：

自动加载的实体创建时的回调，如果脚本层实现此回调，那么实体由脚本层创建，否则引擎默认使用createEntityAnywhereFromDBID来创建实体。

这个回调被调用是由于Entity.writeToDB时设置了实体自动加载。
注：该回调优先于onBaseAppReady执行，可在onBaseAppReady时检查是否已加载实体。

参数：
entityType | string，指定要查询的Entity实体的类型。有效的实体类型在/scripts/entities.xml列出。
dbID | 指定要查询的Entity实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。

属性文档

LOG_ON_ACCEPT

说明：

这个常量由Proxy.onLogOnAttempt返回，意指允许新的client与一个Proxy实体绑定。
如果Proxy实体已经存在一个client绑定关系，那么将踢出之前的client。

LOG_ON_REJECT

说明：

这个常量由Proxy.onLogOnAttempt返回，意指拒绝当前client与Proxy实体绑定。

LOG_ON_WAIT_FOR_DESTROY

说明：

这个常量由Proxy.onLogOnAttempt返回，当前请求client将会等待直到Proxy实体完全销毁，底层再完成后续绑定过程。 在这返回之前Proxy.destroy或者Proxy.destroyCellEntity 应该被调用。

LOG_TYPE_DBG

说明：

日志输出类型为调试类型。
由scriptLogType设置。

LOG_TYPE_ERR

说明：

日志输出类型为错误类型。
由scriptLogType设置。

LOG_TYPE_INFO

说明：

日志输出类型为常规信息类型。
由scriptLogType设置。

LOG_TYPE_NORMAL

说明：

日志输出类型为常规类型。
由scriptLogType设置。

LOG_TYPE_WAR

说明：

日志输出类型为警告类型。
由scriptLogType设置。

NEXT_ONLY

说明：

这个常量用于Entity.shouldAutoBackup和Entity.shouldAutoArchive属性。这个值意指在下一次认为可以的时候自动备份该实体，然后这个属性自动设为False（0）。

component

说明：

这是正运行在当前Python环境的组件。（至今为止）可能值有'cell', 'base', 'client', 'database', 'bot' 和 'editor'。

entities

说明：

entities是一个字典对象，包含当前进程上所有的实体。
调试泄露的实体（调用过destroy却没有释放内存的实体，通常是由于被引用导致无法释放）：
>>> KBEngine.entities.garbages.items()
[(1025, Avatar object at 0x7f92431ceae8.)]

>>> e = _[0][1]
>>> import gc
>>> gc.get_referents(e)
[{'spacesIsOk': True, 'bootstrapIdx': 1}, ]

调试泄露的KBEngine封装的Python对象：
KBEngine.debugTracing

类型：
Entities

baseAppData

说明：

这个属性包含一个类字典的对象，这个对象会在所有的BaseApps之间自动同步。 当字典的一个值被修改，这个修改会广播到所有的BaseApps。

例子：
KBEngine.baseAppData[ "hello" ] = "there"

其余BaseApps可以访问下面的：
print KBEngine.baseAppData[ "hello" ]

键和值可以是任意类型，但这些类型必须在所有目标组件上能够被封装和被拆封。

当一个值被改变或被删除，一个回调函数会在所有组件被调用。 参看：KBEngine.onBaseAppData和KBEngine.onDelBaseAppData。

注意：只有顶层的值才会被广播，如果你有一个值（比如一个列表），它改变了内部的值（比如只是改变一个数），这个信息不会被广播。

不要进行下面的操作：
KBEngine.baseAppData[ "list" ] = [1, 2, 3]
KBEngine.baseAppData[ "list" ][1] = 7
这样，本地访问是[1, 7, 3]，远程访问是[1, 2, 3]。

globalData

说明：

这个属性包含一个类字典的对象，这个对象会在所有的BaseApps和CellApps之间自动同步。 当字典的一个值被修改，这个修改会广播到所有的BaseApps和CellApps。

例子：
KBEngine.globalData[ "hello" ] = "there"

其余Baseapp或者 Cellapp可以访问下面的：
print KBEngine.globalData[ "hello" ]

键和值可以是任意类型，但这些类型必须在所有目标组件上能够被封装和被拆封。

当一个值被改变或被删除，一个回调函数会在所有组件被调用。 参看：KBEngine.onGlobalData和KBEngine.onGlobalDataDel。

注意：只有顶层的值才会被广播，如果你有一个值（比如一个列表），它改变了内部的值（比如只是改变一个数），这个信息不会被广播。

不要进行下面的操作：
KBEngine.globalData[ "list" ] = [1, 2, 3]
KBEngine.globalData[ "list" ][1] = 7
这样，本地访问是[1, 7, 3]，远程访问是[1, 2, 3]。


Entity - KBEngine base 文档

Entity类

[KBEngine模块]

Entity是KBEngine模块的一部分。 更多...

import KBEngine

成员函数

def addTimer( self, initialOffset, repeatOffset=0, userArg=0 ):
def createCellEntity( self, cellEntityMB ):
def createCellEntityInNewSpace( self, cellappIndex ):
def delTimer( self, id ):
def destroy( self, deleteFromDB, writeToDB ):
def destroyCellEntity( self ):
def teleport( self, baseEntityMB ):
def writeToDB( self, callback, shouldAutoLoad, dbInterfaceName ):

回调函数

def onCreateCellFailure( self ):
def onDestroy( self ):
def onGetCell( self ):
def onLoseCell( self ):
def onPreArchive( self ):
def onRestore( self ):
def onTimer( self, timerHandle, userData ):
def onTeleportFailure( self ):
def onTeleportSuccess( self, nearbyEntity ):
def onWriteToDB( self, cellData ):

属性

cell | 只读 CellEntityCall
cellData | CELLDATADICT
className | 只读 string
client | 只读 ClientEntityCall
databaseID | 只读 int64
databaseInterfaceName | 只读 string
id | 只读 int32
isDestroyed | bool
shouldAutoArchive | True, False or KBEngine.NEXT_ONLY
shouldAutoBackup | True, False or KBEngine.NEXT_ONLY

详细描述

Entity类代表一个驻留在Baseapp上的实体。 Entity 实体可以通过KBEngine.createEntity函数(以及以createEntity为前缀的函数)创建。一个Entity实体也可以通过Cellapp的函数KBEngine.createEntityOnBaseApp远程创建。

一个Entity实体可以在一个活动的cells里面链接到一个实体，还可以被用来在一个合适的cell上创建一个关联的实体。 这个类允许你创建和销毁在cell上的实体或者在base实体上注册一个定时器也或者访问此对象的联系信息，
还可以访问一个CellEntityCall，通过它这个base实体可以与它的cell实体通信（这个被关联的cell实体可以移动到不同cell上，作为该cell实体移动的结果KBEngine会进行负载均衡）。

成员函数文档

def addTimer( self, initialOffset, repeatOffset=0, userArg=0 ):

功能说明：

注册一个定时器，定时器由回调函数onTimer触发，回调函数将在"initialOffset"秒后被执行第1次，而后将每间隔"repeatOffset"秒执行1次，可设定一个用户参数"userArg"（仅限integer类型）。

onTimer 函数必须在entity的base部分被定义，且带有2个参数，第1个integer类型的是timer的id（可用于移除timer的"delTimer"函数），第2个是用户参数"userArg"。

例子:
# 这里是使用addTimer的一个例子
import KBEngine

class MyBaseEntity( KBEngine.Entity ):

    def __init__( self ):
        KBEngine.Entity.__init__( self )

        # 增加一个定时器，5秒后执行第1次，而后每1秒执行1次，用户参数是9
        self.addTimer( 5, 1, 9 )

        # 增加一个定时器，1秒后执行，用户参数缺省是0
        self.addTimer( 1 )

    # Entity的定时器回调"onTimer"被调用
    def onTimer( self, id, userArg ):
        print "MyBaseEntity.onTimer called: id %i, userArg: %i" % ( id, userArg )
        # if 这是不断重复的定时器，当不再需要该定时器的时候，调用下面函数移除:
        #     self.delTimer( id )

参数：
initialOffset | float，指定定时器从注册到第一次回调的时间间隔（秒）。
repeatOffset | float，指定第一次回调执行后每次执行的时间间隔（秒）。必须用函数delTimer移除定时器，否则它会一直重复下去。值小于等于0将被忽略。
userArg | integer，指定底层回调"onTimer"时的userArg参数值。

返回:
integer，该函数返回timer的内部id，这个id可用于delTimer移除定时器。

def createCellEntity( self, cellEntityMB ):

功能说明：

请求在一个cell里面创建一个关联的实体。

用于创建cell实体的信息被存储在该实体的属性cellData里。这个属性是一个字典，对应实体的.def文件里的默认值，同时还包括用于表示
实体位置和方向(roll, pitch, yaw)的"position", "direction" 和 "spaceID"。

参数：
cellEntityMB 一个可选的CellEntityCall参数， 指定哪个空间里创建这个cell实体的。

只能使用一个直接的CellEntityCall。如果你有一个实体的BaseEntityCall，你不可以使用baseEntityCall.cell传给这个函数。
你必须在这个实体的base上创建一个新的函数来回传这个直接的CellEntityCall。

例如：
baseEntityCallOfNearbyEntity.createCellNearSelf( self )
在实体的base上：
def createCellNearSelf( self, baseEntityCall ):
    baseEntityCall.createCellNearHere( self.cell )
在原实体的base上调用createCellNearSelf()方法：
def createCellNearHere( self. cellEntityCall ):
    self.createCellEntity( cellEntityCall )

def createCellEntityInNewSpace( self, cellappIndex ):

功能说明：

在cellapp上创建一个空间(space)并且将该实体的cell创建到这个新的空间中，它请求通过cellappmgr来完成。

用于创建cell实体的信息被存储在该实体的属性cellData里。这个属性是一个字典，对应实体的.def文件里的默认值同时还包括用于表示
实体位置和方向(roll, pitch, yaw)的"position", "direction" 和 "spaceID"。

参数：
cellappIndex integer，为None或者0则由引擎负载均衡进行动态选择，如果大于0则在指定的cellapp中创建space。
例子：假如预期会开启4个cellapp，那么cellappIndex需要指定时索引可以是1、2、3、4，
如果实际运行的cellapp不足4个，例如只有3个，那么cellappIndex输入4时由于数量溢出4代表1，如果输入5则代表2。

提示：此功能可以结合KBngine.setAppFlags(KBEngine.APP_FLAGS_NOT_PARTCIPATING_LOAD_BALANCING)来使用，例如：将大地图space放到几个固定的cellapp中，并将这些cellapp设置为不参与负载均衡，其他cellapp用于放置副本space。 创建副本space时cellappIndex设置为0或者None，副本地图的消耗将不会影响到大地图进程，从而保证了主场景的流畅。

def delTimer( self, id ):

功能说明：

函数delTimer用于移除一个注册的定时器，移除后的定时器不再执行。只执行1次的定时器在执行回调后自动移除，不必要使用delTimer移除。 如果delTimer函数使用一个无效的id（例如已经移除），将会产生错误。

到Entity.addTimer参考定时器的一个使用例子。

参数：
id integer，它指定要移除的定时器id。

def destroy( self, deleteFromDB, writeToDB ):

功能说明：

这个函数销毁该实体的base部分。如果实体存在cell部分，那么用户必须先销毁cell部分，否则将会产生错误。要销毁实体的cell部分，调用Entity.destroyCellEntity。

也许在onLoseCell回调里调用self.destroy更为恰当。这能保证实体的base部分被销毁。

参数：
deleteFromDB | 如果是True，在数据库里与这个实体有关联的条目将会被删除，该参数默认为False。
writeToDB | 如果是True，与这个实体相关联的存档属性将会写入数据库。只有在这个实体是从数据库读取的或者是使用过Entity.writeToDB写入数据库才会被执行。这个参数默认为True，但当deleteFromDB为True的时候它将被忽略。

def destroyCellEntity( self ):

功能说明：

destroyCellEntity请求销毁关联的cell实体。如果没有关联的cell实体该方法将会产生错误。

def teleport( self, baseEntityMB ):

功能说明：

teleport会瞬移这个实体的cell部分到参数指定的实体所在的空间。

在抵达新的空间后，Entity.onTeleportSuccess被调用。这可以用来在新的空间里移动该实体到合适的位置。

参数：
baseEntityMB 实体应该移到的指定实体所在的空间，baseEntityMB即指定实体的EntityCall。当成功的时候，与此参数相关联的cell实体会被传入到Entity.onTeleportSuccess函数。

def writeToDB( self, callback, shouldAutoLoad, dbInterfaceName ):

功能说明：

该函数保存这个实体的存档属性到数据库，使得以后需要的时候可以重新从数据库加载。

实体也可以被标记为自动加载，这样当服务启动后实体将会被重新创建。

参数：
callback | 这个可选参数是当数据库操作完成后的回调函数。 它有两个参数。第一个是boolean类型标志成功或失败，第二个是base实体。
shouldAutoLoad 这个可选参数指定这个实体在服务启动的时候是否需要从数据库加载。
注意：服务器启动时自动加载实体，底层默认将会调用createEntityAnywhereFromDBID将实体创建到一个负载最小的baseapp上，整个过程将会在第一个启动的baseapp调用onBaseAppReady之前完成。

脚本层可以在个性化脚本(kbengine_defaults.xml->baseapp->entryScriptFile定义)中重新实现实体的创建方法，例如：
def onAutoLoadEntityCreate(entityType, dbid):
KBEngine.createEntityFromDBID(entityType, dbid)
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

回调函数文档

def onCreateCellFailure( self ):

功能说明：

如果这个函数在脚本中有实现，这个函数在cell实体创建失败的时候被调用。 这个函数没有参数。

def onDestroy( self ):

功能说明：

如果这个函数在脚本中有实现，这个函数在调用Entity.destroy()后，在实际销毁之前被调用。 这个函数没有参数。

def onGetCell( self ):

功能说明：

如果这个函数在脚本中有实现，这个函数在它获得cell实体的时候被调用。 这个函数没有参数。

def onLoseCell( self ):

功能说明：

如果这个函数在脚本中有实现，这个函数在它关联的cell实体销毁之后被调用。 这个函数没有参数。

def onPreArchive( self ):

功能说明：

如果这个函数在脚本中有实现，这个函数在该实体自动写入数据库之前被调用。这个回调在Entity.onWriteToDB回调之前被调用。
如果该回调返回False，该归档操作中止。这个回调应该返回True使得操作继续。如果这个回调不存在，则归档操作继续进行。

def onRestore( self ):

功能说明：

如果这个函数在脚本中有实现，这个函数在Entity应用程序崩溃后在其它Entity应用程序上 重新创建该实体时被调用。 这个函数没有参数。

def onTimer( self, timerHandle, userData ):

功能说明：

这个函数当一个与此实体关联的定时器触发的时候被调用。 一个定时器可以使用Entity.addTimer函数添加。

参数：
timerHandle | 定时器的id。
userData | 传进Entity.addTimer的integer用户数据。

def onTeleportFailure( self ):

如果这个函数在脚本中有实现，当用户调用Entity.teleport失败时该回调被调用。

def onTeleportSuccess( self, nearbyEntity ):

如果这个函数在脚本中有实现，当用户调用Entity.teleport成功时该回调被调用。

参数：
nearbyEntity 这个参数由用户调用 Entity.teleport时给出。这是一个real实体。

def onWriteToDB( self, cellData ):

功能说明：

如果这个函数在脚本中有实现，这个函数在实体数据将要写进数据库的时候被调用。

需要注意的是在该回调里调用writeToDB会导致无限循环。

参数：
cellData 包含将要存进数据库的cell属性。 cellData是一个字典。

属性文档

cell

说明：

cell是用于联系cell实体的ENTITYCALL。这个属性是只读的，且如果这个base实体没有关联的cell时属性是None。

类型：
只读 ENTITYCALL

cellData

说明：

cellData是一个字典属性。每当base实体没有创建它的cell实体时，cell实体的属性会保存在这里。

如果cell实体被创建，这些用到的值和cellData属性将被删除。除了cell实体在实体定义文件里指定的属性外，它还包含position, direction and spaceID。

类型：
CELLDATADICT

className

说明：

实体的类名。

类型：
只读，string

client

说明：

client是用于联系客户端的EntityCall。这个属性是只读的，且如果这个base实体没有关联的客户端时属性是None。

类型：
只读 ENTITYCALL

databaseID

说明：

databaseID是实体的永久ID(数据库id)。这个id是uint64类型且大于0，如果是0则表示该实体不是永久的。

类型：
只读 int64

databaseInterfaceName

说明：

databaseInterfaceName是实体持久化所在的数据库接口名称，该接口名称在kbengine_defaults->dbmgr中配置。实体必须持久化过（databaseID>0）该属性才可用，否则返回空字符串。

类型：
只读 string

id

说明：

id是实体的对象id。这个id是一个整型，在base，cell和client相关联的实体之间是相同的。 这个属性是只读的。

类型：
只读 int32

isDestroyed

说明：

如果该Entity实体已经被销毁了，这个属性为True。

类型：
bool

shouldAutoArchive

说明：

这个属性决定了自动存档的策略。如果设为True，自动存档将可用，如果设为False，自动存档将不可用。 如果设为KBEngine.NEXT_ONLY，自动存档将在下一个预定的时间可用， 在下一次存档后，这个属性将置为False。

类型：
True, False or KBEngine.NEXT_ONLY

shouldAutoBackup

说明：

这个属性决定了自动备份的策略。如果设为True，自动备份将可用，如果设为False，自动备份将不可用。 如果设为KBEngine.NEXT_ONLY，自动备份将在下一个预定的时间可用， 在下一次备份后，这个属性将置为False。

类型：
True, False or KBEngine.NEXT_ONLY


Proxy - KBEngine base 文档

Proxy类

[KBEngine模块]

Proxy是KBEngine模块的一部分。 更多...

import KBEngine

父类

Entity

成员函数

def disconnect( self ):
def getClientType( self ):
def getClientDatas( self ):
def giveClientTo( self, proxy ):
def streamFileToClient( self, resourceName, desc="", id=-1 ):
def streamStringToClient( self, data, desc="", id=-1 ):

回调函数

def onClientDeath( self ):
def onClientGetCell( self ):
def onClientEnabled( self ):
def onGiveClientToFailure( self ):
def onLogOnAttempt( self, ip, port, password ):
def onStreamComplete( self, id, success ):

属性

__ACCOUNT_NAME__ | 只读 string
__ACCOUNT_PASSWORD__ | 只读 string
clientAddr | 只读
clientEnabled | 只读 bool
hasClient | 只读 bool
roundTripTime | 只读
timeSinceHeardFromClient | 只读

详细描述

Proxy是Entity的一个特殊类型，它继承自Entity，它有一个关联的客户端。本身来说， 它就是一个代理客户端的实体，操控所有服务端向客户端的更新。不能在脚本直接创建Proxy类对象。

成员函数文档

def disconnect( self ):

断开客户端连接。

def getClientType( self ):

功能说明：

这个函数返回客户端类型。

返回:
UNKNOWN_CLIENT_COMPONENT_TYPE = 0,
CLIENT_TYPE_MOBILE = 1, // 手机类
CLIENT_TYPE_WIN = 2, // pc， 一般都是exe客户端
CLIENT_TYPE_LINUX = 3 // Linux Application program
CLIENT_TYPE_MAC = 4 // Mac Application program
CLIENT_TYPE_BROWSER = 5, // web应用， html5，flash
CLIENT_TYPE_BOTS = 6, // bots
CLIENT_TYPE_MINI = 7, // Mini-Client
CLIENT_TYPE_END = 8 // end

def getClientDatas( self ):

功能说明：

这个函数返回客户端登录时和注册时所附带的数据。
此数据可用于运营系统扩展，如果连接了第三方账号服务，此数据会经过interfaces进程发往第三方服务系统。

返回:
tuple, 固定为2个元素的tuple(登陆数据bytes，注册数据bytes)，第一个元素为登陆时客户端调用登陆时传入的datas参数， 第二个元素为注册时客户端调用注册所传入的datas参数。由于可以存储任意二进制数据，因此他们都是以bytes类型存在。

def giveClientTo( self, proxy ):

功能说明：

将客户端的控制器转交给另一个Proxy，当前的Proxy必须有一个客户端而目标Proxy则必须没有关联客户端，否则将会提示错误。

参看：
Proxy.onGiveClientToFailure

参数：
proxy 控制权将转交给这个实体。

def streamFileToClient( self, resourceName, desc="", id=-1 ):

功能说明：

这个函数类似于streamStringToClient()，将一个资源文件发送给客户端。发送过程在不同的线程上操作，因此不会危及主线程。

参看：
Proxy.onStreamComplete

参数：
resourceName | 要发送的资源名称，包含路径。
desc | 一个可选的字符串，发送给客户端的资源描述。
id | 一个16位的id，它的值完全取决于调用者。如果传入-1系统将会在队列里面选择一个没有在用的id。可以在客户端根据这个id做资源判断。

返回：
与这个下载关联的id。

def streamStringToClient( self, data, desc="", id=-1 ):

功能说明：

发送一些数据到当前实体绑定的客户端。如果客户端端口则数据被清除， 当客户端再次绑定到实体的时候才可调用这个函数。16位的id完全取决于调用者。
如果调用者没有指定这个ID则系统会分配一个未用过的id。可以在客户端根据这个id做资源判断。

你可以在Proxy的派生类中定义回调函数（onStreamComplete），所有数据成功发送给客户端时或下载失败时会调用这个回调函数。

参看：Proxy.onStreamComplete与客户端实体Entity.onStreamDataStarted和 Entity.onStreamDataRecv还有Entity.onStreamDataCompleted。

参数：
data | 要发送的字符串。
desc | 一个可选的字符串，发送给客户端的描述。
id | 一个16位的id，它的值完全取决于调用者。如果传入-1系统将会在队列里面选择一个没有在用的id。

返回：
与这个下载关联的id。

回调函数文档

def onClientDeath( self ):

如果在脚本中实现了此回调，这个方法将在客户端断开连接时被调用。 这个方法没有参数。

def onClientGetCell( self ):

如果在脚本中实现了此回调，当客户端能够调用实体的cell属性时，该回调被调用。

def onClientEnabled( self ):

如果在脚本中实现了此回调，当实体可用时（ 各种初始化完毕并且可以与客户端通讯 ）该回调被调用。 这个方法没有参数。
注意：giveClientTo将控制权赋给了该实体时也会导致该回调被调用。

def onGiveClientToFailure( self ):

如果在脚本中实现了此回调，当实体调用giveClientTo失败时，该回调被调用。这个方法没有参数。

def onLogOnAttempt( self, ip, port, password ):

如果在脚本中实现了此回调，这个函数在客户端尝试使用当前账号实体进行登录时触发回调。
这种情况通常是实体存在于内存中处于有效状态，最明显的例子是用户A使用此账号登录了，用户B使用同一账号进行登录，此时回调触发。

这个回调函数可以返回如下常量值：
KBEngine.LOG_ON_ACCEPT：允许新的客户端与实体进行绑定，如果实体已经绑定了一个客户端，之前的客户端将被踢出。
KBEngine.LOG_ON_REJECT：拒绝新的客户端与实体绑定。
KBEngine.LOG_ON_WAIT_FOR_DESTROY：等待实体销毁后再进行客户端绑定。

参数：
ip | 尝试登录的客户端IP地址。
port | 尝试登录的客户端连接的端口。
password | 用户登录时使用的MD5密码。

def onStreamComplete( self, id, success ):

如果在脚本中实现了此回调，当用户使用Proxy.streamStringToClient()或Proxy.streamFileToClient()完成时，该回调被调用。

参数：
id | 与下载关联的id。
success | 成功与否。

属性文档

__ACCOUNT_NAME__

说明：

如果proxy是帐号则可以访问__ACCOUNT_NAME__得到帐号名。

__ACCOUNT_PASSWORD__

说明：

如果proxy是帐号则可以访问__ACCOUNT_PASSWORD__得到帐号MD5密码。

clientAddr

这是一个tuple对象，包含了客户端的ip与端口。

clientEnabled

实体是否已经可用。在实体可用之前脚本不能与客户端进行通讯。

hasClient

Proxy是否绑定了一个客户端连接。

roundTripTime

在一段时间内服务器与这个Proxy绑定的客户端通讯平均往返时间。这个属性只在Linux下生效。

timeSinceHeardFromClient

最后一次收到客户端数据包时到目前为止所过去的时间（秒）。


KBEngine - KBEngine loginapp 文档

Loginapp进程

Loginapp进程主要负责处理实体的注册与登陆请求。
注意：该进程脚本实现在scripts/login目录中。


KBEngine - KBEngine loginapp 文档

KBEngine模块

KBEngine模块提供了Python脚本控制loginapp进程处理实体登陆注册等部分。

成员函数

def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):
def delTimer( id ):

回调函数

def onLoginAppReady( ):
def onLoginAppShutDown( ):
def onRequestLogin( loginName, password, clientType, datas ):
def onLoginCallbackFromDB( loginName, accountName, errorno, datas ):
def onRequestCreateAccount( accountName, password, datas ):
def onCreateAccountCallbackFromDB( accountName, errorno, datas ):

成员函数文档

def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):

功能说明：

注册一个定时器，定时器由回调函数callbackObj触发，回调函数将在"initialOffset"秒后被执行第1次，而后将每间隔"repeatOffset"秒执行1次。

例子:
# 这里是使用addTimer的一个例子
        import KBEngine

        # 增加一个定时器，5秒后执行第1次，而后每1秒执行1次，用户参数是9
        KBEngine.addTimer( 5, 1, onTimer_Callbackfun )

        # 增加一个定时器，1秒后执行，用户参数缺省是0
        KBEngine.addTimer( 1, onTimer_Callbackfun )

    def onTimer_Callbackfun( id ):
        print "onTimer_Callbackfun called: id %i" % ( id )
        # if 这是不断重复的定时器，当不再需要该定时器的时候，调用下面函数移除:
        #     KBEngine.delTimer( id )

参数：
initialOffset | float，指定定时器从注册到第一次回调的时间间隔（秒）。
repeatOffset | float，指定第一次回调执行后每次执行的时间间隔（秒）。必须用函数delTimer移除定时器，否则它会一直重复下去。值小于等于0将被忽略。
callbackObj | function，指定的回调函数对象。

返回:
integer，该函数返回timer的内部id，这个id可用于delTimer移除定时器。

def delTimer( id ):

功能说明：

函数delTimer用于移除一个注册的定时器，移除后的定时器不再执行。只执行1次的定时器在执行回调后自动移除，不必要使用delTimer移除。 如果delTimer函数使用一个无效的id（例如已经移除），将会产生错误。

到KBEngine.addTimer参考定时器的一个使用例子。

参数：
id integer，它指定要移除的定时器id。

回调函数文档

def onLoginAppReady( ):

功能说明：

当前进程已经准备好的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onLoginAppShutDown( ):

功能说明：

进程关闭会回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onRequestLogin( loginName, password, clientType, datas ):

功能说明：

客户端请求服务器登陆账号时回调。

此处可以对用户登陆做一些管理控制，例如：
利用该接口可以在此截断用户的登陆，将请求记录下来进行排队并返回一个错误码告诉客户端排队状态，客户端通过不断登陆从此处获得状态。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
loginName | string，登陆时提交的账号名称。
password | string，MD5密码。
clientType | integer，客户端类型，客户端登陆时给出。
datas | bytes，客户端请求时所附带的数据，可将数据转发第三方平台。

返回：
Tuple，返回值分别为（错误码，真实账号名，密码，客户端类别，客户端提交的数据datas），如果没有任何需要扩展修改的则通常返回值为毁掉传入的值（KBEngine.SERVER_SUCCESS, loginName, password, clientType, datas）。

def onLoginAppReady( ):

功能说明：

当前进程已经准备好的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onLoginAppShutDown( ):

功能说明：

进程关闭会回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onLoginCallbackFromDB( loginName, accountName, errorno, datas ):

功能说明：

客户端请求服务器登陆账号后由dbmgr返回的回调。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
loginName | string，登陆时提交的账号名称。
accountName | string，真实的账号名称（由dbmgr处查询获得）。
errorno | integer，错误码，如果非KBEngine.SERVER_SUCCESS则表示登陆失败。
datas | bytes，可能是任何数据，例如：第三方平台返回的数据或者由dbmgr以及interfaces中处理登陆时返回的数据。

def onRequestCreateAccount( accountName, password, data ):

功能说明：

客户端请求服务器创建账号时回调。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
accountName | string，客户端提交的账号名称。
password | string，MD5密码。
datas | bytes，客户端请求时所附带的数据，可将数据转发第三方平台。

返回：
Tuple，返回值分别为（错误码，真实账号名，密码，客户端提交的数据datas），如果没有任何需要扩展修改的则通常返回值为毁掉传入的值（KBEngine.SERVER_SUCCESS, loginName, password, datas）。

def onCreateAccountCallbackFromDB( accountName, errorno, datas ):

功能说明：

客户端请求服务器创建账号后由dbmgr返回的回调。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
accountName | string，客户端提交的账号名称。
errorno | integer，错误码，如果非KBEngine.SERVER_SUCCESS则表示登陆失败。
datas | bytes，可能是任何数据，例如：第三方平台返回的数据或者由dbmgr以及interfaces中处理登陆时返回的数据。


KBEngine - KBEngine dbmgr 文档

Dbmgr进程

Dbmgr进程主要负责处理实体数据的存储与实体数据的加载查询等等。
注意：该进程脚本实现在scripts/db目录中。


KBEngine - KBEngine dbmgr 文档

KBEngine模块

KBEngine模块提供了Python脚本控制dbmgr进程处理实体登陆查询与数据存取等部分。

成员函数

def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):
def delTimer( id ):
def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):

回调函数

def onDBMgrReady( ):
def onDBMgrShutDown( ):
def onReadyForShutDown( ):
def onSelectAccountDBInterface( accountName ):

成员函数文档

def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):

功能说明：

注册一个定时器，定时器由回调函数callbackObj触发，回调函数将在"initialOffset"秒后被执行第1次，而后将每间隔"repeatOffset"秒执行1次。

例子:
# 这里是使用addTimer的一个例子
        import KBEngine

        # 增加一个定时器，5秒后执行第1次，而后每1秒执行1次，用户参数是9
        KBEngine.addTimer( 5, 1, onTimer_Callbackfun )

        # 增加一个定时器，1秒后执行，用户参数缺省是0
        KBEngine.addTimer( 1, onTimer_Callbackfun )

    def onTimer_Callbackfun( id ):
        print "onTimer_Callbackfun called: id %i" % ( id )
        # if 这是不断重复的定时器，当不再需要该定时器的时候，调用下面函数移除:
        #     KBEngine.delTimer( id )

参数：
initialOffset | float，指定定时器从注册到第一次回调的时间间隔（秒）。
repeatOffset | float，指定第一次回调执行后每次执行的时间间隔（秒）。必须用函数delTimer移除定时器，否则它会一直重复下去。值小于等于0将被忽略。
callbackObj | function，指定的回调函数对象。

返回:
integer，该函数返回timer的内部id，这个id可用于delTimer移除定时器。

def delTimer( id ):

功能说明：

函数delTimer用于移除一个注册的定时器，移除后的定时器不再执行。只执行1次的定时器在执行回调后自动移除，不必要使用delTimer移除。 如果delTimer函数使用一个无效的id（例如已经移除），将会产生错误。

到KBEngine.addTimer参考定时器的一个使用例子。

参数：
id integer，它指定要移除的定时器id。

def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):

功能说明：

这个脚本函数在数据库上执行原始数据库命令，该命令将直接由相关数据库进行解析。

请注意使用该函数修改实体数据可能不生效，因为如果实体已经检出，被修改过的实体数据将仍会被实体存档而导致覆盖。
强烈不推荐这个函数用于读取或修改实体数据。

参数：
command | 这个数据库命令将会因为不同数据库配置方案而不同。对于方案为MySQL数据库它是一个SQL查询语句。
callback

可选参数，带有命令执行结果的回调对象（比如说是一个函数）。这个回调带有4个参数：结果集合，影响的行数，自増长值，错误信息。
声明样例：
def sqlcallback(result, rows, insertid, error):
print(result, rows, insertid, error)

如同上面的例子所示，result参数对应的就是“结果集合”，这个结果集合参数是一个行列表。 每一行是一个包含字段值的字符串列表。
命令执行没有返回结果集合（比如说是DELETE命令）， 或者 命令执行有错误时这个结果集合为None。

rows参数则是“影响的行数”，它是一个整数，表示命令执行受影响的行数。这个参数只和不返回结果结合的命令（如DELETE）相关。
如果有结果集合返回或者命令执行有错误时这个参数为None。

insertid对应的是“自増长值”，类似于实体的databaseID，当成功的向一张带有自増长类型字段的表中插入数据时，它返回该数据在插入时自増长字段所被赋于的值。
更多的信息可以参阅mysql的mysql_insert_id()方法。另外，此参数仅在数据库类型为mysql时有意义。

error则对应了“错误信息”，当命令执行有错误时，这个参数是一个描述错误的字符串。命令执行没有发生错误时这个参数为None。

threadID int32，可选参数，指定一个线程来处理本条命令。用户可以通过这个参数控制某一类命令的执行先后顺序（dbmgr是多线程处理的），默认是不指定，如果threadID是实体的ID，
那么将加入到该实体的存档队列中由线程逐条写入。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

回调函数文档

def onDBMgrReady( ):

功能说明：

当前进程已经准备好的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onDBMgrShutDown( ):

功能说明：

进程关闭会回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onReadyForShutDown( ):

功能说明：

如果这个函数在脚本中有实现，当进程准备退出时，该回调函数被调用。

可以通过该回调控制进程退出的时机。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

返回：
bool，如果返回True，则允许进入进程退出流程，返回其它值则进程会过一段时间后再次询问。

def onSelectAccountDBInterface( accountName ):

功能说明：

这个回调实现返回某个账号对应的数据库接口，选定接口后dbmgr针对这个账号的相关操作都由对应的数据库接口完成。

数据库接口在kbengine_defaults.xml->dbmgr->databaseInterfaces定义。
利用该接口可以根据accountName来决定账号应该存储在哪个数据库。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
accountName string，账号的名称。

返回：
string，数据库接口名（数据库接口在kbengine_defaults.xml->dbmgr->databaseInterfaces定义）。


KBEngine - KBEngine bots 文档

Bots进程

Bots是一种对服务端进行模拟测试的轻量级客户端程序，Bots没有渲染等部分，通过大量的模拟客户端与服务端进行逻辑交互能够测试出服务端隐含的BUG与压力，从而使得开发人员能够有效的针对性的对服务端进行优化。

注意：Bots进程需要在scripts/bots下实现相关客户端代码，由Python脚本来扩展实现。


KBEngine - KBEngine bots 文档

KBEngine模块

KBEngine模块提供了逻辑脚本层访问实体的部分, 以及当前进程其他客户端的数据等等。

类

Entity
PyClientApp

成员函数

def addBots( reqCreateAndLoginTotalCount, reqCreateAndLoginTickCount=0, reqCreateAndLoginTickTime=0 ):
def callback( initialOffset, callbackObj ):
def cancelCallback( id ):
def genUUID64( ):
def getWatcher( path ):
def getWatcherDir( path ):
def scriptLogType( logType ):

回调函数

def onInit( isReload ):
def onFinish( ):

属性

bots | bots
component | 只读 string

成员函数文档

def addBots( reqCreateAndLoginTotalCount, reqCreateAndLoginTickCount=0, reqCreateAndLoginTickTime=0 ):

功能说明：

向服务端添加机器人。

例子:
# 这里是使用addBots的一个例子
        import KBEngine

        # 一次性向服务器添加5个机器人（瞬时完成）
        KBEngine.addBots( 5 )

        # 一共向服务器添加1000个机器人，每次添加5个，每次添加所用时间(s)
        KBEngine.addBots( 1000, 5, 10 )

参数：
reqCreateAndLoginTotalCount | integer，向服务器添加的机器人总数。
reqCreateAndLoginTickCount | integer，每次向服务器添加的机器人数量。
reqCreateAndLoginTickTime | integer，每次添加所用时间(秒)。

def callback( initialOffset, callbackObj ):

功能说明：

注册一个回调，回调函数callbackObj触发，回调函数将在"initialOffset"秒后被执行。

例子:
# 这里是使用callback的一个例子
        import KBEngine

        # 增加一个定时器，1秒后执行
        KBEngine.callback( 1, onCallbackfun )

    def onCallbackfun( ):
        print "onCallbackfun called“

参数：
initialOffset | float，指定回调从注册到回调的时间间隔（秒）。
callbackObj | function，指定的回调函数对象。

返回:
integer，该函数返回callback的内部id，这个id可用于cancelCallback移除回调。

def cancelCallback( id ):

功能说明：

函数cancelCallback用于移除一个注册但还未触发的回调，移除后的回调不再执行。 如果cancelCallback函数使用一个无效的id（例如已经移除），将会产生错误。

到KBEngine.callback参考回调的一个使用例子。

参数：
id integer，它指定要移除的回调id。

def genUUID64( ):

功能说明：

该函数生成一个64位的唯一ID。
注意：这个函数依赖于Cellapps服务进程启动参数gus，请正确设置启动参数保持唯一性。
另外如果gus超过65535则该函数只能在当前进程上保持唯一性。

用途：
多个服务进程上产生唯一物品ID并且在合服时不会产生冲突。
多个服务进程上产生一个房间ID，不需要进行唯一性校验。

返回：
返回一个64位的integer。

def getWatcher( path ):

功能说明：

从KBEngine调试系统中获取一个监视变量的值。

例子：在baseapp1的Python命令行输入:
>>>KBEngine.getWatcher("/root/stats/runningTime")
12673648533

>>>KBEngine.getWatcher("/root/scripts/players")
32133

参数：
path string，该变量的绝对路径包括变量名(可以在GUIConsole的watcher页查看)。

返回：
该变量的值。

def getWatcherDir( path ):

功能说明：

从KBEngine调试系统中获取一个监视目录下的元素列表(目录、变量名)。

例子：在baseapp1的Python命令行输入:
>>>KBEngine.getWatcher("/root")
('stats', 'objectPools', 'network', 'syspaths', 'ThreadPool', 'cprofiles', 'scripts', 'numProxices', 'componentID', 'componentType', 'uid', 'numClients', 'globalOrder', 'username', 'load', 'gametime', 'entitiesSize', 'groupOrder')

参数：
path string，该变量的绝对路径(可以在GUIConsole的watcher页查看)。

返回：
监视目录下的元素列表(目录、变量名)。

def scriptLogType( logType ):

功能说明：

设置当前Python.print输出的信息类型(参考: KBEngine.LOG_TYPE_*)。

回调函数文档

def onInit( isReload ):

功能说明：

当引擎启动后初始化完所有的脚本后这个接口被调用。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
isReload bool，是否是被重写加载脚本后触发的。

def onFinish( ):

功能说明：

进程关闭会回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

属性文档

bots

说明：

bots是一个字典对象，包含当前进程上所有的客户端对象。

类型：
PyBots

component

说明：

这是正运行在当前脚本环境的组件。（至今为止）可能值有'cell', 'base', 'client', 'database', 'bot' 和 'editor'。


PyClientApp - KBEngine bots 文档

PyClientApp类

[KBEngine模块]

PyClientApp是KBEngine模块的一部分，由C++底层模拟一个客户端时创建的客户端对象，脚本层不可直接创建。

成员函数

def getSpaceData( key ):

回调函数

def onDestroy( self ):
def onEnterWorld( self ):
def onLeaveWorld( self ):
def onEnterSpace( self ):
def onLeaveSpace( self ):

属性

id | 只读 Integer
entities | Entities

详细描述

类Entity的实例代表着在client上的游戏对象。

一个Entity可以通过ENTITYCALL访问在base和cell应用程序上的等价的实体。这需要 一组远程调用的函数（在实体的.def文件里指定）。

成员函数文档

def getSpaceData( key ):

功能说明：

获取指定key的space数据。
space数据由用户在服务端通过setSpaceData设置。

参数：
key string，一个字符串关键字。

返回：
string，指定key的字符串数据。

回调函数文档

def onDestroy( self ):

实体被销毁时调用。

def onEnterWorld( self ):

如果实体非客户端控制实体，则表明实体进入了服务端上客户端控制的实体的View范围，此时客户端可以看见这个实体了。
如果实体是客户端控制的实体则表明该实体已经在服务端创建了cell并进入了space。

def onLeaveWorld( self ):

如果实体非客户端控制实体，则表明实体离开了服务端上客户端控制的实体的View范围，此时客户端看不见这个实体了。
如果实体是客户端控制的实体则表明该实体已经在服务端销毁了cell并离开了space。

def onEnterSpace( self ):

客户端控制的实体进入了一个新的space。

def onLeaveSpace( self ):

客户端控制的实体离开了当前的space。

属性文档

entities

说明：

entities是一个字典对象，包含当前进程上所有的实体。

类型：
Entities


Entity - KBEngine bots 文档

Entity类

[KBEngine模块]

Entity是KBEngine模块的一部分。 更多...

import KBEngine

成员函数

def moveToPoint( self, destination, velocity, distance, userData, faceMovement, moveVertically ):
def cancelController( self, controllerID ):

回调函数

def onEnterWorld( self ):
def onLeaveWorld( self ):
def onEnterSpace( self ):
def onLeaveSpace( self ):

属性

base | 只读 ENTITYCALL
cell | 只读 ENTITYCALL
className | 只读 string
clientapp | 只读 PyClientApp
direction | Tuple of 3 floats as (roll, pitch, yaw)
id | 只读 Integer
position | Vector3
spaceID | 只读 uint32
isOnGround | 只读 bool

详细描述

类Entity的实例代表着在client上的游戏对象。

一个Entity可以通过ENTITYCALL访问在base和cell应用程序上的等价的实体。这需要 一组远程调用的函数（在实体的.def文件里指定）。

成员函数文档

def moveToPoint( self, destination, velocity, distance, userData, faceMovement, moveVertically ):

功能说明：

直线移动Entity到给定的坐标点，成功或失败会调用回调函数。
任何实体，在任意时刻只能有一个移动控制器，重复调用任何移动函数将终止之前的移动控制器。
返回一个可以用于取消这次移动的控制器ID。

例如：
Entity.cancelController( movementID )。 移动取消还可以调用Entity.cancelController( "Movement" )。当移动被取消之后通知方法将 不被调用。

回调函数如下定义：
    def onMove( self, controllerID, userData ):
    def onMoveOver( self, controllerID, userData ):
    def onMoveFailure( self, controllerID, userData ):

参看：
Entity.cancelController

参数：
destination | Vector3，Entity要移动到的目标位置点
velocity | float，Entity的移动速度，单位m/s
distance | float，距离目标小于该值停止移动，如果该值为0则移动到目标位置。
userData | object，传给通知函数的数据
faceMovement | bool，如果实体面向移动方向则为true。如果是其它机制则为false。
moveVertically | bool，设为true指移动为直线移动，设为false指贴着地面移动。

返回：
int，新创建的控制器ID。

def cancelController( self, controllerID ):

功能说明：

函数cancelController停止一个控制器对Entity的影响。它只能在一个real实体上被调用。

参数：
controllerID controllerID是要取消的控制器的索引，它是一个整型。一个专用的控制器类型的字符串也可以作为它的类型。 例如，一次只有一个移动/导航控制器可以被激活，这可以用entity.cancelController( "Movement" )取消。

回调函数文档

def onEnterWorld( self ):

如果实体非客户端控制实体，则表明实体进入了服务端上客户端控制的实体的View范围，此时客户端可以看见这个实体了。
如果实体是客户端控制的实体则表明该实体已经在服务端创建了cell并进入了space。

def onLeaveWorld( self ):

如果实体非客户端控制实体，则表明实体离开了服务端上客户端控制的实体的View范围，此时客户端看不见这个实体了。
如果实体是客户端控制的实体则表明该实体已经在服务端销毁了cell并离开了space。

def onEnterSpace( self ):

客户端控制的实体进入了一个新的space。

def onLeaveSpace( self ):

客户端控制的实体离开了当前的space。

属性文档

base

base是用于联系Entity实体的entityCall。这个属性是只读的，且如果这个实体没有关联的Entity实体时属性是None。

其他参考：
Entity.clientEntity
Entity.allClients
Entity.otherClients

类型：
只读的，ENTITYCALL

cell

说明：

cell是用于联系cell实体的ENTITYCALL。这个属性是只读的，且如果这个base实体没有关联的cell时属性是None。

类型：
只读 ENTITYCALL

cellData

说明：

cellData是一个字典属性。每当base实体没有创建它的cell实体时，cell实体的属性会保存在这里。

如果cell实体被创建，这些用到的值和cellData属性将被删除。除了cell实体在实体定义文件里指定的属性外，它还包含position, direction and spaceID。

类型：
CELLDATADICT

className

说明：

实体的类名。

类型：
只读，string

clientapp

说明：

当前实体所属的客户端（对象）。

类型：
只读，PyClientApp

position

这个实体在世界空间中的坐标(x, y, z)，数据由服务端同步到客户端。

类型：
Vector3

direction

这个属性描述的是Entity在世界空间中的朝向，数据由服务端同步到客户端。

类型：
Vector3, 其中包含(roll, pitch, yaw)，以弧度表示。

isOnGround

如果这个属性的值为True，Entity在地面上，否则为False。
如果是客户端控制的实体该属性将会在改变时同步到服务端，其他实体则由服务端同步到客户端，客户端可以判断这个值来强制贴地避免精度带来的影响。

类型：
可读写， bool


KBEngine - KBEngine interfaces 文档

Interfaces进程

Interfaces进程主要处理KBEngine服务端与第三方平台的接入接出工作。
注意：该进程脚本实现在scripts/interface目录中。


KBEngine - KBEngine interfaces 文档

KBEngine模块

KBEngine模块主要处理KBEngine服务端与第三方平台的接入接出工作。

成员函数

def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):
def accountLoginResponse( commitName, realAccountName, extraDatas, errorCode ):
def createAccountResponse( commitName, realAccountName, extraDatas, errorCode ):
def chargeResponse( orderID, extraDatas, errorCode ):
def delTimer( id ):
def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):

回调函数

def onInterfaceAppReady( ):
def onInterfaceAppShutDown( ):
def onRequestCreateAccount( registerName, password, datas ):
def onRequestAccountLogin( loginName, password, datas ):
def onRequestCharge( ordersID, entityDBID, datas ):

成员函数文档

def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):

功能说明：

注册一个定时器，定时器由回调函数callbackObj触发，回调函数将在"initialOffset"秒后被执行第1次，而后将每间隔"repeatOffset"秒执行1次。

例子:
# 这里是使用addTimer的一个例子
        import KBEngine

        # 增加一个定时器，5秒后执行第1次，而后每1秒执行1次，用户参数是9
        KBEngine.addTimer( 5, 1, onTimer_Callbackfun )

        # 增加一个定时器，1秒后执行，用户参数缺省是0
        KBEngine.addTimer( 1, onTimer_Callbackfun )

    def onTimer_Callbackfun( id ):
        print "onTimer_Callbackfun called: id %i" % ( id )
        # if 这是不断重复的定时器，当不再需要该定时器的时候，调用下面函数移除:
        #     KBEngine.delTimer( id )

参数：
initialOffset | float，指定定时器从注册到第一次回调的时间间隔（秒）。
repeatOffset | float，指定第一次回调执行后每次执行的时间间隔（秒）。必须用函数delTimer移除定时器，否则它会一直重复下去。值小于等于0将被忽略。
callbackObj | function，指定的回调函数对象。

返回:
integer，该函数返回timer的内部id，这个id可用于delTimer移除定时器。

def accountLoginResponse( commitName, realAccountName, extraDatas, errorCode ):

功能说明：

在onRequestAccountLogin被回调后，脚本需要调用此接口给出登陆处理结果。

参数：
commitName | string，客户端请求时所提交的名称。
realAccountName | string，返回真实的账号名称（没有特殊要求通常就是commitName，使用各种别名账号登陆时可用到）。
extraDatas | bytes，客户端请求时所附带的数据，可将数据转发第三方平台，在此提供对其进行修改的机会。该参数可以通过base实体的getClientDatas接口在脚本读取。
errorCode | integer，错误码。如果需要中断用户的行为可在此设置错误码，错误码可参考（KBEngine.SERVER_ERROR_*， 描述在kbengine/kbe/res/server/server_errors.xml），否则提交KBEngine.SERVER_SUCCESS代表允许此处登陆。

def createAccountResponse( commitName, realAccountName, extraDatas, errorCode ):

功能说明：

在onRequestCreateAccount被回调后，脚本需要调用此接口给出账号创建处理结果。

参数：
commitName | string，客户端请求时所提交的名称。
realAccountName | string，返回真实的账号名称（没有特殊要求通常就是commitName，使用各种别名账号登陆时可用到）。
extraDatas | bytes，客户端请求时所附带的数据，可将数据转发第三方平台，在此提供对其进行修改的机会。该参数可以通过base实体的getClientDatas接口在脚本读取。
errorCode | integer，错误码。如果需要中断用户的行为可在此设置错误码，错误码可参考（KBEngine.SERVER_ERROR_*， 描述在kbengine/kbe/res/server/server_errors.xml），否则提交KBEngine.SERVER_SUCCESS代表允许此处登陆。

def chargeResponse( orderID, extraDatas, errorCode ):

功能说明：

在onRequestCharge被回调后，脚本需要调用此接口给出计费处理结果。

参数：
ordersID | string，订单的ID。
extraDatas | bytes，客户端请求时所附带的数据，可将数据转发第三方平台，在此提供对其进行修改的机会。该参数可以通过base实体的getClientDatas接口在脚本读取。
errorCode | integer，错误码。如果需要中断用户的行为可在此设置错误码，错误码可参考（KBEngine.SERVER_ERROR_*， 描述在kbengine/kbe/res/server/server_errors.xml），否则提交KBEngine.SERVER_SUCCESS代表允许此处登陆。

def delTimer( id ):

功能说明：

函数delTimer用于移除一个注册的定时器，移除后的定时器不再执行。只执行1次的定时器在执行回调后自动移除，不必要使用delTimer移除。 如果delTimer函数使用一个无效的id（例如已经移除），将会产生错误。

到KBEngine.addTimer参考定时器的一个使用例子。

参数：
id integer，它指定要移除的定时器id。

def executeRawDatabaseCommand( command, callback, threadID, dbInterfaceName ):

功能说明：

这个脚本函数在数据库上执行原始数据库命令，该命令将直接由相关数据库进行解析。

请注意使用该函数修改实体数据可能不生效，因为如果实体已经检出，被修改过的实体数据将仍会被实体存档而导致覆盖。
强烈不推荐这个函数用于读取或修改实体数据。

参数：
command | 这个数据库命令将会因为不同数据库配置方案而不同。对于方案为MySQL数据库它是一个SQL查询语句。
callback

可选参数，带有命令执行结果的回调对象（比如说是一个函数）。这个回调带有4个参数：结果集合，影响的行数，自増长值，错误信息。
声明样例：
def sqlcallback(result, rows, insertid, error):
print(result, rows, insertid, error)

如同上面的例子所示，result参数对应的就是“结果集合”，这个结果集合参数是一个行列表。 每一行是一个包含字段值的字符串列表。
命令执行没有返回结果集合（比如说是DELETE命令）， 或者 命令执行有错误时这个结果集合为None。

rows参数则是“影响的行数”，它是一个整数，表示命令执行受影响的行数。这个参数只和不返回结果结合的命令（如DELETE）相关。
如果有结果集合返回或者命令执行有错误时这个参数为None。

insertid对应的是“自増长值”，类似于实体的databaseID，当成功的向一张带有自増长类型字段的表中插入数据时，它返回该数据在插入时自増长字段所被赋于的值。
更多的信息可以参阅mysql的mysql_insert_id()方法。另外，此参数仅在数据库类型为mysql时有意义。

error则对应了“错误信息”，当命令执行有错误时，这个参数是一个描述错误的字符串。命令执行没有发生错误时这个参数为None。

threadID int32，可选参数，指定一个线程来处理本条命令。用户可以通过这个参数控制某一类命令的执行先后顺序（dbmgr是多线程处理的），默认是不指定，如果threadID是实体的ID，
那么将加入到该实体的存档队列中由线程逐条写入。
dbInterfaceName | string，可选参数，指定由某个数据库接口来完成, 默认使用"default"接口。数据库接口由kbengine_defaults.xml->dbmgr->databaseInterfaces中定义。

回调函数文档

def onInterfaceAppReady( ):

功能说明：

当前进程已经准备好的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onInterfaceAppShutDown( ):

功能说明：

进程关闭会回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onRequestCreateAccount( registerName, password, datas ):

功能说明：

当客户端请求服务器创建账号时，该回调被调用。

可在此函数内数据进行检查和修改，将最终结果通过KBEngine.createAccountResponse提交给引擎。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
registerName | string，客户端请求时所提交的名称。
password | string，密码。
datas | bytes，客户端请求时所附带的数据，可将数据转发第三方平台。

def onRequestAccountLogin( loginName, password, datas ):

功能说明：

当客户端请求服务器登陆账号时，该回调被调用。

可在此函数内数据进行检查和修改，将最终结果通过KBEngine.accountLoginResponse提交给引擎。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
loginName | string，客户端请求时所提交的名称。
password | string，密码。
datas | bytes，客户端请求时所附带的数据，可将数据转发第三方平台。

def onRequestCharge( ordersID, entityDBID, datas ):

功能说明：

当请求计费时（通常是baseapp上调用了KBEngine.charge），该回调被调用。

可在此函数内数据进行检查和修改，将最终结果通过KBEngine.chargeResponse提交给引擎。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
ordersID | uint64，订单的ID。
entityDBID | uint64，提交订单的实体DBID。
datas | bytes，客户端请求时所附带的数据，可将数据转发第三方平台。


KBEngine - KBEngine logger 文档

Logger进程

Logger进程主要负责收集KBEngine服务器所输出的日志。
注意：该进程脚本实现在scripts/logger目录中。


KBEngine - KBEngine logger 文档

KBEngine模块

KBEngine模块提供了Python脚本控制对特定类型的日志进行分析和转储等能力。

成员函数

def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):
def delTimer( id ):

回调函数

def onLoggerAppReady( ):
def onLoggerAppShutDown( ):
def onLogWrote( datas ):
def onReadyForShutDown( ):

成员函数文档

def addTimer( initialOffset, repeatOffset=0, callbackObj=None ):

功能说明：

注册一个定时器，定时器由回调函数callbackObj触发，回调函数将在"initialOffset"秒后被执行第1次，而后将每间隔"repeatOffset"秒执行1次。

例子:
# 这里是使用addTimer的一个例子
        import KBEngine

        # 增加一个定时器，5秒后执行第1次，而后每1秒执行1次，用户参数是9
        KBEngine.addTimer( 5, 1, onTimer_Callbackfun )

        # 增加一个定时器，1秒后执行，用户参数缺省是0
        KBEngine.addTimer( 1, onTimer_Callbackfun )

    def onTimer_Callbackfun( id ):
        print "onTimer_Callbackfun called: id %i" % ( id )
        # if 这是不断重复的定时器，当不再需要该定时器的时候，调用下面函数移除:
        #     KBEngine.delTimer( id )

参数：
initialOffset | float，指定定时器从注册到第一次回调的时间间隔（秒）。
repeatOffset | float，指定第一次回调执行后每次执行的时间间隔（秒）。必须用函数delTimer移除定时器，否则它会一直重复下去。值小于等于0将被忽略。
callbackObj | function，指定的回调函数对象。

返回:
integer，该函数返回timer的内部id，这个id可用于delTimer移除定时器。

def delTimer( id ):

功能说明：

函数delTimer用于移除一个注册的定时器，移除后的定时器不再执行。只执行1次的定时器在执行回调后自动移除，不必要使用delTimer移除。 如果delTimer函数使用一个无效的id（例如已经移除），将会产生错误。

到KBEngine.addTimer参考定时器的一个使用例子。

参数：
id integer，它指定要移除的定时器id。

回调函数文档

def onLoggerAppReady( ):

功能说明：

当前进程已经准备好的时候回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onLoggerAppShutDown( ):

功能说明：

进程关闭会回调此函数。
注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

def onLogWrote( datas ):

功能说明：

如果这个函数在脚本中有实现，logger进程获得了一条新日志，该回调函数被调用。

数据库接口在kbengine_defaults.xml->dbmgr->databaseInterfaces定义。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

参数：
datas bytes，日志数据。

def onReadyForShutDown( ):

功能说明：

如果这个函数在脚本中有实现，当进程准备退出时，该回调函数被调用。

可以通过该回调控制进程退出的时机。

注意：该回调接口必须实现在入口模块(kbengine_defaults.xml->entryScriptFile)中。

返回：
bool，如果返回True，则允许进入进程退出流程，返回其它值则进程会过一段时间后再次询问。